crawlSpider

源碼:

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:

這個就不細說了,看看源碼就好,兩行代碼。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 寫在前面 在Scrapy基礎(chǔ)——Spider中,我簡要地說了一下Spider類。Spider基本上能做很多事情了,...
    xuzhougeng閱讀 29,051評論 10 37
  • 前言 在之前的文章Scrapy學習筆記(2)-使用pycharm在虛擬環(huán)境中運行第一個spider中有提到在使用s...
    leeyis閱讀 1,188評論 0 0
  • 非原創(chuàng) CrawlSpider 通過下面的命令可以快速創(chuàng)建 CrawlSpider模板 的代碼: scrapy g...
    MononokeHime閱讀 335評論 0 2
  • 11月25偶然qq空間看見初中同學分享的一篇簡書上的文章,點進去一看是初中班主任的的減肥讓分享文章,瀏覽文章后不免...
    Sabrina_良辰閱讀 251評論 0 0
  • 今天上會計課講到銀行的時候,我突然想起一個人。 她是我同院的一個姐姐,我那時并不好看,沉默寡言又乏味,但她...
    南瑯子柒呀閱讀 415評論 0 0

友情鏈接更多精彩內(nèi)容