你可以定义一个类似这样的配置文件(借用the Scrapy tutorial):
{
"region": [["xpath", "//ul/li"]],
"fields": {
"title": [["xpath", "a/text()"]],
"link": [["xpath", "./a"], ["css", "::attr(href)"]],
"desc": [["xpath", "text()"]]
}
}
其中列表表示要应用的连续选择器表达式,可以是 CSS 选择器,也可以是 XPath 表达式。
例如,
-
[["xpath", "//ul/li"]] 表示“应用 XPath 表达式 //ul/li,即 sel.xpath('//ul/li')
-
[["xpath", "./a"], ["css", "::attr(href)"]] 表示“应用 XPath 表达式 ./a,CSS 选择器 ::attr(href)(注意:这是非标准的,它是 Scrapy 扩展),相当于 sel.xpath('./a').css('::attr(href)')
我添加了一个配置“区域”以将选择器应用于特定区域
您可以将 JSON 字符串作为参数传递给您的蜘蛛 (-a argname=argvalue),您的参数可以作为蜘蛛的属性使用——在我的例子中是 self.selconfig。
蜘蛛码:
from scrapy.spider import Spider
from scrapy.selector import Selector
from scrapy.item import Item, Field
import json
import pprint
def apply_exp_list(selector, expression_list):
out = selector
for expr_type, expr_val in expression_list:
if expr_type == "xpath":
out = out.xpath(expr_val)
elif expr_type == "css":
out = out.css(expr_val)
return out
class DmozItem(Item):
title = Field()
link = Field()
desc = Field()
class DmozSpider(Spider):
name = "dmoz"
allowed_domains = ["dmoz.org"]
start_urls = [
"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
]
def parse(self, response):
sel = Selector(response)
config = json.loads(self.selconfig)
self.log("selector configuration: \n%s" % pprint.pformat(config))
regions = apply_exp_list(sel, config["region"])
items = []
for region in regions:
item = DmozItem()
for field_name, exp_list in config["fields"].items():
item[field_name] = apply_exp_list(region, exp_list).extract()
items.append(item)
return items
并在命令行上,例如:
paul@wheezy:~/tmp/stackoverflow$ scrapy runspider 21474657.py \
-a selconfig='{"fields": {"desc": [["xpath", "text()"]], "link": [["xpath", "./a"], ["css", "::attr(href)"]], "title": [["xpath", "a/text()"]]}, "region": [["xpath", "//ul/li"]]}'
注意:我玩了一下,它可能比预期的要复杂一些,它让我想起了(免责声明:我自己的)parslepy 项目。