開啟Scrapy爬蟲之路
@[TOC]
摘要
七夜大佬的《python爬蟲開發與項目實戰》,買了好多年了,學習了好多東西,基本上爬蟲都是在這里面學的,后期的scrapy框架爬蟲一直不得門而入,前段時間補了下面向對象的知識,今天突然頓悟了!寫個筆記記錄下學習過程
1.scrapy安裝
# -i參數后跟清華鏡像源,加速下載,其他pip的包也可這么操作 pip install Scrapy -ihttps://pypi.tuna.tsinghua.edu.cn/simple
測試如下圖表示安裝成功
其他參考方法:win7安裝scrapy
2.相關命令介紹
scrapy命令分為
全局命令:全局命令就是在哪都能用;
項目命令:項目命令就是只能依托你的項目;
2.1全局命令
全局命令就是上圖安裝測試時主動跳出來的那些命令
startproject、genspider、settings、runspider、shell、fetch、view、version
比較常用的有三個:
scrapy startproject project_name # 創建項目 scrapy crawl spider_name # 運行名為spider_name的爬蟲項目 # 調試網址為https://blog.csdn.net/qq_35866846的網站 scrapy shell "https://blog.csdn.net/qq_35866846"
全局命令就是不依托項目存在的,也就是不關你有木有項目都能運行,
比如:startproject它就是創建項目的命令,肯定是沒有項目也能運行;
詳細用法說明:
startproject
# 使用頻次最高,用于項目創建,eg:創建一個名為:cnblogSpider的項目 scrapy strartproject cnblogSpider
genspider
# 用于創建爬蟲模板,example是spider名稱,生成文件在spiders下面,也是后面寫爬蟲的地方 # 注意spider名稱不能和項目相同 scrapy genspider example example.com
詳情請參考scrapy命令:scrapy genspider詳解
settings
# 查看scray參數設置 scrapy settings --get DOWNLOAD_DELAY # 查看爬蟲的下載延遲 scrapy settings --get BOT_NAME # 爬蟲的名字
runspider
運行蜘蛛除了使用前面所說的scrapy crawl XX之外,我們還能用:runspider;
crawl是基于項目運行,runspide是基于文件運行,
也就是說你按照scrapy的蜘蛛格式編寫了一個py文件,如果不想創建項目,就可以使用runspider,eg:編寫了一個:test.py的蜘蛛,你要直接運行就是:
scrapy runspider test.py
shell
# 這個命令比較重要,主要是調試用,里面還有很多細節的命令 # 最簡單常用的的就是調試,查看我們的選擇器到底有木有正確選中某個元素 scrapy shell "https://www.cnblogs.com/qiyeboy/default.html?page=1" # 然后我們可以直接執行response命令, #比如我們要測試我們獲取標題的選擇器正不正確: response.css("title").extract_first() # 以及測試xpath路徑選擇是否正確 response.xpath("http://*[@id='mainContent']/div/div/div[2]/a/span").extract()
fetch
這個命令其實也可以歸結為調試命令的范疇!它的功效就是模擬我們的蜘蛛下載頁面,也就是說用這個命令下載的頁面就是我們蜘蛛運行時下載的頁面,這樣的好處就是能準確診斷出,我們的到的html結構到底是不是我們所看到的,然后能及時調整我們編寫爬蟲的策略!舉個栗子,淘寶詳情頁,我們一般看得到,但你如果按常規的方法卻爬不到,為神馬?因為它使用了異步傳輸!因此但你發現獲取不到內容的時候,你就要有所警覺,感覺用fetch命令來吧它的html代碼拿下來看看,到底有木有我們想要的那個標簽節點,如果木有的話,你就要明白我們需要使用js渲染之類的技術!用法很簡單:
scrapy fetch http://www.scrapyd.cn
就這樣,如果你要把它下載的頁面保存到一個html文件中進行分析,我們可以使用window或者linux的輸出命令,這里演示window下如下如何把下載的頁面保存:
scrapy fetch http://www.scrapyd.cn >d:/3.html
可以看到,經過這個命令,scrapy下載的html文件已經被存儲,接下來你就全文找找,看有木有那個節點,木有的話,毫無懸念,使用了異步加載!
view
# 和fetch類似都是查看spider看到的是否和你看到的一致,便于排錯 scrapy view https://blog.csdn.net/qq_35866846
version
# 查看scrapy版本 scrapy version
2.2項目命令
項目命令比較簡單,感覺沒什么好說的,我也沒怎么詳細測試,
直接參考這篇【scrapy 命令行:scrpay項目命令】
3.scrapy框架介紹
Scrapy 是一個用python寫的Crawler Framework,簡單輕巧,并且十分方便,使用Twisted這個一部網絡庫來處理網絡通信,架構清晰,并包含了各種中間件接口,可以靈活地完成各種需求,整體架構組成如下圖
Scrapy引擎(Engine): 引擎負責控制數據流在系統的所有組件中流動,并在相應動作發生時觸發事件;
調度器(Scheduler): 調度器從引擎接收request 并將他們入隊,以便之后引擎請求request時提供引擎;
下載器(Downloader): 下載器負責獲取頁面數據并提供給引擎,而后提供給Spider;
Spider: Spider是Scrapy用戶編寫用于分析Response 并提取Item(即獲取到的Item)或額外跟進的URL的類,每個Spider負責處理一個特定(或一些)網站
Item Pipeline: Item Pipeline 負責處理被Spider提取出來的Item .典型的處理有清理驗證及持久化(例如存儲到數據庫中);
下載器中間件(Downloader middlewares): 下載器中間件是在引擎及下載器之間的特定鉤子(specific hook),處理Downloader傳遞給引擎的Response。其提供了一個簡單的機制,通過插入自定義代碼來擴展Scrapy功能;
Spider中間件(Spider middlwares): Spider中間件是在引擎及Spider之間的特定鉤子(specific hook), 處理Spider的輸入(response)和輸出(items 及request)其中提供了一個簡便的機制,通過插入自定義代碼來實現Scrapy功能。
4.Scrapy中數據流的流轉
引擎打開一個網站(open a domain),找到處理該網站的Spider 并向該Spider請求第一個要爬取的URL
引擎從Spider中獲取第一個要爬取的URL并通過調度器(Schedule)以Request進行調度
引擎向調度器請求下一個要爬取的URL
調度器返回下一個要爬取的URL給引擎,引擎降URL通過下載中間件(請求(request)方向)轉發給下載器(Downloader)
一旦頁面下載完畢,下載器生成一個該頁面的Response,并將其通過下載中間件(返回(response)方向)發送給引擎
引擎從下載器中接收到Response并通過Spider中間件(輸入方向)發送給Spider處理
Spider處理Response并返回爬取到的Item及(跟進的)新的Request給引擎
引擎將(Spider返回的)爬取到的Item 給Item Pipeline,將(Spider返回的)Request給調度器
(從第二步)重復直到調度器中沒有更多的Request,引擎關閉網站
5.第一個scrapy爬蟲
七夜大佬《》的案例項目,由于書買的比較早,里面用的還是python2
自己動手在python3的環境下實現一下
5.1創建項目
# 創建一個名為cnblogSpider 的Scrapy項目 scrapy startproject cnblogSpider
創建好項目之后,直接使用pycharm打開,繼續工作即可
結構性文件自動生成,把框架填充起來即可
scrapy.cfg: 項目部署文件
cnblogSpider/ : 給項目的python模塊,之后可以在此加入代碼
cnblogSpider/items.py:項目中的Item文件
cnblogSpider/pipelines.py:項目中的Pipelines文件
cnblogSpider/settings.py:項目的配置文件
cnblogSpider/spiders/:放置Spider代碼的目錄
5.2創建爬蟲模塊
from ..items import CnblogspiderItem class CnblogsSpider(scrapy.Spider): name = "cnblogs" # 爬蟲的名稱 allowed_domains = ["cnblogs.com"] # 允許的域名 start_urls = [ "https://www.cnblogs.com/qiyeboy/default.html?page=1" ] def parse(self, response): # 實現網頁解析 # 首先抽取所有文章 papers = response.xpath("http://*[@class='day']") # 從每篇文章中抽取數據 for paper in papers: url = paper.xpath(".//*[@class='postTitle']/a/@href").extract()[0] title = paper.xpath(".//*[@class='postTitle']/a/span/text()").extract()[0] time = paper.xpath(".//*[@class='dayTitle']/a/text()").extract()[0] content = paper.xpath(".//*[@class='postCon']/div/text()").extract()[0] # print(url, title, time, content) item = CnblogspiderItem(url=url, title=title, time=time, content=content) yield item next_page = Selector(response).re(u'下一頁') if next_page: yield scrapy.Request(url=next_page[0], callback=self.parse)
5.3定義item
# Define here the models for your scraped items # # See documentation in: # https://docs.scrapy.org/en/latest/topics/items.html import scrapy class CnblogspiderItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() url = scrapy.Field() time = scrapy.Field() title = scrapy.Field() content = scrapy.Field() class newCnblogsItem(CnblogspiderItem): body = scrapy.Field() # title = scrapy.Field(CnblogspiderItem.Fields['title'], serializer = my_serializer)
5.4構建Item Pipeline
# Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html # useful for handling different item types with a single interface from itemadapter import ItemAdapter import json from scrapy.exceptions import DropItem from .items import CnblogspiderItem class CnblogspiderPipeline(object): def __init__(self): self.file = open('papers.json', 'w', encoding='UTF-8') def process_item(self, item, spider): if item['title']: line = json.dumps(dict(item)) + '\n' # print(type(line)) # self.file.write(line.encode()) # 注意open "wb" 寫入的是字節流,“w”寫入的是str # 使用decode 和 encode進行字節流和str的相互轉化 self.file.write(line) return item else: raise DropItem(f"Missing title in {item}")
5.5 激活Item Pipeline
定制完Item Pipeline ,它是無法工作的需要進行激活,要啟用一個Item Pipeline組件
必須將它的類添加到settings.py中的ITEM_PIPELINES 變量中
自動創建的Scrapy直接把settings.py中的該行取消注釋即可
TEM_PIPELINES 變量中可以配置很多個Item Pipeline組件,分配給每個類的整型值確定了他們的運行順序,item 按數字從低到高的順序通過Item Pipeline,取值范圍0 ~1000
ITEM_PIPELINES = { 'cnblogSpider.pipelines.CnblogspiderPipeline': 300, }
激活完成后,將命令行切換到項目目錄下執行
scrapy crawl cnblogs
參考資料
【1】書《python爬蟲開發與項目實戰》和 隨書代碼
【2】scrapy1.5中文文檔
GitHub Python Scrapy
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。