【问题标题】:Scrapy - xpath return parent node with content based on regex matchScrapy - xpath 返回父节点,内容基于正则表达式匹配
【发布时间】:2016-06-04 04:44:47
【问题描述】:

早安,

我正在尝试使用 Scrapy 递归地获取网站信息。 Startpoint 是一个列出 URL 的站点。我使用以下代码通过 Scrapy 获取这些 URL: 第 1 步:

def parse(self, response):
    for href in response.css('.column a::attr(href)'):
        full_url = response.urljoin(href.extract())
        yield { 'url': full_url, }

然后对于每个 URL,我将查找包含关键字的特定 URL(我现在将每个步骤分开,因为我是 Scrapy 的新手。最后我想由一个蜘蛛运行它): 第 2 步:

def parse(self, response):
    for href in response.xpath('//a[contains(translate(@href,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz"),"keyword")]/@href'):
        full_url = response.urljoin(href.extract())
        yield { 'url': full_url, }

到目前为止一切顺利,但最后一步:

第 3 步: 我想从返回的 URL 中获取特定信息(如果有的话)。现在我遇到了麻烦;o) 我试图帮凶:

  • 使用正则表达式搜索其值/内容与正则表达式匹配的元素:([0-9][0-9][0-9][0-9].*[A-Z][A-Z]) >>这匹配 1234AB 和/或 1234 AB
  • 返回整个父 div(以后,如果可能的话,如果没有父 div,我想返回上面的两个父 div,但那是以后的事了)。

所以当你拿下面的HTML代码时,我想返回父div()的内容。请注意,我不知道课程,所以我无法匹配。

<html>
    <head>
        <title>Webpage</title>
    </head>
    <body>
        <h1 class="bookTitle">A very short ebook</h1>
        <p style="text-align:right">some text</p>
          <div class="contenttxt">
            <h1>Info</h1>
        <h4>header text</h4>

        <p>something<br />
        1234 AB</p>

        <p>somthing else</p>
      </div>
        <h2 class="chapter">Chapter One</h2>
        <p>This is a truly fascinating chapter.</p>

        <h2 class="chapter">Chapter Two</h2>
        <p>A worthy continuation of a fine tradition.</p>
    </body>
</html>

我试过的代码:

2016-05-31 18:59:32 [scrapy] INFO: Spider opened
2016-05-31 18:59:32 [scrapy] DEBUG: Crawled (200) <GET http://localhost/test/test.html> (referer: None)
[s] Available Scrapy objects:
[s]   crawler    <scrapy.crawler.Crawler object at 0x7f6bc2be0e90>
[s]   item       {}
[s]   request    <GET http://localhost/test/test.html>
[s]   response   <200 http://localhost/test/test.html>
[s]   settings   <scrapy.settings.Settings object at 0x7f6bc2be0d10>
[s]   spider     <DefaultSpider 'default' at 0x7f6bc2643b90>
[s] Useful shortcuts:
[s]   shelp()           Shell help (print this help)
[s]   fetch(req_or_url) Fetch request (or URL) and update local objects
[s]   view(response)    View response in a browser
>>> response.xpath('//*').re('([0-9][0-9][0-9][0-9].*[A-Z][A-Z])')
[u'1234 AB', u'1234 AB', u'1234 AB', u'1234 AB']

首先,它返回了 4 次匹配,所以至少它可以找到一些东西。我搜索了“scrapy xpath return parent node”,但这只给了我一个只得到一个结果的“解决方案”:

>>> response.xpath('//*/../../../..').re('([0-9][0-9][0-9][0-9].*[A-Z][A-Z])')
[u'1234 AB']

我也尝试过类似的方法:

>>> for nodes in response.xpath('//*').re('([0-9][0-9][0-9][0-9].*[A-Z][A-Z])'):
...     for i in nodes.xpath('ancestor:://*'):
...         print i
... 
Traceback (most recent call last):
  File "<console>", line 2, in <module>
AttributeError: 'unicode' object has no attribute 'xpath'

但这也无济于事。 希望有人能指出我正确的方向。首先是因为我不知道为什么正则表达式匹配 4 次,其次是因为我不知道如何到达我想要的位置。刚刚回顾了“可能已经有你答案的问题”显示的最有希望的结果。但没有找到我的解决方案。我最好的猜测是我必须建立某种循环,但是再一次,没有线索。 :s

最后,我尝试获取一个输出结果,其中包含在步骤 1 和步骤 2 中找到的 URL,以及来自步骤 3 的数据。

谢谢! 韩国, 小野。

【问题讨论】:

    标签: regex xpath scrapy


    【解决方案1】:

    re 方法在 xpath 选择器提取感兴趣的元素后提取数据,请查看documentation 了解更多信息。如果您知道元素(在这种情况下可能是 div),您可以遍历所有 div 检查其内容或使用 scrapy 对 XPath 中正则表达式的内置支持;使用您之前的示例,如下所示:

    response.xpath('//div[re:test(., "[0-9]{4}\s?[A-Z]{2}")]').extract()
    

    返回

    [u'<div class="contenttxt">\n            <h1>Info</h1>\n        <h4>header text</h4>\n\n        <p>something<br>\n        1234 AB</p>\n\n        <p>somthing else</p>\n      </div>']
    

    【讨论】:

      猜你喜欢
      • 2015-12-21
      • 1970-01-01
      • 2010-10-10
      • 1970-01-01
      • 1970-01-01
      • 2019-10-08
      • 1970-01-01
      • 2022-01-14
      • 1970-01-01
      相关资源
      最近更新 更多