【问题标题】:python scrapy dynamic select xpaths and csspython scrapy动态选择xpaths和css
【发布时间】:2014-02-23 19:52:39
【问题描述】:

我不想在蜘蛛中硬编码我的项目的 xpath 和 css 选择器。

相反,我想将它们保存在一个地方,并在蜘蛛运行时动态提取它们。

这个功能有官方支持吗?

我尝试过的

我做了一个字典,key是item name,value是一个list,包含两个值,第一个是xpath,第二个是css。

【问题讨论】:

  • “key是item name”:你是说item字段名?为什么有 2 个值,XPath 和 CSS?我不确定你想要达到什么目标。告诉我们更多。
  • @pault。我正在尝试将 css 和 xpath 值保存在一个类中,稍后使用 sel 调用它们,就像这样 sel.xpath(valueofxpath).css(valueofcss)
  • 我猜你可以将 JSON 字符串作为参数传递给你的蜘蛛。
  • @pault。请给我一个答案的例子

标签: python css python-2.7 xpath scrapy


【解决方案1】:

你可以定义一个类似这样的配置文件(借用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 项目。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    相关资源
    最近更新 更多