【问题标题】:Scrapy pagination timing errorScrapy分页计时错误
【发布时间】:2017-06-03 05:45:16
【问题描述】:

所以我设置了一个蜘蛛,和scrapy上的例子非常相似。

我希望蜘蛛在进入下一页之前抓取所有引号。我还希望它每秒只解析 1 个报价。因此,如果一个页面上有 20 条引号,则抓取引号需要 20 秒,然后需要 1 秒才能转到下一页。

截至目前,我当前的实现是在实际获取报价信息之前先遍历每个页面。

import scrapy

class AuthorSpider(scrapy.Spider):
name = 'author'

start_urls = ['http://quotes.toscrape.com/']

def parse(self, response):
    # follow links to author pages
    for href in response.css('.author+a::attr(href)').extract():
        yield scrapy.Request(response.urljoin(href),
                             callback=self.parse_author)

    # follow pagination links
    next_page = response.css('li.next a::attr(href)').extract_first()
    if next_page is not None:
        next_page = response.urljoin(next_page)
        yield scrapy.Request(next_page, callback=self.parse)

def parse_author(self, response):
    def extract_with_css(query):
        return response.css(query).extract_first().strip()

    yield {
        'name': extract_with_css('h3.author-title::text'),
        'birthdate': extract_with_css('.author-born-date::text'),
        'bio': extract_with_css('.author-description::text'),
    }

这里是我的 settings.py 文件的基础知识

ROBOTSTXT_OBEY = True
CONCURRENT_REQUESTS = 1
DOWNLOAD_DELAY = 2

【问题讨论】:

    标签: python pagination scrapy


    【解决方案1】:

    您可以安排 scrapy.Requests 的产生方式。

    例如,您可以创建下一页请求,但仅在所有作者请求终止抓取其项目时才产生它。

    例子:

    import scrapy
    
    # Store common info about pending request
    pending_authors = {}
    
    class AuthorSpider(scrapy.Spider):
    name = 'author'
    
    start_urls = ['http://quotes.toscrape.com/']
    
    def parse(self, response):
    
        # process pagination links
        next_page = response.css('li.next a::attr(href)').extract_first()
        next_page_request = None
        if next_page is not None:
            next_page = response.urljoin(next_page)
            # Create the Request object, but does not yield it now
            next_page_request = scrapy.Request(next_page, callback=self.parse)
    
        # Requests scrapping of authors, and pass reference to the Request for next page
        for href in response.css('.author+a::attr(href)').extract():
            pending_authors[href] = False  # Marks this author as 'not processed'
            yield scrapy.Request(response.urljoin(href), callback=self.parse_author,
                                 meta={'next_page_request': next_page_request})
    
    
    def parse_author(self, response):
        def extract_with_css(query):
            return response.css(query).extract_first().strip()
    
        item = {
            'name': extract_with_css('h3.author-title::text'),
            'birthdate': extract_with_css('.author-born-date::text'),
            'bio': extract_with_css('.author-description::text'),
        }
    
        # marks this author as 'processed'
        pending_authors[response.url] = True
    
        # checks if finished processing of all authors
        if len([value for key, value in pending_authors.iteritems() if value == False]) == 0:
            yield item
            next_page_request = response.meta['next_page_request']
    
            # Requests next page, after finishinr all authors
            yield next_page_request
        else:
            yield item
    

    【讨论】:

    • 似乎没有用。全局名称 pending_authors 未定义。
    • JK 对于它的所有实例,它应该是 self.pending_authors。
    • 后续问题:我注意到使用这种方法,如果它看到一个已经解析的页面,它不会尝试转到下一个链接。你知道如何禁用它吗(不要抓取它以前见过的作者,但仍然遍历页面)?
    • 刚刚编辑了我的答案,'pending_authors' 是全局的,而不是针对每个实例。关于后续问题:这只是您可以编排抓取请求的一个示例;您可以通过 url 以外的方式保存作者。我已经做了类似的事情,但是我使用 mongodb 来存储项目,并且当我抓取时,我可以在保存抓取的数据之前先检查一下。
    • 感谢您的帮助!但是,我注意到这个实现的一些事情。 1. pending_authors 必须在 parse 和 parse_author 中全局调用 2. 使用此实现,如果您看到重复的作者(您之前在之前的抓取中解析过的作者),除非您在全局 pending_authors 中设置键,否则不会对其进行处理middleware.py 中的 dict 为 true
    猜你喜欢
    • 1970-01-01
    • 2019-11-16
    • 1970-01-01
    • 1970-01-01
    • 2015-07-27
    • 2017-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多