天天看點

Scrapy--CrawlSpider全站爬取

CrawlSpider繼承了scrapy.spiders類

  • 增加了功能:允許客戶自定義方法來搜尋url繼續爬取。

使用CrawlSpider的優缺點

  • 優點:我們可以友善爬取我們想要的相關url
  • 缺點:由于Rules在擷取到url直接運作回調函數,在中間過程我們無法加入其它操作,使之有了局限性。

其他功能:可以配合redis完成增量式爬蟲

CrawlSpider的機制:

- 連結提取器: 可以根據指定的規則進行連接配接的提取
- 規則解析器: 跟據指定的規則對響應資料進行解析
           

Rules

連接配接提取器,一個包含一個(或多個) Rule 對象的集合(list)。 每個 Rule 對爬取網站的一類URL連結定義了特定表現。 如果多個Rule比對了相同的連結,則根據他們在本屬性中被定義的順序,第一個會被使用。

rules規則

  • link_extractor:定義需要提取的連結
  • callback:從link_extractor中每擷取到比對的連結時将會調用該函數。也就是規則解析器,我們可以自定義解析方式來擷取資料。
  • cb_kwargs 包含傳遞給回調函數的參數(keyword argument)的字典。
  • follow:如果 callback 為 None, follow 預設設定為 True ,否則預設為 False 。指定是否要跟進url,若為true,則尋找starts_url中所有的url,反之隻爬取與連結提取器相關的。
  • process_links 是一個callable或string(該spider 中同名的函數将作為回調函數被調用)。 從link_extractor 中擷取到連結清單時将會調用該函數。該方法主要用來過濾。
  • process_request 是一個callable或string(該spider 中同名的函數将作為回調函數被調用)。 該規則提取到每個request時都會調用該函數。該函數必須傳回一個request或者None。 (用來過濾request)

警告:當編寫爬蟲規則時,請避免使用 parse 作為回調函數。 由于 CrawlSpider 使用 parse 方法來實作其邏輯,如果 您覆寫了 parse 方法,crawl spider 将會運作失敗。

LinkExtractor

  • LinkExtractor是我們的規則解析器,我們通過它可以制定擷取規則(通過正則)來尋找我們需要的url。
  • 若allow裡面的内容為空,則全部url都被比對。

下面是我們的執行個體:電影天堂下載下傳連結

資料篩選和持久化略,這裡我們主要寫CrawlSpider

操作代碼

  • 建立項目:scrapy startproject 項目名
  • cd 到目錄
  • scrapy genspider -t crawl url
  • 啟動scrapy:scrapy crawl 爬蟲名 --nolog
  • nolog不列印日志
# spider編碼:
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from ..items import MvItem


class BSpider(CrawlSpider):
    name = 'mv'
    # allowed_domains = ['www.baidu.com']
    start_urls = ['https://www.ygdy8.net/html/gndy/oumei/index.html']
    # 定義兩個連結提取器,分别為首頁和詳情頁的
    # 由于我們不需要首頁的内容,是以首頁的連結提取器pass
    link = LinkExtractor(allow=r'list.*?html')
    link_detail = LinkExtractor(allow=r'.*?/\d+\.html')
    # 兩個函數為解析器
    rules = (
        Rule(link, callback='parse_item', follow=True,),
        Rule(link_detail, callback='parse_detail', follow=True,),
    )

    def parse_item(self, response):
        pass

    def parse_detail(self, response):
        title = response.xpath('//h1//text()').extract_first()
        downloadlink = response.xpath('//tbody/tr/td/a/text()').extract_first()
        if title and downloadlink and 'ftp' in downloadlink:
            item = BossItem()
            item['title'] = title
            item['downloadlink'] = downloadlink
            yield item
           
# item定義存儲字段:
import scrapy


class BossItem(scrapy.Item):
    title = scrapy.Field()
    downloadlink = scrapy.Field()
           

個人感覺CrawlSpider是非常強大的,省時省力,擷取我們需要的資料,後面我會寫基于CrawlSpider的增量式爬蟲。

參考部落格:pengjunlee的部落格