【问题标题】:Scrapy LinkExtractor - Limit the number of pages crawled per URLScrapy LinkExtractor - 限制每个 URL 抓取的页面数量
【发布时间】:2015-12-24 12:23:57
【问题描述】:

我正在尝试限制 Scrapy 中 CrawlSpider 中每个 URL 的爬网页面数。我有一个 start_urls 列表,我想对每个 URL 中正在抓取的页面数量设置一个限制。一旦达到限制,蜘蛛应该移动到下一个 start_url。

我知道设置中有 DEPTH_LIMIT 参数,但这不是我想要的。

任何帮助都会很有用。

这是我目前拥有的代码:

class MySpider(CrawlSpider):
    name = 'test'
    allowed_domains = domainvarwebsite
    start_urls = httpvarwebsite

    rules = [Rule(LinkExtractor(),
             callback='parse_item',
             follow=True)
            ]

    def parse_item(self, response):
        #here I parse and yield the items I am interested in.

编辑

我试图实现这一点,但我得到了 exceptions.SyntaxError: invalid syntax (filter_domain.py, line 20) 。有什么想法吗?

再次感谢。

filter_domain.py

import urlparse
from collections import defaultdict
from scrapy.exceptions import IgnoreRequest

class FilterDomainbyLimitMiddleware(object):
def __init__(self, domains_to_filter):
    self.domains_to_filter = domains_to_filter
    self.counter = defaultdict(int)

@classmethod
def from_crawler(cls, crawler):
    settings = crawler.settings
    spider_name = crawler.spider.name
    max_to_filter = settings.get('MAX_TO_FILTER')
    o = cls(max_to_filter)
    return o

def process_request(self, request, spider):
    parsed_url = urlparse.urlparse(request.url)
    (LINE 20:) if self.counter.get(parsed_url.netloc, 0) < self.max_to_filter[parsed_url.netloc]):
        self.counter[parsed_url.netloc] += 1
    else:
        raise IgnoreRequest()

settings.py

MAX_TO_FILTER = 30

DOWNLOADER_MIDDLEWARES = {
    'myproject.filter_domain.FilterDomainbyLimitMiddleware' :400,

}

【问题讨论】:

  • 第 20 行的 ':' 之前有一个前导 ')'。

标签: python web-crawler scrapy limit


【解决方案1】:

Scrapy 不直接提供此功能,但您可以创建自定义中间件,如下所示:

import urlparse
from collections import defaultdict
from scrapy.exceptions import IgnoreRequest

class FilterDomainbyLimitMiddleware(object):
    def __init__(self, domains_to_filter):
        self.domains_to_filter = domains_to_filter
        self.counter = defaultdict(int)

    @classmethod
    def from_crawler(cls, crawler):
        settings = crawler.settings
        spider_name = crawler.spider.name
        domains_to_filter = settings.get('DOMAINS_TO_FILTER')
        o = cls(domains_to_filter)
        return o

    def process_request(self, request, spider):
        parsed_url = urlparse.urlparse(request.url)
        if parsed_url.netloc in self.domains_to_filter:
            if self.counter.get(parsed_url.netloc, 0) < self.domains_to_filter[parsed_url.netloc]):
                self.counter[parsed_url.netloc] += 1
            else:
                raise IgnoreRequest()

并在如下设置中声明DOMAINS_TO_FILTER

DOMAINS_TO_FILTER = {
    'mydomain': 5
}

只接受来自该域的 5 个请求。还要记得在设置中启用中间件,如指定的here

【讨论】:

  • 太棒了!无论是哪个域,我如何修改您的代码以设置固定数量的请求?所以我只需要在 settings.py 上写一个 MAX_REQUESTS = 5 ?
  • 删除第一个if in process_request
  • 我尝试修改它,但出现错误。我已经编辑了我的问题以放置我正在使用的当前代码。
猜你喜欢
  • 2015-11-11
  • 1970-01-01
  • 1970-01-01
  • 2021-12-13
  • 2012-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多