050_Scrapy 爬虫框架 案例四大名著爬取
文章目錄
- 1. 認識 Scrapy
- 2. Scrapy 項目——四大名著爬取
- 2.1 items
- 2.2 spiders
- 2.3 Scrapy shell
- 2.4 Item Loaders
- 2.5 pipelines
- 2.6 settings
1. 認識 Scrapy
Scrapy爬蟲框架的優勢:
- 用戶只需要定制開發幾個模塊, 就可以輕松實現爬蟲,用來抓取網頁內容和圖片, 非常方便。
- Scrapy 使用了 Twisted 異步網絡框架來處理網絡通訊, 加快網頁下載速度, 不需要自己實現異步框架和多線程等, 并且包含了各種中間件接口, 靈活完成各種需求。
Scrapy架構流程:
只有當調度器中不存在任何request時,整個程序才會停止。(注:對于下載失敗的URL,
Scrapy也會重新下載.。)
Scrapy主要包括了以下組件:
- 引擎(Scrapy):用來處理整個系統的數據流,觸發事務(框架核心)
- 調度器(Scheduler):用來接受引擎發過來的請求,壓入隊列中,并在引擎再次請求的時候返回。可以想像成一個URL(抓取網頁的網址或者說是鏈接)的優先隊列,由它來決定下一個要抓取的網址是什么,同時去除重復的網址
- 下載器(Downloader):用于下載網頁內容,并將網頁內容返回給蜘蛛(Scrapy下載器是建立在 twisted 這個高效的異步模型上的)
安裝 Scrapy
pip install scrapyScrapy 爬蟲步驟:
- 新建爬蟲項目 ScrapyProject
- 明確抓取目標 —> 編寫item.py
- 制作spider,爬取頁面 ----> spiders/xxspider.py
- 存儲爬蟲,設置管道存儲爬取內容 —> pipelines.py
- 項目編寫完成后,啟動爬蟲功能 book
項目結構大體如下圖所示:
2. Scrapy 項目——四大名著爬取
Scrapy 項目介紹并分析:
‘http://shicimingju.com/book/sanguoyanyi.html’,
‘http://shicimingju.com/book/hongloumeng.html’,
‘http://shicimingju.com/book/shuihuzhuan.html’,
‘http://shicimingju.com/book/xiyouji.html’,
爬蟲流程:
2.1 items
抓取的主要目的是從非結構化源(通常是網頁)中提取結構化數據。 Scrapy Spider可以將提取的數據作為 Python 字典返回。 Python 字典雖然方便且熟悉,但缺乏結構容易在字段名稱中輸入錯誤或返回不一致的數據,尤其是在具有許多 spider 的大型項目中。
為了定義常見的輸出數據格式,Scrapy提供了Item類。 項目對象是用于收集抓取數據的簡單容器。 它們提供了類似于字典的API,并帶有方便的語法來聲明其可用字段。
示例:
# ScrapyProject/items.py import scrapy from scrapy.loader.processors import TakeFirstclass BookItem(scrapy.Item):"""定義Item類:1. 繼承scrapy.Item類2. 每個屬性指定為scrapy.Field(不管是什么類型)"""# name = scrapy.Field()# content = scrapy.Field()# bookname = scrapy.Field()name = scrapy.Field(output_processor=TakeFirst())content = scrapy.Field(output_processor=TakeFirst())bookname = scrapy.Field(output_processor=TakeFirst())2.2 spiders
BookSpider(如下2.4節示例代碼) 是你定義的類,是Scrapy用于從網站(或一組網站)中獲取信息的,必須繼承 Spider 的子類 (scrapy.Spider) ,并定義要發出的初始請求,可以選擇如何跟隨頁面中的鏈接,以及如何解析 (parse) 下載的頁面內容以提取數據。
Spider 子類 scrapy.Spider 中定義了一些屬性和方法:
-
name:標識 spider,它在一個項目中必須是唯一的,即不能為不同的Spider設置相同的名稱。
-
start_requests():必須返回一個可迭代的請求(可以返回請求列表或編寫一個生成器函數),Spider將從此開始。 隨后的請求將根據這些初始請求連續生成。
-
parse():調用該方法來處理為每個請求下載的響應。 response 參數是 TextResponse 的一個實例,該實例保存頁面內容并具有其他有用的方法來處理它。
parse()方法通常解析響應,提取數據并生成一個字典,并且能夠查找要遵循的新URL從中創建新請求(Request)。
2.3 Scrapy shell
Scrapy shell是一個交互式shell,在其中運行可以非常快速的調試爬蟲代碼,而不必運行Spider。 它是用于測試代碼提取數據,但是實際上也可以將其用于測試任何類型的代碼,因為它也是常規的 Python shell。
Scrapy shell 主要用于測試 XPath 或 CSS 表達式,并查看它們的工作方式以及從要抓取的網頁中提取數據。 可以在編寫 spider 程序時以交互方式測試你的表達式,而不必運行spider 程序來測試所有更改。
運行:
scrapy shell url
2.4 Item Loaders
Item Loaders 提供了一種方便的機制來填充爬取的 Items。 雖然,可使用它們自己的類似于字典的API填充Item,但 Item Loader 提供了更方便的 API,用于在 scrapy 過程中將數據填充到item對象中,自動執行一些常見任務(例如在分配原始數據之前解析原始提取的數據)。
換句話說,項目提供了已抓取數據的容器,而項目 Item Loaders 則提供了填充該容器的機制。
Item Loaders 旨在提供一種靈活,高效且容易的機制,以擴展或覆蓋不同的字段解析規則方便后續的維護。
基于 2.2、2.3、2.4的介紹,spider 的代碼示例(請結合對頁面的分析食用)如下所示:
# ScrapyProject/spiders/book.py import scrapy from scrapy import Request from scrapy.loader import ItemLoader from ScrapyProject.items import BookItemclass BookSpider(scrapy.Spider):# 爬蟲名稱必須唯一name = 'book'base_url = "http://shicimingju.com"# 起始的url地址,可以指定多個,有兩種方式確定# 1. start_urls=[] 屬性設置# 2. 通過 start_requests 方法生成起始url地址 --> 使用方法詳見https://doc.scrapy.org/en/latest/intro/tutorial.html#our-first-spiderstart_urls = ['http://shicimingju.com/book/sanguoyanyi.html','http://shicimingju.com/book/hongloumeng.html','http://shicimingju.com/book/shuihuzhuan.html','http://shicimingju.com/book/xiyouji.html',]def parse(self, response):"""圖書詳情頁解析1). 如何編寫好的解析代碼?可以使用 Scrapy 的交互式工具 scrapy shell url2). 如何處理解析后的數據? 通過 yield 返回解析數據的字典格式3). 如何獲取下載小數章節詳情頁的鏈接并下載到本地:param response::return:"""# 1). 獲取所有章節的li標簽chapters = response.xpath('//div[@class="book-mulu"]/ul/li')# 2). 遍歷每一個li標簽, 提取章節的詳細網址和章節名稱for chapter in chapters:# -). 創建ItemLoader對象, 將item對象和selector/response關聯l = ItemLoader(item=BookItem(), selector=chapter)# -). 根據xpath進行提取數據信息并填充到item對象的name屬性中l.add_xpath('name', './a/text()')# -). 將數據信息(書籍名稱)填充到item對象的bookname屬性中l.add_value('bookname', response.url.split('/')[-1].strip('.html'))detail_url = chapter.xpath('./a/@href').extract_first() # ....extract_first()獲得列表第一個值并轉換為字符串# 將章節詳情頁url提交到調度隊列,通過Downloader下載器下載并提交給self.parse_chater_detail解析器進行解析處理數據yield Request(url=self.base_url + detail_url,callback=self.parse_chater_detail,# meta={"name": name, "bookname": bookname}# -). load_item獲取item對象meta={'item': l.load_item()})def parse_chater_detail(self, response):"""章節詳情頁解析"""# 1. .xpath('string(.)') 獲取該標簽及子孫標簽所有的文本信息# 2. 如何將對象轉換為字符串?# - ....extract_first()/get() 獲得列表中第一個值并轉換為字符串# - ....extract()/get_all() 獲得列表中所有對象并將其轉換為字符串item = response.meta['item']content = response.xpath(".//div[@class='chapter_content']")[0].xpath('string(.)').get()item['content'] = contentyield item2.5 pipelines
spider 抓取了一個項目后,將其發送到項目管道(piplines),該管道通過依次執行的幾個組件對其進行處理。
每個項目管道組件(有時僅稱為“項目管道”)都是一個實現簡單方法的 Python 類。 他們接收到一個項目并對其執行操作,還決定該項目是否應該繼續通過管道或被刪除并不再處理。
piplines 的典型用途是:
- 清理HTML數據
- 驗證抓取的數據(檢查項目是否包含某些字段)
- 檢查重復項(并將其刪除)
- 將 scrapy 的 items 存儲在數據庫中
組件 process_item(self, item, spider) :
每個項目管道組件均調用此方法。 process_item() 必須執行以下操作之一:返回帶有數據的字典;返回Item(或任何后代類)對象;返回Deferred或引發DropItem異常。
刪除的項目不再由其他管道組件處理。
參數:
- item (Item object or a dict) – the item scraped
- spider (Spider object) – the spider which scraped the item
代碼示例:
import osclass ScrapyprojectPipeline(object):"""設置管道存儲爬取內容"""def process_item(self, item, spider):# books/xiyoujidirname = os.path.join("books", item["bookname"])if not os.path.exists(dirname):os.makedirs(dirname) # 遞歸創建目錄name = item["name"]# 文件名的相對路徑用join方法拼接:linux路徑拼接符是/;windows是\filename = os.path.join(dirname, name)# 寫入文件以 w 方式打開,并指定編碼格式為 utf-8 寫入中文with open(filename, "w", encoding="utf-8") as f:f.write(item["content"])# print("寫入文件%s成功" % name)return item2.6 settings
項目的設置文件 settings.py
最后,執行 scrapy crael book 后可以獲得:
總結
以上是生活随笔為你收集整理的050_Scrapy 爬虫框架 案例四大名著爬取的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: consonant combinatio
- 下一篇: js之Symbol类型