源碼:
class CrawlSpider(Spider):
rules = ()
def __init__(self, *a, **kw):
super(CrawlSpider, self).__init__(*a, **kw)
self._compile_rules()
def parse(self, response):
return self._parse_response(response, self.parse_start_url, cb_kwargs={}, follow=True)
def parse_start_url(self, response):
return []
def process_results(self, response, results):
return results
def _build_request(self, rule, link):
r = Request(url=link.url, callback=self._response_downloaded)
r.meta.update(rule=rule, link_text=link.text)
return r
def _requests_to_follow(self, response):
if not isinstance(response, HtmlResponse):
return
seen = set()
for n, rule in enumerate(self._rules):
links = [lnk for lnk in rule.link_extractor.extract_links(response)
if lnk not in seen]
if links and rule.process_links:
links = rule.process_links(links)
for link in links:
seen.add(link)
r = self._build_request(n, link)
yield rule.process_request(r)
def _response_downloaded(self, response):
rule = self._rules[response.meta['rule']]
return self._parse_response(response, rule.callback, rule.cb_kwargs, rule.follow)
def _parse_response(self, response, callback, cb_kwargs, follow=True):
if callback:
cb_res = callback(response, **cb_kwargs) or ()
cb_res = self.process_results(response, cb_res)
for requests_or_item in iterate_spider_output(cb_res):
yield requests_or_item
if follow and self._follow_links:
for request_or_item in self._requests_to_follow(response):
yield request_or_item
def _compile_rules(self):
def get_method(method):
if callable(method):
return method
elif isinstance(method, six.string_types):
return getattr(self, method, None)
self._rules = [copy.copy(r) for r in self.rules]
for rule in self._rules:
rule.callback = get_method(rule.callback)
rule.process_links = get_method(rule.process_links)
rule.process_request = get_method(rule.process_request)
@classmethod
def from_crawler(cls, crawler, *args, **kwargs):
spider = super(CrawlSpider, cls).from_crawler(crawler, *args, **kwargs)
spider._follow_links = crawler.settings.getbool(
'CRAWLSPIDER_FOLLOW_LINKS', True)
return spider
def set_crawler(self, crawler):
super(CrawlSpider, self).set_crawler(crawler)
self._follow_links = crawler.settings.getbool('CRAWLSPIDER_FOLLOW_LINKS', True)
rules:
它是一個列表,存儲的元素時Rule類的實例,爬取規(guī)則,其中每一個實例都定義了一種采集站點的行為。如果有多個rule都匹配同一個鏈接,那么位置下標最小的一個rule將會被使用。
LinkExtractor
鏈接提取器是其唯一目的是從scrapy.http.Response最終將跟隨的網(wǎng)頁(對象)提取鏈接的對象。
有Scrapy,但你可以創(chuàng)建自己的自定義鏈接提取器,以滿足您的需求通??過實現(xiàn)一個簡單的界面。scrapy.linkextractors import LinkExtractor
每個鏈接提取器唯一的公共方法是extract_links接收一個Response對象并返回一個scrapy.link.Link對象列表。鏈接提取器意在被實例化一次,并且它們的extract_links方法被調(diào)用幾次,具有不同的響應以提取跟隨的鏈接。
鏈接提取程序CrawlSpider 通過一組規(guī)則在類中使用(可以在Scrapy中使用),但是您也可以在爬蟲中使用它,即使不從其中CrawlSpider提取子類 ,因為其目的非常簡單:提取鏈接。
LxmlLinkExtractor是推薦的鏈接提取器與方便的過濾選項。它使用lxml的強大的HTMLParser實現(xiàn)。
rules = (
Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),
Rule(LinkExtractor(allow=r'Items/',allow_domains=()),callback='parse_item', follow=True),
)
| 參數(shù) | 含義 |
|---|---|
| allow | 提取符合正則表達式的連接,如果沒有給出(或為空),它將匹配所有鏈接。 |
| deny | 提取不符合正則表達式的連接。它優(yōu)先于allow如果沒有給出(或為空),它不會排除任何鏈接。 |
| allow_domains(str或list) | 允許提取域名 |
| deny_domains(str或list) | 不允許提取域名 |
| restrict_xpaths | 使用xpath表達式和allow共同作用提取同時符合的連接 |
init:
在源碼中可以看到,它主要就是執(zhí)行了_compile_rules方法,這邊暫時不講。
parse:
默認回調(diào)方法,同上章一樣。不過在這里進行了重寫,這里直接調(diào)用方法_parse_response,并把parse_start_url方法作為處理response的方法。
parse_start_url:
這個方法在源碼中只看其定義是沒有什么發(fā)現(xiàn)的,需要查看其使用環(huán)境。它的主要作用就是處理parse返回的response,比如提取出需要的數(shù)據(jù)等,該方法也需要返回item、request或者他們的可迭代對象。它就是一個回調(diào)方法,和rule.callback用法一樣。
_requests_to_follow:
閱讀源碼可以發(fā)現(xiàn),它的作用就是從response中解析出目標url,并將其包裝成request請求。該請求的回調(diào)方法是_response_downloaded,這里為request的meta值添加了rule參數(shù),該參數(shù)的值是這個url對應rule在rules中的下標。
_response_downloaded:
該方法是方法_requests_to_follow的回調(diào)方法,作用就是調(diào)用_parse_response方法,處理下載器返回的response,設(shè)置response的處理方法為rule.callback方法。
_parse_response:
該方法將resposne交給參數(shù)callback代表的方法去處理,然后處理callback方法的requests_or_item。再根據(jù)rule.follow and spider._follow_links來判斷是否繼續(xù)采集,如果繼續(xù)那么就將response交給_requests_to_follow方法,根據(jù)規(guī)則提取相關(guān)的鏈接。spider._follow_links的值是從settings的CRAWLSPIDER_FOLLOW_LINKS值獲取到的。
_compile_rules:
這個方法的作用就是將rule中的字符串表示的方法改成實際的方法,方便以后使用。
from_crawler:
這個就不細說了,看看源碼就好,兩行代碼。