談起爬蟲必然要提起 Scrapy 框架,因為它能夠幫助提升爬蟲的效率,從而更好地實現(xiàn)爬蟲。 Scrapy 是一個為了抓取網(wǎng)頁數(shù)據(jù)、提取結構性數(shù)據(jù)而編寫的應用框架,該框架是封裝的,包含 request (異步調度和處理)、下載器(多線程的 Downloader)、解析器(selector)和 twisted(異步處理)等。對于網(wǎng)站的內容爬取,其速度非??旖荨?br> 也許讀者會感到迷惑,有這么好的爬蟲框架,為什么前面的章節(jié)還要學習使用 requests 庫請求網(wǎng)頁數(shù)據(jù)。其實,requests 是一個功能十分強大的庫,它能夠滿足大部分網(wǎng)頁數(shù)據(jù)獲取的需求。其工作原理是向服務器發(fā)送數(shù)據(jù)請求,至于數(shù)據(jù)的下載和解析,都需要自己處理,因而靈活性高;而由于 Scrapy 框架的封裝,使得其靈活性降低。 至于使用哪種爬蟲方式,完全取決于個人的實際需求。在沒有明確需求之前,筆者依然推薦初學者先選擇 requests 庫請求網(wǎng)頁數(shù)據(jù),而在業(yè)務實戰(zhàn)中產生實際需求時,再考慮 Scrapy 框架。 Scrapy 安裝直接使用 pip 安裝 Scrapy 會產生一些錯誤的安裝提示信息,導致 Scrapy 無法正常安裝。當然,既然有問題出現(xiàn),必然對應著許多的解決辦法。在 http://www.lfd./~gohlke/pythonlibs 網(wǎng)站中,擁有很多適用于 Windows 的、已經編譯好的 Python 第三方庫,讀者只需根據(jù)錯誤的安裝提示信息找到相應的包,進行安裝即可,此處不對這種方法進行詳細講解。本小節(jié)主要介紹如何在 PyCharm 中安裝 Scrapy。第一步,選擇 Anaconda 3 作為編譯環(huán)境。在 PyCharm 中單擊左上角 File 選項,單擊“Settings”按鈕,彈出如圖 1 所示界面,然后展開 Project Interpreter 的下拉菜單,選擇 Anaconda 3 的下拉菜單: 圖 1 這里需要提前安裝 Anaconda,安裝之后才能添加 Anaconda 編譯環(huán)境。 第二步,安裝 Scrapy。單擊圖 1 界面右上角綠色加號按鈕,彈出如圖 2 所示的界面。輸入并搜索“scrapy”,然后單擊“Install Package”按鈕。等待,直至出現(xiàn)“Pakage‘scrapy’ installed successfully”:圖 2 案例:用 Scrapy 抓取股票行情本案例將使用 Scrapy 框架,抓取某證券網(wǎng)站A股行情。爬取過程分為以下五步:
創(chuàng)建Scrapy爬蟲項目調出 CMD,輸入如下代碼并按【Enter】鍵,創(chuàng)建 Scrapy 爬蟲項目:scrapy startproject stockstar 其中 scrapy startproject 是固定命令,stockstar 是筆者設置的工程名字。運行上述代碼的目的是創(chuàng)建相應的項目文件,如下所示:
項目結構如圖 3 所示: 圖 3 項目結構 創(chuàng)建 scrapy 項目以后,在 settings 文件中有這樣的一條默認開啟的語句。 POBOTSOXT_OBEY = True robots.txt 是遵循 Robot 協(xié)議的一個文件,在 Scrapy 啟動后,首先會訪問網(wǎng)站的 robots.txt 文件,然后決定該網(wǎng)站的爬取范圍。有時我們需要將此配置項設置為 False。在 settings.py 文件中,修改文件屬性的方法如下。ROBOTSTXT_OBEY=False 右擊 E:\stockstar\stockstar 文件夾,在彈出的快捷菜單中選擇“Mark Directory as”命令→選擇“Sources Root”命令,這樣可以使得導入包的語法更加簡潔,如圖 4 所示。圖 4 定義一個item容器item 是存儲爬取數(shù)據(jù)的容器,其使用方法和 Python 字典類似。它提供了額外的保護機制以避免拼寫錯誤導致的未定義字段錯誤。首先需要對所要抓取的網(wǎng)頁數(shù)據(jù)進行分析,定義所爬取記錄的數(shù)據(jù)結構。在相應的 items.py 中建立相應的字段,詳細代碼如下: import scrapyfrom scrapy.loader import ItemLoaderfrom scrapy.loader.processors import TakeFirstclass StockstarItemLoader (ItemLoader):#自定義itemloader,用于存儲爬蟲所抓取的字段內容default_output_processor = TakeFirst()class StockstarItem (scrapy.Item) : # 建立相應的字段#define the fields for your item here like:#name = scrapy.Field()code = scrapy.Field() # 股票代碼abbr = scrapy.Field() # 股票簡稱last_trade = scrapy.Field() # 最新價chg_ratio = scrapy.Field() # 漲跌幅chg_amt = scrapy.Field() # 漲跌額chg_ratio_5min = scrapy.Field() # 5分鐘漲幅volumn = scrapy.Field() # 成交量turn_over = scrapy.Field() # 成交額 定義settings文件進行基本爬蟲設置在相應的 settings.py 文件中定義可顯示中文的 JSON Lines Exporter,并設置爬取間隔為 0.25 秒,詳細代碼如下:from scrapy.exporters import JsonLinesItemExporter #默認顯示的中文是閱讀性較差的Unicode字符#需要定義子類顯示出原來的字符集(將父類的ensure_ascii屬性設置為False即可)class CustomJsonLinesItemExporter(JsonLinesItemExporter):def __init__(self, file, **kwargs):super (CustomJsonLinesItemExporter, self).__init__(file, ensure_ascii=False, **kwargs)#啟用新定義的Exporter類\FEED_EXPORTERS = {'json':'stockstar.settings.CustomJsonLinesItemExporter',}...#Configure a delay for requests for the same website (default: 0)#See http:IIscrapy.readthedocs.org/en/latest/topics/settings.html#download-delay#See also autothrottle settings and docs DOWNLOAD DELAY = 0.25 編寫爬蟲邏輯在編寫爬蟲邏輯之前,需要在 stockstar/spider 子文件下創(chuàng)建 .py 文件,用于定義爬蟲的范圍,也就是初始 URL。接下來定義一個名為 parse 的函數(shù),用于解析服務器返回的內容。首先在 CMD 中輸入代碼,并生成 spider 代碼,如下所示: cd stockstar 圖 5 代碼詳情如圖 6 所示: 圖 6 隨后在 spiders/stock.py 文件下,定義爬蟲邏輯,詳細代碼如下: import scrapyfrom items import StockstarItem, StockstarItemLoader\class StockSpider(scrapy.Spider):name = 'stock' #定義爬蟲名稱allowed_domains = ['quote.stockstar.com'] #定義爬蟲域start_urls = ['http://quote.stockstar.com/stock/ranklist_a_3_1_1.html']#定義開始爬蟲鏈接def parse (self, response) : #撰寫爬蟲邏輯page = int (response.url.split("_")[-1].split(".")[0])#抓取頁碼item_nodes = response.css('#datalist tr')for item_node in item_nodes:#根據(jù)item文件中所定義的字段內容,進行字段內容的抓取item_loader = StockstarItemLoader(item=StockstarItem(), selector = item_node)item_loader.add_css("code", "td:nth-child(1) a::text")item_loader.add_css("abbr", "td:nth-child(2) a::text")item_loader.add_css("last_trade", “td:nth-child(3) span::text")item_loader.add_css("chg_ratio", "td:nth-child(4) span::text")item_loader.add_css("chg_amt", "td:nth-child(5) span::text")item_loader.add_css("chg_ratio_5min","td:nth-child(6) span::text")item_loader.add_css("volumn", "td:nth-child(7)::text")item_loader.add_css ("turn_over", "td:nth-child(8) :: text")stock_item = item_loader.load_item()yield stock_itemif item_nodes:next_page = page + 1next_url = response.url.replace ("{0}.html".format (page) , "{0}.html".format(next_page))yield scrapy.Request(url=next_url, callback=self.parse) 代碼調試為了調試方便,在 E:\stockstar 下新建一個 main.py,調試代碼如下:from scrapy.cmdline import execute E:\stockstar>scrapy crawl stock -o items.json 在代碼里可設置斷點(如在 spiders/stock.py 內),然后單擊“Run”選項按鈕→在彈出的菜單中選擇“Debug‘main’”命令,進行調試,如圖 7 和圖 8 所示。圖 7 圖 8 最后在 PyCharm 中運行 Run'main',運行界面如圖 9 所示: 圖 9 將所抓取的數(shù)據(jù)以 JSON 格式保存在 item 容器中。 知識擴展本文從實戰(zhàn)(抓取股票行情)出發(fā)講解 Scrapy 框架,致力于讓初學者快速了解 Python 爬蟲 Scarpy 框架的使用。 |
|