本篇文章,通過 scrapy 架構來實現相同的功能。scrapy 是一個為了爬取網站資料,提取結構性資料而編寫的應用程式框架。關於架構使用的更多詳情可瀏覽官方文檔,本篇文章展示的是爬取漫畫圖片的大體實現過程。 scrapy環境配置 安裝
首先是 scrapy 的安裝,博主用的是Mac系統,直接運行命令列:
pip install Scrapy
對於html節點資訊的提取使用了 Beautiful Soup 庫,大概的用法可見之前的一篇文章,直接通過命令安裝:
pip install beautifulsoup4
對於目標網頁的 Beautiful Soup 對象初始化需要用到 html5lib 解譯器,安裝的命令:
pip install html5lib
安裝完成後,直接在命令列運行命令:
scrapy
可以看到如下輸出結果,這時候證明scrapy安裝完成了。
Scrapy 1.2.1 - no active projectUsage: scrapy <command> [options] [args]Available commands: bench Run quick benchmark test commands fetch Fetch a URL using the Scrapy downloader genspider Generate new spider using pre-defined templates runspider Run a self-contained spider (without creating a project) settings Get settings values ...
項目建立
通過命令列在當前路徑下建立一個名為 Comics 的項目
scrapy startproject Comics
建立完成後,目前的目錄下出現對應的專案檔夾,可以看到產生的Comics檔案結構為:
|____Comics| |______init__.py| |______pycache__| |____items.py| |____pipelines.py| |____settings.py| |____spiders| | |______init__.py| | |______pycache__|____scrapy.cfg
Ps. 列印當前檔案結構命令為:
find . -print | sed -e 's;{FNXX==XXFN}*/;|____;g;s;____|; |;g'
每個檔案對應的具體功能可查閱官方文檔,本篇實現對這些檔案涉及不多,所以按下不表。 建立Spider類
建立一個用來實現具體爬取功能的類,我們所有的處理實現都會在這個類中進行,它必須為 scrapy.Spider 的子類。
在 Comics/spiders 檔案路徑下建立 comics.py 檔案。
comics.py 的具體實現:
#coding:utf-8import scrapyclass Comics(scrapy.Spider): name = "comics" def start_requests(self): urls = ['http://www.xeall.com/shenshi'] for url in urls: yield scrapy.Request(url=url, callback=self.parse) def parse(self, response): self.log(response.body);
自訂的類為scrapy.Spider的子類,其中的name屬性為該爬蟲的唯一標識,作為scrapy爬取命令的參數。其他方法的屬性後續再解釋。 運行
建立好自訂的類後,切換到Comics路徑下,運行命令,啟動爬蟲任務開始爬取網頁。
scrapy crawl comics
列印的結果為爬蟲運行過程中的資訊,和目標爬取網頁的html源碼。
2016-11-26 22:04:35 [scrapy] INFO: Scrapy 1.2.1 started (bot: Comics)2016-11-26 22:04:35 [scrapy] INFO: Overridden settings: {'ROBOTSTXT_OBEY': True, 'BOT_NAME': 'Comics', 'NEWSPIDER_MODULE': 'Comics.spiders', 'SPIDER_MODULES': ['Comics.spiders']}2016-11-26 22:04:35 [scrapy] INFO: Enabled extensions:['scrapy.extensions.corestats.CoreStats', 'scrapy.extensions.telnet.TelnetConsole', 'scrapy.extensions.logstats.LogStats'] ...
此時,一個基本的爬蟲建立完成了,下面是具體過程的實現。 爬取漫畫圖片 起始地址
爬蟲的起始地址為:
http://www.xeall.com/shenshi
我們主要的關注點在於頁面中間的漫畫列表,列表下方有顯示頁數的控制項。如下圖所示
1.jpg
爬蟲的主要任務是爬取列表中每一部漫畫的圖片,爬取完當前頁後,進入下一頁漫畫列表繼續爬取漫畫,依次不斷迴圈直至所有漫畫爬取完畢。
起始地址的url我們放在了start_requests函數的urls數組中。其中start_requests是重載了父類的方法,爬蟲任務開始時會執行到這個方法。
start_requests方法中主要的執行在這一行代碼:請求指定的url,請求完成後調用對應的回呼函數self.parse
scrapy.Request(url=url, callback=self.parse)
對於之前的代碼其實還有另一種實現方式:
#coding:utf-8import scrapyclass Comics(scrapy.Spider): name = "comics" start_urls = ['http://www.xeall.com/shenshi'] def parse(self, response): self.log(response.body);
start_urls是架構中提供的屬性,為一個包含目標網頁url的數組,設定了start_urls的值後,不需要重載start_requests方法,爬蟲也會依次爬取start_urls中的地址,並在請求完成後自動調用parse作為回調方法。
不過為了在過程中方便調式其它的回呼函數,demo中還是使用了前一種實現方式。 爬取漫畫url
從起始網頁開始,首先我們要爬取到每一部漫畫的url。 當前頁漫畫列表
起始頁為漫畫列表的第一頁,我們要從當前頁中提取出所需資訊,動過實現回調parse方法。
在開頭匯入BeautifulSoup庫
from bs4 import BeautifulSoup
請求返回的html源碼用來給BeautifulSoup初始化。
def parse(self, response): content = response.body; soup = BeautifulSoup(content, "html5lib")
初始化指定了html5lib解譯器,若沒安裝這裡會報錯。BeautifulSoup初始化時若不提供指定解譯器,則會自動使用自認為匹配的最佳解譯器,這裡有個坑,對於目標網頁的源碼使用預設最佳解譯器為lxml,此時解析出的結果會有問題,而導致無法進行接下來的資料提取。所以當發現有時候提取結果又問題時,列印soup看看是否正確。
查看html源碼可知,頁面中顯示漫畫列表的部分為類名為listcon的ul標籤,通過listcon類能唯一確認對應的標籤
2.jpg
提取包含漫畫列表的標籤
listcon_tag = soup.find('ul', class_='listcon')
上面的find方法意為尋找class為listcon的