如何在scrapy中使用非常大的“allowed_domains”属性?

时间:2016-04-06 02:58:36

标签: python-2.7 scrapy

以下是我的scrapy代码:

{{1}}

因为allowed_domains非常大,所以会抛出此异常:

  

regex = r'^(。*。)?(%s)$'%'|'。join(如果d不是None,则在allow_domains中对d执行re.escape(d))

如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

您可以构建自己的OffsiteMiddleware变体,使用不同的实施方式检查不在蜘蛛allowed_domains中的域的请求。

例如,将其添加到middlewares.py文件

from scrapy.spidermiddlewares.offsite import OffsiteMiddleware
from scrapy.utils.httpobj import urlparse_cached


class SimpleOffsiteMiddleware(OffsiteMiddleware):

    def spider_opened(self, spider):
        # don't build a regex, just use the list as-is
        self.allowed_hosts = getattr(spider, 'allowed_domains', [])
        self.domains_seen = set()

    def should_follow(self, request, spider):
        if self.allowed_hosts:
            host = urlparse_cached(request).hostname or ''
            # does 'www.example.com' end with 'example.com'?
            # test this for all allowed domains
            return any([host.endswith(h) for h in self.allowed_hosts])
        else:
            return True

并更改您的设置以禁用默认的OffsiteMiddleware,并添加您的:

SPIDER_MIDDLEWARES = {
    'scrapy.spidermiddlewares.offsite.OffsiteMiddleware': None,
    'myproject.middlewares.SimpleOffsiteMiddleware': 500,
}

警告:此中间件未经过测试。这是一个非常天真的实现,绝对不是非常有效(为每个请求测试每个50'000个可能域的字符串包含)。 您可以使用另一个后端来存储列表并测试主机名值,例如sqlite。