1. 程式人生 > >股票資料爬蟲(Scrapy框架與requests-bs4-re技術路線)

股票資料爬蟲(Scrapy框架與requests-bs4-re技術路線)

Scrapy

中文名:抓取

一個功能強大、快速、優秀的第三方庫

它是軟體結構與功能元件的結合,可以幫助使用者快速實現爬蟲。

Python開發的一個快速、高層次的螢幕抓取和web抓取框架,用於抓取web站點並從頁面中提取結構化的資料。Scrapy用途廣泛,可以用於資料探勘、監測和自動化測試。

Scrapy吸引人的地方在於它是一個框架,任何人都可以根據需求方便的修改。它也提供了多種型別爬蟲的基類,如BaseSpider、sitemap爬蟲等,最新版本又提供了web2.0爬蟲的支援。

框架安裝

使用管理員許可權啟動command控制檯

\>pip install scrapy

測試安裝

輸入指令檢視所有scrpy命令

\>scrapy -h

出現以下介面則可視為安裝成功

我們還可以通過指令檢視幫助資訊:

\>scrapy --help

命令提示符輸出如下:


Scrapy框架常用命令:

我們本次實驗只用到了startprojectgenspidercrawl命令

Scrapy“5+2”框架結構

5個主體部分:

已有的功能實現:

Engine 控制模組間的資料流、根據條件觸發事件

Schedule 對所有爬取請求進行排程

 Downloader 根據請求下載網頁

需要配置實現:

Spiders 解析返回的響應、產生爬取項與新的爬取請求 

Item Pipelines 清理、檢驗和查重爬取項中的資料與資料儲存

2箇中間鍵(可配置)


SpiderMiddleware 修改、丟棄、新增請求或爬取項 

Downloader Middleware 修改、丟棄、新增請求或響應

1.  SpidersEngine傳送網頁資訊爬取請求     

2.  SchedulerEngine接收爬取請求並進行排程

3,4.  EngineScheduler獲得下一個網頁資訊爬取請求,通過中間鍵傳送給Downloader

5,6.  Downloader連線網際網路爬取網頁內容,形成響應(爬取內容)通過中間鍵與Engine傳送給Spiders

7.  Spiders處理獲得的響應(爬取內容),形成爬取項與新的網頁資訊爬取請求傳送給Engine

8.  Engine

將爬取項傳送給Item Pipelines,將新的爬取請求傳送給Scheduler進行排程,形成迴圈為資料處理與再次啟動爬蟲進行爬取提供資料。

功能概述:

·      技術:Scrapy
·      目標:獲取上交所和深交所的股票名稱與交易資訊
·      輸出:txt文件

獲取股票列表:

獲取個股資訊:

過程概述:

1.   編寫spider爬蟲處理連結的爬取和網頁解析

2.   編寫pipeline處理解析後的股票資料並存儲

具體流程

·      相關安裝

使用管理員許可權啟動command控制檯

\>pip install requests

\>pip install scrapy

====================================

接下來的工程我剛開始執行失敗,後通過以下四步才得以執行

(視個人情況而定)

#先解除安裝scrapy框架

1. pip uninstall scrapy  

#再解除安裝twisted框架

2. pip uninstall twisted 

重新安裝scrapy以及16.6.0版本的twisted

 #先安裝twisted框架

3. pip install twisted==16.6.0  

#再安裝scrapy--no-deps指不安裝依賴的twisted

4. pip  install scrapy--no-deps 

如仍不能執行可能需要安裝pywin32模組

\>pip install pywin32

·      建立工程和Spider模板


1. 轉到目標目錄

\>d:
\>cd pycodes

:目錄位置不限定)

2. 生成BaiduStocks專案

\>scrapy startproject BaiduStocks

3. 修改當前目錄

\>cd BaiduStocks

4. 生成stocks爬蟲

\>scrapy genspider stocks baidu.com

·      編寫spider

配置stocks.py

修改對返回頁面與新增的URL爬取請求的處理,使其解析返回的資訊

  1. import scrapy  
  2. import re  # 引入正則表示式庫
  3. class StocksSpider(scrapy.Spider):  
  4.     name = "stocks"
  5.     # 設定初始連結為股票列表頁面連結
  6.     start_urls = ['http://quote.eastmoney.com/stocklist.html']  
  7.     def parse(self, response):  # 獲取頁面中股票程式碼並生成對應股票頁面連結
  8.         # for迴圈提取頁面中所有<a>標籤中的連結
  9.         for href in response.css('a::attr(href)').extract():  
  10.             # 使用try...except忽略錯誤資訊
  11.             try:  
  12.                 # 通過正則表示式獲取股票程式碼
  13.                 stock = re.findall(r"[s][hz]\d{6}", href)[0]  
  14.                 # 生成對應股票程式碼的頁面連結
  15.                 url = 'https://gupiao.baidu.com/stock/' + stock + '.html'
  16.                 # 使用yield將函式定義為生成器將新請求重新提交給scrapy
  17.                 yield scrapy.Request(url, callback=self.parse_stock)  
  18.             except:  
  19.                 continue
  20.     def parse_stock(self, response):  # 從對應股票程式碼的頁面提取資訊
  21.         infoDict = {}  # 生成空字典
  22.         stockInfo = response.css('.stock-bets')  # 找到屬性為"stock-bets"的區域
  23.         # 在區域中檢索"bets-name"屬性提取股票名稱
  24.         name = stockInfo.css('.bets-name').extract()[0]  
  25.         # 提取股票中的其他資訊儲存為鍵值對
  26.         keyList = stockInfo.css('dt').extract()  
  27.         valueList = stockInfo.css('dd').extract()  
  28.         for i in range(len(keyList)):  # 將提取到的股票資訊儲存在字典中
  29.             key = re.findall(r'>.*</dt>', keyList[i])[0][1:-5]  
  30.             try:  
  31.                 val = re.findall(r'\d+\.?.*</dd>', valueList[i])[0][0:-5]  
  32.             except:  
  33.                 val = '--'
  34.             infoDict[key] = val  
  35.         # 儲存對應股票程式碼的股票頁面中的股票名稱和相關資訊
  36.         infoDict.update(  
  37.             {'股票名稱': re.findall('\s.*\(', name)[0].split()[0] + \  
  38.                      re.findall('\>.*\<', name)[0][1:-1]})  
  39.         # 使用yield將函式定義為生成器傳遞資訊給後續處理的pipeline模組
  40.         yield infoDict  
·      編寫Pipelines

配置pipelines.py

定義對爬取項的處理類

  1. # -*- coding: utf-8 -*-
  2. # Define your item pipelines here
  3. #
  4. # Don't forget to add your pipeline to the ITEM_PIPELINES setting
  5. # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
  6. class BaidustocksPipeline(object):  
  7.     def process_item(self, item, spider):  
  8.         return item  
  9. class BaidustocksInfoPipeline(object):  # 嘗試定義新類
  10.     def open_spider(self, spider):  # 爬蟲呼叫時,對應啟動的方法
  11.         self.f = open('BaiduStockInfo.txt''w')  # 開啟檔案
  12.     def close_spider(self, spider):  # 爬蟲關閉時,對應啟動的方法
  13.         self.f.close()  # 關閉檔案
  14.     def process_item(self, item, spider):  # 對item項的處理方法
  15.         try:  
  16.             line = str(dict(item)) + '\n'
  17.             self.f.write(line)  # 把每一個股票的字典資訊寫入檔案中
  18.         except:  
  19.             pass
  20.         return item  # 讓其他函式也可以處理當前item

·      配置ITEM_PIPELINES選項

settings.py找到以下程式碼塊

  1. # ITEM_PIPELINES = {
  2. #    'BaiduStocks.pipelines.BaidustocksPipeline': 300,
  3. # }

將指向的pipelines修改為剛才定義的處理類BaidustocksInfoPipeline

  1. ITEM_PIPELINES = {  
  2.     'BaiduStocks.pipelines.BaidustocksInfoPipeline'300,  
  3. }  
·      執行爬蟲

使用管理員許可權啟動command控制檯

修改當前路徑:

\>d:

\>cd pycodes

\>cd BaiduStocks

執行爬蟲

\>scrapy crawl stocks


執行結束會在BaiduStocks資料夾生成BaiduStockInfo.txt

內容如下


我們還可以採用Beautiful Soup庫與Requests庫通過requests-bs4-re技術路線製作股票資料爬蟲

Beautiful soup

BeautifulSoup是Python的一個庫,最主要的功能就是從網頁爬取我們需要的資料。BeautifulSoup將html解析為物件進行處理,全部頁面轉變為字典或者陣列,相對於正則表示式的方式,可以大大簡化處理過程。

BeautifulSoup預設支援Python的標準HTML解析庫,但是它也支援一些第三方的解析庫:

解析庫

使用方法

優勢

劣勢

Python標準庫

BeautifulSoup(html,’html.parser’)

Python內建標準庫;執行速度快

容錯能力較差

lxml HTML解析庫

BeautifulSoup(html,’lxml’)

速度快;容錯能力強

需要安裝,需要C語言庫

lxml XML解析庫

BeautifulSoup(html,[‘lxml’,’xml’])

速度快;容錯能力強;支援XML格式

需要C語言庫

htm5lib解析庫

BeautifulSoup(html,’htm5llib’)

以瀏覽器方式解析,最好的容錯性

速度慢

Requests

目前公認的爬取網頁最好的第三方庫

簡單,簡潔,甚至只用一行程式碼就可以從網頁上獲得相關資源

Requests庫的七個主要方法:

具體實現

安裝相關庫,使用管理員許可權啟動command控制檯

\>pip install beautifulsoup4

\>pip install requests

測試安裝Requests

出現以下介面則可視為成功安裝Requests

測試安裝Beautiful Soup


出現以下介面即可視為安裝成功Beautiflu Soup

·      程式碼實現
  1. import requests  
  2. from bs4 import BeautifulSoup  
  3. import traceback  # 引用traceback庫方便除錯
  4. import re  
  5. # 獲得url對應的頁面,第二個引數為編碼方式
  6. def getHTMLText(url, code="utf-8"):  
  7.     try:  # 使用try...except規避錯誤資訊
  8.         r = requests.get(url)  # 通過get函式獲取url資訊
  9.         r.raise_for_status()  # 產生異常資訊
  10.         r.encoding = code  # 直接修改編碼方式提高效率
  11.         return r.text  # 將資訊返回給程式的其他部分
  12.     except:  
  13.         return ""  # 出現錯誤則返回空字串
  14. def getStockList(lst, stockURL):  
  15.     # 獲得股票的資訊列表,第一個引數為列表型別,第二個為獲得資訊的url
  16.     html = getHTMLText(stockURL, "GB2312")  # 獲得股票列表頁面
  17.     # 使用beautifulsoup解析頁面
  18.     soup = BeautifulSoup(html, 'html.parser')  
  19.     a = soup.find_all('a')  # 找到頁面中所有<a>標籤
  20.     for i in a:  
  21.         try:  # 使用try...except規避錯誤資訊
  22.             href = i.attrs['href']  # 找到<a>標籤中所有href屬性
  23.