scrapy 每个解析页产生的请求量很大,阻止了爬网

sg3maiej  于 2022-11-09  发布在  其他
关注(0)|答案(1)|浏览(127)

我有一个抓取,其中每个子页面包含300+链接,我需要遵循。爬行慢下来后,一分钟左右/有时它抓取0页/分钟。
如果我用10-50页的链接,每页有同样的问题不会显示爬行。
我已经配置了10个concurrent_requests和10个已处理项,React器线程池为400。这意味着每10个已处理项最多可产生3.000个产出...
日志记录显示解析函数每页花费70秒以上。日志记录显示此处所需的时间来自生成(每个生成最多花费2秒)。
这似乎是在等待引擎或类似的东西完成一个任务,并准备处理新的产量请求?添加请求到调度程序不需要很长时间,所以在我看来,产量是在等待其他东西。
有什么建议要调整或哪里出了问题吗?
是否可以批量生成请求而不是单独生成每个请求?是否可以将它们添加到调度程序而不生成它们?
其他信息:

  • 如果我使用scrapy-redis或者只是基于磁盘的调度程序,没有区别。
  • 由于呈现javascript,下载爬网页面可能需要10秒。
  • 自动油门已禁用
  • 如果我给予更多的cpu资源,它不会加快速度。

第一个
如果len(引擎.下载器.活动)变为0,则进行测试

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

爬网程序代码:

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)

同样的结果如果我这样做:

for link in 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
jtw3ybtb

jtw3ybtb1#

yield的性能是理想的,飞溅是什么让你慢下来,尝试让你的数据不使用飞溅,检查网络选项卡中的devtools找到真实的的请求加载您的动态内容,以避免使用飞溅,如果你可以分享一个页面,你试图刮我可以帮助你更多地刮它使用纯scrapy没有飞溅或 selenium 的需要。

相关问题