中間件:
主要討論的是下載中間件,明確一下順序: download_middlewares --> server.url ---> spider_middleware
我主要是用來加header或者cookie,有的時候,用了scrapy-redis框架,直接往redis隊列里塞網頁,不同的domain有不同的cookie,不能共用一個cookie。
這里我不同的搜索引擎肯定用不同的cookie,整個process_request()函數返回None,表明加了這些cookie,header之后,繼續運行,參考 編寫下載中間件
代碼:
import urlparse, urllib, random, re import scrapy from scrapy import signals class RandomUserAgent(object): def process_request(self, request, spider): # http://scrapy-chs.readthedocs.io/zh_CN/1.0/topics/downloader-middleware.html#id2 有詳細講解 if request.method == 'GET': target_word = self.target(request) request.headers.setdefault('User-Agent', random.choice(USER_PC_AGENTS)) request.meta.setdefault('target_word', target_word) if 'baidu' in request.url: request.cookies = baiducookie elif 'so.360.cn' in request.url: request.cookies = san60cookie elif 'cn.bing' in request.url: request.cookies = biyingcookie pass def target(self, request): url = urllib.unquote(request.url) # 注意這里,網頁的編碼與解碼 m = re.search(r'[wdq]=(.*?)$', url) # print m.group(1) target_word = m.group(1) if isinstance(target_word, unicode): try: target_word = target_word.encode('utf-8') except: pass return target_word
擴展
extension得和signal結合起來使用,爬蟲在不停的干活的時候,往里面發送信號,發信號的意思是,他運行了信號的某個功能的時候,你在這個時候可以加函數進去,為所欲為。
例如:
class delay_test(object): def __init__(self, crawler): self.crawler = crawler crawler.signals.connect(self.bufore_request, signal=signals.response_received) @classmethod def from_crawler(cls, crawler): return cls(crawler) def bufore_request(self,response,spider): if 'www.so.com' in response.url: print '>>>sleep 2s' time.sleep(2) pass
同時在setting里面啟用這個擴展
這段代碼的意思是,每次獲得一個url含有固定詞的 response的時候,就會延遲2s,其實就是自定義設置里的delay了,我別的url不需要delay,特定的url需要delay,為所欲為。
編寫這個很簡單,主要是把信號的內容看懂就行了.
tips:
編寫中間件和擴展可以參考源碼進行改寫,源碼應該很容易看得懂,庫里面的default_setting都有包含了哪些extensions和middlewares。然后再找到對應的代碼,改寫過后,只需要在項目里面setting里關閉默認的,啟用你剛剛改寫的即可。