2011-03-01 31 views
3

我有一个蜘蛛,开始于蜘蛛开始时的一个小列表allowed_domains。我需要动态地将更多的域添加到此白名单中,因为蜘蛛程序从解析器中继续进行,但由于后续请求仍在过滤中,因此下面的一段代码无法完成。解析器中是否有更新allowed_domains动态添加到Scrapy蜘蛛的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) 

... 
+0

到OP:仅供参考,我不认为目前接受的答案真的会解决你的问题。查看该答案留下的评论。 – starrify 2015-10-08 05:52:44

回答

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(...) 

... 
+1

*不,该解决方案不适用于scrapy的任何现有版本(最高为1.0.3)*由于OffsiteMiddleware只在初始化预编译的正则表达式对象时才读取allowed_domains中的内容, 'spider_opened'信号,'allowed_domains'中的值永远不会被访问。因此,您更新该值的解决方案毫无用处。 – starrify 2015-10-08 05:51:36

6

(而此时这个答案写在非常时刻,scrapy最新版本是1.0.3这个答案应为所有最新版本的工作scrapy

由于OffsiteMiddleware仅当在处理spider_opened符号时初始化预编译的正则表达式对象时读取allowed_domains中的内容al,allowed_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这里应是蜘蛛类的一个实例。

参见:

+2

这实际上是正确的答案! – Rebornix 2016-02-18 13:17:19