1. 程式人生 > >經典爬蟲:用Scrapy爬取百度股票

經典爬蟲:用Scrapy爬取百度股票

前言

今天我們編寫一個用 Scrapy 框架來爬取百度股票的程式碼,之前寫過一篇爬取百度股票的文章(點我),程式碼的邏輯和這篇文章的邏輯是一樣的,用到的解析器不同罷了。

經典爬蟲:用Scrapy爬取百度股票

 

Scrapy 爬蟲框架

Scrapy 爬蟲框架是由 7+2 的結構構成: 引擎(Scrapy Engine) 、排程器(Schedule)下載器(Downloader) 、爬蟲(Spider) 、專案通道(Item Pipeline) 和 下載中間器(Downloader Middlewares) 、爬蟲中間器(Spider Middlewares)

 。

經典爬蟲:用Scrapy爬取百度股票

 

 

Scrapy 中的資料流(Data flow)由執行引擎控制,如下所示:

  1. 引擎 從 Spider 中獲得需要爬取初始的 Requests 。
  2. 引擎 在 排程器 中排程 Requests 並詢問下一個需要爬取的 Requests 。
  3. 排程器 向 引擎 返回下一個要爬取的 Requests。
  4. 引擎 通過 下載中間器 把這個 Requests 傳遞給 下載器 。
  5. 一旦頁面下載完畢,下載器
     生成一個 Response (包含那個頁面),並通過 下載中介軟體 把它傳遞給引擎。
  6. 引擎 從 下載器 中接收 Response ,通過 爬蟲中介軟體 的處理傳遞給 Spider 。
  7. Spider 處理完 Response 後,通過 爬蟲中介軟體 向 引擎 返回生成的 items 和新的 Requests (如果有的話)。
  8. 引擎 把 items 傳遞給 Item Pipelines ,並把處理過的 Requests 傳遞給 排程器
     ,詢問新的 requests。
  9. 程式從步驟 1 開始重複,直到 排程器 中不再有更多的請求為止。

更多 Scrapy 資訊參考官方文件:

URL:https://scrapy.org/

建立 Scrapy 專案

在電腦配置好 Scrapy 後,

在 D 盤 建立名為 pycodes 的資料夾。

經典爬蟲:用Scrapy爬取百度股票

 

 

開啟 cmd 命令視窗,進入 D 盤 根目錄後鍵入:

  1. cd d:pycodes 進入目錄。
  2. scrapy startproject BaiduStocks 建立名為 BaiduStocks 的目錄。
  3. cd BaiduStocks 進入專案目錄。
  4. scrapy genspider stocks baidu.com 建立一個名為 stocks 的 .py 檔案,爬蟲的初始 URL 為 baidu.com 。
  5. 在 BaiduStocks 資料夾下找到 stocks.py 檔案後用 IDE 開啟,下面我們來編寫程式碼。

 

經典爬蟲:用Scrapy爬取百度股票

 

 

stocks.py

import scrapyimport reclass stocksSpider(scrapy.Spider):
 name = 'stocks'
 start_urls = ['http://quote.eastmoney.com/stocklist.html']
 def parse(self, response):
 for href in response.css('a::attr(href)').extract():
 try:
 stock = re.findall('[s][zh]d{6}', href)[0]
 url = 'http://gupiao.baidu.com/stock/' + stock + '.html'
 yield scrapy.Request(url, callback=self.parse_stock)
 except:
 continue
 def parse_stock(self, response):
 infoDict = {}
 stockInfo = response.css('.stock-bets') #只搜尋'.stock-bets'標籤下的'dt'和'dd'標籤
 stockname = stockInfo.css('.bets-name').extract()
 keyList = stockInfo.css('dt').extract()
 valueList = stockInfo.css('dd').extract()
 for i in range(len(keyList)):
 key = re.findall('<dt.*?>(.*?)</dt>', keyList)[0]
 try:
 value = re.findall('<dd.*?>(.*?)</dd>', valueList)[0]
 except:
 value = '--'
 infoDict[key] = value
 infoDict.update({'股票名稱': re.findall('<a.*?">(.*?)(<span.*?)', stockname)})
 yield infoDict
  • parse 函式用到關鍵字 yield ,由於 parse 函式生成的股票 URL 超過 4500 個,如果以列表形式傳遞給 parse_stocks , 給記憶體造成的負擔會更大。
  • 在資料夾 BaiduStocks 下找到 pipelines.py ,用 IDE 開啟。

pipelines.py

# -*- coding: utf-8 -*-# Define your item pipelines here## Don't forget to add your pipeline to the ITEM_PIPELINES setting# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.htmlclass BaidustocksPipeline(object):
 def open_item(self, spider):
 self.f = open('baiduStockInfo.txt', 'w')
 def close_item(self, spider):
 self.f.close()
 def process_item(self, item, spider):
 try:
 line = str(dict(item)) + '
'
 self.f.write(line)
 except:
 pass
 return item

類 BaiduStocksPipeline 有三個函式: open_item 、 close_item 、 process_item 。

至此,程式碼編寫完成,執行程式,結果會儲存在一個名為 baiduStockInfo 的 txt 檔案中