【问题标题】:Prevent the scrapy spider from crawling one part of the website too long防止scrapy爬虫爬取网站某一部分的时间过长
【发布时间】:2015-11-20 08:30:41
【问题描述】:

所以我构建了一个爬虫爬虫,它可以爬取网站内的所有内部链接。但是,当我运行蜘蛛时,有些网站的大部分网站与网站内容无关。例如,一个网站运行 Jenkins,而我的蜘蛛程序花费大量时间来探索与该网站完全无关的这些页面。

一种方法是创建一个黑名单并向其中添加一些路径,例如 Jenkins,但我想知道是否有更好的方法来处理这个问题。

class MappingItem(dict, BaseItem):
    pass

class WebsiteSpider(scrapy.Spider):
    name = "Website"

    def __init__(self):
        item = MappingItem()
        self.loader = ItemLoader(item)
        self.filter_urls = list()

    def start_requests(self):
        filename = "filename.csv"
        try:
            with open(filename, 'r') as csv_file:
                reader = csv.reader(csv_file)
                header = next(reader)
                for row in reader:
                    seed_url = row[1].strip()
                    base_url = urlparse(seed_url).netloc
                    self.filter_urls.append(base_url)
                    request = Request(seed_url, callback=self.parse_seed)
                    request.meta['base_url'] = base_url

                    yield request
        except IOError:
            raise CloseSpider("A list of websites are needed")

    def parse_seed(self, response):
        base_url = response.meta['base_url']
        # handle external redirect while still allowing internal redirect
        if urlparse(response.url).netloc != base_url:
            return
        external_le = LinkExtractor(deny_domains=base_url)
        external_links = external_le.extract_links(response)
        for external_link in external_links:
            if urlparse(external_link.url).netloc in self.filter_urls:
                self.loader.add_value(base_url, external_link.url)

        internal_le = LinkExtractor(allow_domains=base_url)
        internal_links = internal_le.extract_links(response)

        for internal_link in internal_links:
            request = Request(internal_link.url, callback=self.parse_seed)
            request.meta['base_url'] = base_url
            request.meta['dont_redirect'] = True
            yield request

【问题讨论】:

  • 您在使用链接提取器吗?显示蜘蛛代码的相关部分可能会有所帮助。谢谢!

标签: python web-scraping scrapy


【解决方案1】:

听起来 Link Extractor 的 deny_domains 参数可以用于不遵循的域的“黑名单”:

deny_domains (str or list) – 单个值或字符串列表 包含不会考虑提取链接的域

【讨论】:

  • 这似乎是一种解决方案,但问题是,即使在我面对蜘蛛大部分时间都在这个“天坑”之后,我也必须手动添加所有形式的天坑。
  • 我想到的一种规避方法是限制您可以在特定路径上进行的访问次数,但问题是当它们是固体内容时可能会有太多的误报沉洞。例如,如果蜘蛛在www.website.com/jenkins/ 上花费了数千个请求,那么它应该终止,但是如果 `www.website.com/articles/' 并且有数千篇文章,则蜘蛛应该发送请求,因为它们是相关材料。我想我需要做的是找到某种可以区分有用和无用网页的模式。
  • @THISUSERNEEDSHELP 明白了。您可能应该围绕它构建一些自定义逻辑 - 例如,具有定义域相关性的域优先级映射和用于计算每次访问次数的计数器字典(defaultdict(int) 我想)领域。然后你可以使用一些相关性来请求计数规则来确定你是否需要停止爬取特定的域。听起来您需要一个自定义中间件……只是一种感觉。
猜你喜欢
  • 2019-06-24
  • 2012-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多