說明:初學者,整理后方便能及時完善,冗余之處請多提建議,感謝!
了解內容:
Scrapy :抓取數據的爬蟲框架
異步與非阻塞的區別
異步:指的是整個過程,中間如果是非阻塞的,那就是異步過程;
非阻塞:關注拿到結果之前的狀態 (如果拿到結果前在等待,是阻塞,反之,是非阻塞)
理解:
Scrapy 基本工作流程(簡單--->復雜)



每個模塊間不通訊,模塊之間通過引擎進行數據傳輸


基本使用
一、創建spider
scrapy項目流程
---創建項目
---scrapy startproject xxxx
---創建爬蟲
---cd 項目目錄下
---scrapy genspider aaa allowed_domains"”
scrapy genspider first_spider
jpdd.com
first_spider 爬蟲名字
jpdd.com 限制爬取數據的范圍
--完善spider
---提取數據,提取url地址構成request對象
xpath extract_first()\extract() response.meta yield scrapy.Requeest
--完善管道
--運行爬蟲
--- cd 項目目錄
---scrapy crawl first_spider
注意:避免爬蟲名和項目名重復 ;
不管在終端還是pycharm 都要切換到當前目錄下 cd myspider
allowed_domains : 限定爬取的范圍
二、完善spider
---- 對數據的提取
1、 Scray 中的parse 做什么用途?
---處理start_urls 中的url地址的響應
2 、yiele 生成器的使用
好處:遍歷函數的返回值的時候,挨個把數據讀到內存,不會造成內存的瞬間占用過高
通過yield傳遞數據給管道,(類似轉發)
yield能夠傳遞的對象只能是:BaseItem, Request, dict, None
3 、使用.extract()把response.xpath()提取的數據轉化為字符串列表
.extract() 返回一個含有字符串的列表,沒有返回空列表
.extract_first() 提取列表中的第一個字符串,如果不存在,返回None
----例:
yield的使用:使用多個yield 來傳遞需要的數據


上面的代碼應該改成:yield item
4、 根據Response返回的url地址,對next_url的url地址進行拼接,構造請求,有5種方式
第1種:手動字符串相加
第2種:urllib.parse.urljoin(baseurl,url) 后面的url會根據baseurl進行url地址的拼接
第3種:response.follow(url ,callback) 能夠根據response的地址把url拼接完整,構造成Request對象,
但這個方法在python 1.0后的版本中才有
第4種(
推薦):response.urljoin(next_url)
更簡潔、好用
第5種:scrapy.Request(url,callback,meta,dont_filter)
---例:
# 第一種:手動拼接下一頁url
#主站鏈接 用來拼接 base_site = 'https://www.jpdd.com' def parse(self,response): book_urls = response.xpath('//table[@class="p-list"]//a/@href').extract() for book_url in book_urls: url = self.base_site + book_url yield scrapy.Request(url, callback=self.getInfo) #獲取下一頁 next_page_url = self.base_site + response.xpath( '//table[@class="p-name"]//a[contains(text(),"下一頁")]/@href' ).extract()[0] yield scrapy.Request(next_page_url, callback=self.parse)
使用urllib實現url地址拼接的原理:


三、完善管道
管道的設置也是以鍵值的形式

數據保存:可以是具體的item,也可以保存在文件中,如下2種方式
第一種:

第二種:


------數字越小,表示離引擎越近,數據越先經過處理,反之 。
-------使用多個管道時,前面的管道中要記得return xx 不然后面的管道接收不到前面的數據,會返回none
四、item的使用
為什么要單獨定義item?
定義item即提前規划好哪些字段需要抓取,scrapy.Field()僅僅是提前占坑,通過item.py能夠讓別人清楚自己的爬蟲是在抓取什么數據;
同時來提示哪些字段是需要抓取的,沒有定義的字段不能使用,防止手誤;
item不能直接存入mongodb中,需要轉化為字典后再存儲。
Item使用之前需要先導入並且實例化,之后的使用方法和使用字典相同
from yanguan.items import YanguanItem item = YanguanItem() #實例化
補充:
構造翻頁請求
meta 自身是個字典
Scrapy.Request() ===>相當於構造了一個requests對象
scrapy.Request(url[,callback,method="GET",headers,body,cookies,meta,dont_filter=False])
參數說明:
括號中的參數為可選參數
callback:表示當前的url的響應交給哪個函數去處理
meta:實現數據在不同的解析函數中傳遞,meta默認帶有部分數據,比如下載延遲,請求深度等
dont_filter:默認會過濾請求的url地址,即請求過的url地址不會繼續被請求,對需要重復請求的url地址可以把它設置為Ture,比如貼吧的翻頁請求,頁面的數據總是在變化;start_urls中的地址會被反復請求,否則程序不會啟動