【问题标题】:Limit scrapy spider for certain number of requests限制一定数量的请求的scrapy蜘蛛
【发布时间】:2020-07-27 18:19:20
【问题描述】:

我希望我的 scrapy spider 在达到某个请求限制时关闭。我试过但不适合我。它会再次显示输入消息,并且在达到限制之前不会中断。

这就是我想要的:

  • 如果我想限制请求数量,请在终端输入
  • 在达到限制下继续并中断

下面是代码:

# -*- coding: utf-8 -*-
import scrapy

links_list = open('links.txt').read().split('\n')


class MainSpider(scrapy.Spider):
    name = 'main'
    allowed_domains = ['www.yellowpages.com']
    start_urls = links_list

    def parse(self, response):

        try:
            limit = input('Do you want any limit? reply with [y - n]: ')
            if limit == 'y':
                limit_count = int(input('Enter the limit (Only a number value): '))
        except:
            pass

        for i in range(limit_count):
            i += 1
            if i == limit_count:
                break
        
            lists = response.xpath('//a[@class="business-name"]')

            for each in lists:

                link = each.xpath('.//@href').get()
                yield response.follow(url=link, callback=self.parse_links)

            next_page = response.xpath('//a[contains(@class, "next")]/@href').get()
            if next_page:
                yield response.follow(url=next_page, callback=self.parse)

    def parse_links(self, response):
        link = response.url
        name = response.xpath('//div[@class="sales-info"]/h1/text()').get()
        address = response.xpath('//h2[@class="address"]/text()').get()
        website = response.xpath('//a[contains(@class,"website-link")]/@href').get()
        phone = response.xpath('//p[@class="phone"]/text()').get()
        email = response.xpath('(//a[@class="email-business"])[1]/@href').get()

        yield {
            "Link": link,
            "Name": name,
            "Address": address,
            "Website": website,
            "Phone": phone,
            "Email": email,
        }

【问题讨论】:

    标签: python scrapy


    【解决方案1】:

    您可以通过设置CLOSESPIDER_PAGECOUNT 来实现此目的。

    一个整数,它指定要抓取的最大响应数。 如果蜘蛛爬得更多,蜘蛛将被关闭 closespider_pagecount 的原因。如果为零(或未设置),蜘蛛不会 被抓取的响应数关闭。

    来自docs

    就在终端进行控制,您可以使用-s 标志,如下所示:

    scrapy crawl my_spider -s CLOSESPIDER_PAGECOUNT=10
    

    现在,看看你的控制方法:

    假设我刚刚执行,我为limit_count 输入了 10。

            for i in range(limit_count):
                i += 1
                if i == limit_count:
                    break
                lists = response.xpath('//a[@class="business-name"]')
                for each in lists:
                    link = each.xpath('.//@href').get()
                    yield response.follow(url=link, callback=self.parse_links)
    

    在您的第一次迭代 (i == 1) 中,列表将返回一个 list 的选择器(带有链接)。假设lists 返回 20 个项目。这意味着在第 1 次迭代中,这个嵌套循环将产生 20 个请求,而i 仍然等于 1。您计算的不是请求数,而是 父循环 的迭代次数。

                next_page = response.xpath('//a[contains(@class, "next")]/@href').get()
                if next_page:
                    yield response.follow(url=next_page, callback=self.parse)
    

    现在,对next_page 的每个请求都会在另一个范围内回调parse 方法,这意味着他们不会“意识到”彼此的limit_count 10 并将继续请求他们自己的@987654337 @。如果您想了解更多关于变量 scopes 的信息,请点击此处。

    最后,您的迭代器将选择i==2(等等),并重复之前所做的一切。 (和以前一样,response 从未改变过。)

    【讨论】:

    • 谢谢,我试过了。它以某种方式起作用,但实际上直到我给出的限制才爬行。我把限制设置为 55,它爬取了 66 页。您可以看到以下日志: scrapy crawl main -o dataset.csv -s CLOSESPIDER_PAGECOUNT=55 2020-07-27 11:32:56 [scrapy.extensions.feedexport] INFO: Stored csv feed (66 items) in: datasett. csv
    • CLOSESPIDER_PAGECOUNT 将计算请求,而不是项目。即使这很奇怪,因为您的 parse_links 每次请求只产生一个项目。您正在运行您发布的相同代码吗?我编辑了我的答案,以向您展示循环逻辑中的一些问题。
    • 好的 this 解释了页数差异。我刚刚知道了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-29
    • 1970-01-01
    • 2016-06-15
    相关资源
    最近更新 更多