2011-03-01 54 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