Python 3.x scrapy:将链接提取限制到请求域

Python 3.x scrapy:将链接提取限制到请求域,python-3.x,web-scraping,scrapy,web-crawler,domain-name,Python 3.x,Web Scraping,Scrapy,Web Crawler,Domain Name,我有一个scrapy项目,它使用来自不同域的URL列表作为种子,但是对于任何给定的页面,我只希望跟踪与该页面URL相同域中的链接(因此通常的LinkExtractor(accept='example.com'))这种方法行不通。我很惊讶在web上找不到解决方案,因为我希望这是一项常见的任务。我能想到的最好办法是在spider文件中找到它,并在规则中引用它: class CustomLinkExtractor(LinkExtractor): def get_domain(self, ur

我有一个scrapy项目,它使用来自不同域的URL列表作为种子,但是对于任何给定的页面,我只希望跟踪与该页面URL相同域中的链接(因此通常的
LinkExtractor(accept='example.com'))
这种方法行不通。我很惊讶在web上找不到解决方案,因为我希望这是一项常见的任务。我能想到的最好办法是在spider文件中找到它,并在规则中引用它:

class CustomLinkExtractor(LinkExtractor):

    def get_domain(self, url):
        # https://stackoverflow.com/questions/9626535/get-protocol-host-name-from-url
        return '.'.join(tldextract.extract(url)[1:])


    def extract_links(self, response):
        domain = self.get_domain(response.url)
        # https://stackoverflow.com/questions/40701227/using-scrapy-linkextractor-to-locate-specific-domain-extensions
        return list(
            filter(
                lambda link: self.get_domain(link.url) == domain,
                super(CustomLinkExtractor, self).extract_links(response)
            )
        )
但这不起作用(蜘蛛离开了域名)

现在,我尝试在规则中使用process_request选项:

    rules = (
        Rule(LinkExtractor(deny_domains='twitter.com'),
             callback='parse_response',
             process_request='check_r_r_domains',
             follow=True,
             ),
    )


但是我得到了一个异常,因为它正在将
self
传递给该方法(爬行器没有
url
属性);当我将
self
添加到方法签名时,我得到一个异常,即
响应
位置参数丢失!如果我将回调更改为
process\u request=self。检查\u r\u domains
,我会得到一个错误,因为
self
没有在我设置
规则的地方定义!

如果您正在使用或更高版本,您可以传递一个可调用的
进程\u请求
,以检查请求和响应的URL,并删除请求(
返回无
)如果域不匹配。

Oops,我使用的服务器上的conda安装了1.6版本的scrapy。我已经强制它从conda forge安装了1.8.0,我认为它现在可以工作了

    def check_r_r_domains(request, response):
        domain0 = '.'.join(tldextract.extract(request.url)[1:])
        domain1 = '.'.join(tldextract.extract(response.url)[1:])
        log('TEST:', domain0, domain1)
        if (domain0 == domain1) and (domain0 != 'twitter.com'):
            return request
        log(domain0, ' != ', domain1)
        return None