Scrapy:仅关注外部链接

时间:2018-11-29 20:41:57

标签: python web-scraping scrapy

使用OffsiteMiddleware,您可以控制如何跟踪Scrapy中的外部链接。

我希望蜘蛛程序忽略网站上的所有内部链接,并仅 关注外部链接。

Dynamic rules不能将响应URL域添加到# Java RUN mkdir -p /usr/share/man/man1 && \ (echo "deb http://http.debian.net/debian stretch main" > /etc/apt/sources.list.d/backports.list) && \ apt-get update -y \ && apt-get install --no-install-recommends -y build-essential libkrb5-dev libsasl2-dev libffi-dev default-libmysqlclient-dev vim-tiny gosu krb5-user openjdk-8-jre openjdk-8-jdk-headless openjdk-8-jdk openjdk-8-jre-headless \ && apt-get clean RUN apt-get install unzip -y && \ apt-get autoremove -y

您可以覆盖deny_domains中的get_host_regex来过滤掉所有现场链接吗?还有其他方法吗?

说明:我希望蜘蛛程序忽略OffsiteMiddleware中定义的域,并爬行每个域上的所有内部链接。因此,当蜘蛛位于该URL上时,必须忽略每个URL的域名,后跟蜘蛛。 换句话说:当搜寻器到达example.com之类的网站时,我希望它忽略example.com上的任何链接,而只关注外部链接,而不是example.com上的站点。

2 个答案:

答案 0 :(得分:4)

您可以通过简单地反转should_follow()方法来创建反向异地中间件:

#mycrawler.middlewares.py

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

class ReverseOffsiteMiddleware(OffsiteMiddleware):

    seen = set()

    def should_follow(self, request, spider):
        allowed_domains = not super().should_follow(request, spider)
        # if failed to pass reverse allowed_domains don't follow
        if not allowed_domains:  
            return False

        # if visited domain before do not schedule request
        domain = urlparse_cached(request).hostname
        if domain in self.seen:
            return False
        # otherwise add to seen domain set and schedule request
        self.seen.add(domain)
        return True

然后在您的settings.py中激活它:

# settings.py
SPIDER_MIDDLEWARES = {
    'scrapy.spidermiddlewares.offsite.OffsiteMiddleware': None,
    'mycrawler.middlewares.ReverseOffsiteMiddleware': 500,
}

现在spider.allowed_domains中的所有域都将被忽略:)

答案 1 :(得分:0)

我的答案不使用Scrapy。如果您认为此回答与主题无关,请随时举报。

但是我提供的是一个解决方案,可以帮助您解决更普遍的问题。

我在解析google的结果时遇到了类似的问题。我不希望结果页面上显示的任何样板网址都包含在我的最终网址列表中。我也不想显示任何与Google相关的查询字符串。使用BeautifulSoup,re模块和requests模块,我能够做到这一点。

对于您的问题,我会说您只需要BeautifulSoup即可。您将需要一个用于过滤域的函数。该函数应采用两个参数,即引用和被测试的url。使用re模块,您可以检查测试url基本字符串是否与参考字符串相同;如果是,则可以合理地得出结论,这是一个内部网址。

您将使用BeautifulSoup解析包含<a>的{​​{1}}标签的html。