【问题标题】:Scrapy - How to avoid Pagination Blackhole?Scrapy - 如何避免分页黑洞?
【发布时间】:2016-12-25 22:39:36
【问题描述】:

我最近正在研究一个网站蜘蛛,并注意到它正在请求无限数量的页面,因为网站没有将其分页编码为永远停止。

因此,虽然他们只有几页内容,但仍会生成下一个链接和 url ...?page=400、...?page=401 等。

内容没有改变,只是 URL。当内容停止变化时,有没有办法让 Scrapy 停止跟随分页?或者我可以编写自定义代码。

【问题讨论】:

  • 您将需要跟踪发生变化的内容并在不再发生变化时停止,即页面标题或显示结果的标题(您显然可以通过 xpath 查询分析文本)。
  • 但是我如何将它链接到它即将抓取的 URL 并阻止 LinkExtractor 使用它?将其集成到 CrawlSpider 超出了我的范围。

标签: python pagination scrapy web-crawler


【解决方案1】:

如果内容没有变化,您可以将当前页面的内容与上一页的内容进行比较,如果相同,则中断抓取。

例如:

def parse(self, response):
    product_urls = response.xpath("//a/@href").extract()
    # check last page
    if response.meta.get('prev_urls') == product_urls:
        logging.info('reached the last page at: {}'.format(response.url))
        return  # reached the last page
    # crawl products
    for url in product_urls:
        yield Request(url, self.parse_product)
    # create next page url
    next_page = response.meta.get('page', 0) + 1
    next_url = re.sub('page=\d+', 'page={}'.format(next_page), response.url)
    # now for the next page carry some data in meta
    yield Request(next_url, 
                  meta={'prev_urls': product_urls,
                        'page': next_page}

【讨论】:

  • 混合yieldsreturn 是行不通的,但限制产品链接的一般想法很有趣。另外,还不如在产生产品Request 对象之前测试response.meta.get('prev_urls') == product_urls
  • @paultrmbrth 谢谢,在开头移动了支票。尽管只要return 不返回任何东西,在python2 中混合return 和yield 就可以正常工作,但它就像break 这里一样。
  • 这可以与爬虫和链接提取器一起使用吗?或者这是一个默认的 Scrapy 蜘蛛?
  • @JimFactor 这是默认的scrapy.Spider。我敢打赌,如果您想使用 CrawlSpider,肯定可以将某些东西与 Downloader 中间件一起破解。也许检查每个响应中的产品并缓存它,如果某个页面上的产品已经在缓存中,那么这可能是分页的指示,您可以引发 CloseSpider 异常来停止爬网。 Scrapy 非常灵活,因此可能至少有几种方法可以做某事。你总是可以打开一个新问题,也许之前有人已经这样做了:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-28
  • 1970-01-01
相关资源
最近更新 更多