每个解析的页面阻止爬行的大量请求

Mic*_*ber 5 python scrapy

我抓了一个爬网,其中每个子页面包含300多个我需要遵循的链接.一分钟后,抓取速度会减慢/有时会以0页/分钟的速度爬行.

如果我以每页10-50页链接进行爬行,则不会显示相同的问题.

我已经配置了10个concurrent_requests和10个已处理的项目以及反应堆theradpool和400.这意味着每10个处理项目最多可达3.000个产量...

记录显示解析功能每页需要70多秒.记录显示此处所需的时间来自产量(每次产量最多需要2个秒).

似乎scrapy一直等到发动机?或类似的东西做了一个任务,并准备处理新的收益率请求?将请求添加到调度程序并不需要很长时间,所以在我看来,收益正在等待其他东西.

有什么提示可以调整或出错吗?

是否可以批量生成请求而不是单独产生每个请求?是否可以将它们添加到调度程序而不会产生它们?

一些额外的信息: - 如果我使用scrapy-redis或只是基于磁盘的调度程序没有区别. - 由于渲染javascript,下载爬网页面最多可能需要10秒钟. - Autothrottle被禁用 - 如果我提供更多的cpu资源,它不会加快速度.

telnet-> est()

time()-engine.start_time                        : 676.0599975585938
engine.has_capacity()                           : False
len(engine.downloader.active)                   : 7
engine.scraper.is_idle()                        : False
engine.spider.name                              : onetwothree
engine.spider_is_idle(engine.spider)            : False
engine.slot.closing                             : False
len(engine.slot.inprogress)                     : 28
len(engine.slot.scheduler.dqs or [])            : AttributeError (exception)
len(engine.slot.scheduler.mqs)                  : AttributeError (exception)
len(engine.scraper.slot.queue)                  : 0
len(engine.scraper.slot.active)                 : 21
engine.scraper.slot.active_size                 : 3878605
engine.scraper.slot.itemproc_size               : 0
engine.scraper.slot.needs_backout()             : False

AttributeError seems to come from scrapy-redis plugin, 
without scrapy counts up the pages to request in mgs.
Run Code Online (Sandbox Code Playgroud)

如果len(engine.downloader.active)变为0,则为est

time()-engine.start_time                        : 7236.464096784592
engine.has_capacity()                           : False
len(engine.downloader.active)                   : 0
engine.scraper.is_idle()                        : False
engine.spider.name                              : onetwothree
engine.spider_is_idle(engine.spider)            : False
engine.slot.closing                             : False
len(engine.slot.inprogress)                     : 25
len(engine.slot.scheduler.dqs or [])            : AttributeError (exception)
len(engine.slot.scheduler.mqs)                  : AttributeError (exception)
len(engine.scraper.slot.queue)                  : 0
len(engine.scraper.slot.active)                 : 25
engine.scraper.slot.active_size                 : 5357134
engine.scraper.slot.itemproc_size               : 0
engine.scraper.slot.needs_backout()             : True
Run Code Online (Sandbox Code Playgroud)

爬虫代码:

class robo2Spider(Spider):
    http_pass = None
    http_user = None
    dont_redirect = True
    start_urls = []

    def __init__(self, *args, **kwargs):

        # ... some config ...

        self.start_urls = self.custom_settings["TEST_URLS"]
        # Don't Follow links in test mode

    def start_requests(self):
        for url in self.start_urls:
            r = self.get_request(url)
            yield r

    def parse(self, response):
        # some extraction and co...
        yield from self.scrape_data(response)

    def scrape_data(self, response):
        start_time = time.time()

        # more extraction, build item

        extract_links = util.extract_links_from_response(response, self.query_pars_to_ignore)
        logging.info(
            "--- logging time 1: %s --- %s seconds ---" % (response.url, time.time() - start_time))

        request_links = []
        for link in extract_links:

            if (not link["nofollow"]) and (l.get_output_value("crawl_meta_nofollow") != "nofollow"):
                r = self.get_request(link["url"])
                request_links.append(r)

        yield from request_links

        logging.info(
            "--- logging time 2 (takes up to 70 sec): %s --- %s seconds ---" % (response.url, time.time() - start_time))

        yield l.load_item()


    def get_request(self, url, rit=None, splash_retry=None):

        # ... setting meta & co ...
        meta = {}
        splash_args = {}
        return SplashRequest(url=url, callback=self.parse, meta=meta,
                             args=splash_args, http_status_from_error_code=True,
                             endpoint='execute', slot_policy=scrapy_splash.SlotPolicy.SCRAPY_DEFAULT)
Run Code Online (Sandbox Code Playgroud)

如果我这样做,结果相同:对于extract_links中的链接:

    if (not link["nofollow"]) and (l.get_output_value("crawl_meta_nofollow") != "nofollow"):
        r = self.get_viu_request(link["url"])
        request_links.append(r)
        yield r
Run Code Online (Sandbox Code Playgroud)

小智 0

yield性能是理想的,启动画面会减慢您的速度,尝试在不使用启动画面的情况下获取数据,检查网络选项卡以devtools查找加载动态内容的真实请求,以避免使用启动画面,如果您可以共享您所在的页面尝试刮擦我可以帮助你更多地使用纯scrapy来刮擦它,不需要飞溅或硒。