首页 > 解决方案 > Scrapy管道性能

问题描述

我目前正在将 Scrapy 用于个人项目,但在性能方面遇到了困难。

当我不使用管道时,我的 4 个模拟爬虫可以在 30 秒内爬取 600 个页面。

我已经实现了一个自定义管道来处理每个页面中的脚本,并将它们与 5000 个 url 列表进行比较,以检查 url 是否存在于脚本代码中。

问题是,当我不使用管道时,这会使我的爬网运行 110 秒而不是 30 秒。

我想知道如何优化我的代码,因为对于每个页面,我都会通过我的所有脚本检查我的每个链接。

下面是它的外观:

我们可以运行多线程以加快循环速度吗?

蜘蛛类中的解析函数:

    def parse(self, response):

    print('### SCANNED: %s', (response.request.url))

    if len(response.css('script').getall()) > 0:

        yield {
            'domain': response.meta['domain'],
            'scripts': response.css('script').getall()
        }

管道内的流程项功能

    def process_item(self, item, spider):

    domain = item['domain']
    scripts = item['scripts']

      for script in scripts: # There are about 15 scripts per item

        for script_group in self.script_groups: # There are about 5000 script_groups

            # Check all urls in script_group to see if script_group is being used

            for url in script_group['urls']: # There are about 2 urls per script_group
                # If at least one url found then script_group is being used

                if url in script:

                    print("url found, script_group is being used")
                    break

    return item

标签: pythonscrapy

解决方案


尽量避免这么多 for 循环。

例如:

  1. __init__在管道方法中创建一个正则表达式对象self.script_groups
    self.url_re = re.compile(
        '(?:{})'.format(
            '|'.join(
                re.escape(url)
                for url in group['urls']
                for group in self.script_groups
            )
        )
    )
  1. 用它:
    for script in scripts:
        if self.url_re.search(script):
            print("url found, script_group is being used")
            break

推荐阅读