4

我有一个蜘蛛,它以蜘蛛开始时的一个小列表allowed_domains开头。我需要动态地将更多域添加到此白名单中,因为从解析器中继续进行爬虫,但是由于后续请求仍在过滤中,因此以下代码无法完成。allowed_domains解析器中是否有另一个更新?

class APSpider(BaseSpider):
name = "APSpider"

allowed_domains = ["www.somedomain.com"]

start_urls = [
    "http://www.somedomain.com/list-of-websites",
]

...

def parse(self, response):
    soup = BeautifulSoup( response.body )

    for link_tag in soup.findAll('td',{'class':'half-width'}):
        _website = link_tag.find('a')['href']
        u = urlparse.urlparse(_website)
        self.allowed_domains.append(u.netloc)

        yield Request(url=_website, callback=self.parse_secondary_site)

...
4

2 回答 2

9

(在编写此答案时,最新版本scrapy1.0.3。此答案适用于所有最新版本scrapy

由于仅在处理信号时初始化预编译的正则表达式对象时才OffsiteMiddleware读取内容,因此以后永远不会访问其中的值。 因此仅仅更新内容并不能解决问题。allowed_domainsspider_openedallowed_domains
allowed_domains

基本上,需要两个步骤:

  1. allowed_domains根据您的实际需要更新内容。
  2. OffsiteMiddleware刷新正则表达式缓存。

这是我用于第 2 步的代码:

# Refresh the regex cache for `allowed_domains`
for mw in self.crawler.engine.scraper.spidermw.middlewares:
    if isinstance(mw, scrapy.spidermiddlewares.offsite.OffsiteMiddleware):
        mw.spider_opened(self)

上面的代码应该在响应回调中调用,因此self这里应该是蜘蛛类的一个实例。

也可以看看:

于 2015-10-08T06:01:00.913 回答
1

您可以尝试以下方法:

class APSpider(BaseSpider):
name = "APSpider"

start_urls = [
    "http://www.somedomain.com/list-of-websites",
]

def __init__(self):
    self.allowed_domains = None

def parse(self, response):
    soup = BeautifulSoup( response.body )

    if not self.allowed_domains:
        for link_tag in soup.findAll('td',{'class':'half-width'}):
            _website = link_tag.find('a')['href']
            u = urlparse.urlparse(_website)
            self.allowed_domains.append(u.netloc)

            yield Request(url=_website, callback=self.parse_secondary_site)

    if response.url in self.allowed_domains:
        yield Request(...)

...
于 2011-03-02T03:52:40.333 回答