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的部落格