【问题标题】:Using Functions like Boolean() and count() with scrapy and xpath将 Boolean() 和 count() 等函数与 scrapy 和 xpath 一起使用
【发布时间】:2017-07-19 07:22:57
【问题描述】:

所以我尝试使用 xpath 函数 boolean() 并使用 scrapy 提取真假响应 但是所有的scrapy返回都是u'0'

是否返回布尔值 true 或 boolean :false scrapy 总是返回
[<Selector xpath="boolean(.//*[@id='olp']/a)" data=u'0'>]

基本上这是我的 xpath

布尔值(.//*[@id='olp']/a)

当我使用 firepath 运行它时,它返回 true 或 false 如果元素存在,则返回 true,如果不存在,则返回 false 但是当通过scrapy做时

print selector.xpath("boolean(.//*[@id='olp']/a)").extract()

这里的任何人都可以帮助我如何通过scrapy直接获得真或假...我知道我可以通过python通过检查元素是否存在来做到这一点..但我的目标是知道scrapy是否可以处理和此类函数的返回值,例如 boolean()count()

ps:我不需要我的抓取目标的确切答案..我只需要知道如何或是否可以这样做.. 谢谢

【问题讨论】:

    标签: python xml xpath scrapy


    【解决方案1】:

    注意:Scrapy 选择器虽然基于 lxml,但在布尔 XPath 表达式或返回数字的结果方面与 lxml 不同。

    让我们使用这个示例 HTML 文档来说明:

    >>> html = '''<!DOCTYPE html>
    ... <html>
    ...   <head>
    ...     <title>This is a title</title>
    ...   </head>
    ...   <body>
    ...     <p>Hello world!</p>
    ...   </body>
    ... </html>'''
    

    如果你直接使用lxml,你可以测试例如文档中是否存在&lt;div&gt;&lt;p&gt;等元素:

    >>> import lxml.html
    >>> doc = lxml.html.fromstring(html)
    >>> doc.xpath('boolean(//div)')
    False
    >>> doc.xpath('boolean(//p)')
    True
    

    lxml 的.xpath() 返回您所期望的:没有&lt;div&gt; 元素,但有一个&lt;p&gt;

    如果你将它与 Scrapy 选择器进行比较,调用 .xpath() 将返回一个 Selector 列表。 (这与是否使用布尔表达式无关。)

    >>> import scrapy
    >>> response = scrapy.Selector(text=html)
    >>> response.xpath('boolean(//p)')
    [<Selector xpath='boolean(//p)' data='1'>]
    

    您需要调用.extract().extract_first()(或新的.get() 快捷方式)来获取“有用的”数据以进行处理。而你从.extract()/.extract_first()/.get() 得到的是字符串:

    >>> response.xpath('boolean(//p)').extract()
    ['1']
    >>> response.xpath('boolean(//p)').extract_first()
    '1'
    >>> response.xpath('boolean(//p)').get()
    '1'
    

    您会看到用于 XPath true'1'。您还可以得到一个用于 XPath 的 '0' false

    >>> response.xpath('boolean(//div)').get()
    '0'
    

    在 Python 中,非空字符串上的 bool() 将返回 True,无论字符串是什么:

    >>> bool(response.xpath('boolean(//p)').get())
    True
    >>> bool(response.xpath('boolean(//div)').get())
    True
    

    一种解决方法是在“中间”使用int() 进行转换:

    >>> bool(int(response.xpath('boolean(//p)').get()))
    True
    >>> bool(int(response.xpath('boolean(//div)').get()))
    False
    

    对于返回数字的 XPath 表达式,例如 count(...),lxml 返回浮点数:

    >>> doc.xpath('count(//div)')
    0.0
    >>> doc.xpath('count(//p)')
    1.0
    

    而 Scrapy 选择器返回浮点数的字符串表示:

    >>> response.xpath('count(//div)').get()
    '0.0'
    >>> response.xpath('count(//p)').get()
    '1.0'
    

    所以你想在处理结果之前将提取的字符串传递给float()

    >>> float(response.xpath('count(//p)').get())
    1.0
    >>> float(response.xpath('count(//div)').get())
    0.0
    

    【讨论】:

      【解决方案2】:

      您可以获取 xpath 并使用 python 对其进行评估:

      body = "<div class=something>hello!</div>"
      sel = Selector(text=body)
      elements = sel.xpath('//div[@class="something"]')
      print(bool(elements))
      # True
      print(len(elements))
      # 1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-03
        • 2020-01-20
        • 1970-01-01
        • 2011-07-21
        相关资源
        最近更新 更多