动态添加到Scrapy蜘蛛中的allowed_domains

时间:2011-03-01 23:45:52

标签: python screen-scraping scrapy

我有一只蜘蛛,在蜘蛛开始时以小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)

...

2 个答案:

答案 0 :(得分:7)

(在撰写此答案的那一刻,scrapy的最新版本为1.0.3。此答案适用于所有最新版本的scrapy

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

基本上,需要两个步骤:

  1. 根据您的实际需要更新allowed_domains的内容。
  2. OffsiteMiddleware刷新正则表达式缓存。
  3. 以下是我用于步骤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这里应该是蜘蛛类的一个实例。

    另见:

答案 1 :(得分: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(...)

...