股票資料爬蟲(Scrapy框架與requests-bs4-re技術路線)
Scrapy
中文名:抓取
一個功能強大、快速、優秀的第三方庫
它是軟體結構與功能元件的結合,可以幫助使用者快速實現爬蟲。
Python開發的一個快速、高層次的螢幕抓取和web抓取框架,用於抓取web站點並從頁面中提取結構化的資料。Scrapy用途廣泛,可以用於資料探勘、監測和自動化測試。
Scrapy吸引人的地方在於它是一個框架,任何人都可以根據需求方便的修改。它也提供了多種型別爬蟲的基類,如BaseSpider、sitemap爬蟲等,最新版本又提供了web2.0爬蟲的支援。
框架安裝
使用管理員許可權啟動command控制檯
\>pip install scrapy
測試安裝
輸入指令檢視所有scrpy命令
\>scrapy -h
出現以下介面則可視為安裝成功
我們還可以通過指令檢視幫助資訊:
\>scrapy --help
命令提示符輸出如下:
Scrapy框架常用命令:
我們本次實驗只用到了startproject、genspider和crawl命令
Scrapy“5+2”框架結構
5個主體部分:
已有的功能實現:
Engine 控制模組間的資料流、根據條件觸發事件
Schedule 對所有爬取請求進行排程
Downloader 根據請求下載網頁
需要配置實現:
Spiders 解析返回的響應、產生爬取項與新的爬取請求
Item Pipelines 清理、檢驗和查重爬取項中的資料與資料儲存
2箇中間鍵(可配置):
SpiderMiddleware 修改、丟棄、新增請求或爬取項
Downloader Middleware 修改、丟棄、新增請求或響應
1. Spiders向Engine傳送網頁資訊爬取請求
2. Scheduler從Engine接收爬取請求並進行排程
3,4. Engine從Scheduler獲得下一個網頁資訊爬取請求,通過中間鍵傳送給Downloader
5,6. Downloader連線網際網路爬取網頁內容,形成響應(爬取內容)通過中間鍵與Engine傳送給Spiders
7. Spiders處理獲得的響應(爬取內容),形成爬取項與新的網頁資訊爬取請求傳送給Engine
8. Engine
功能概述:
· 技術: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爬取請求的處理,使其解析返回的資訊
- import scrapy
- import re # 引入正則表示式庫
- class StocksSpider(scrapy.Spider):
- name = "stocks"
- # 設定初始連結為股票列表頁面連結
- start_urls = ['http://quote.eastmoney.com/stocklist.html']
- def parse(self, response): # 獲取頁面中股票程式碼並生成對應股票頁面連結
- # for迴圈提取頁面中所有<a>標籤中的連結
- for href in response.css('a::attr(href)').extract():
- # 使用try...except忽略錯誤資訊
- try:
- # 通過正則表示式獲取股票程式碼
- stock = re.findall(r"[s][hz]\d{6}", href)[0]
- # 生成對應股票程式碼的頁面連結
- url = 'https://gupiao.baidu.com/stock/' + stock + '.html'
- # 使用yield將函式定義為生成器將新請求重新提交給scrapy
- yield scrapy.Request(url, callback=self.parse_stock)
- except:
- continue
- def parse_stock(self, response): # 從對應股票程式碼的頁面提取資訊
- infoDict = {} # 生成空字典
- stockInfo = response.css('.stock-bets') # 找到屬性為"stock-bets"的區域
- # 在區域中檢索"bets-name"屬性提取股票名稱
- name = stockInfo.css('.bets-name').extract()[0]
- # 提取股票中的其他資訊儲存為鍵值對
- keyList = stockInfo.css('dt').extract()
- valueList = stockInfo.css('dd').extract()
- for i in range(len(keyList)): # 將提取到的股票資訊儲存在字典中
- key = re.findall(r'>.*</dt>', keyList[i])[0][1:-5]
- try:
- val = re.findall(r'\d+\.?.*</dd>', valueList[i])[0][0:-5]
- except:
- val = '--'
- infoDict[key] = val
- # 儲存對應股票程式碼的股票頁面中的股票名稱和相關資訊
- infoDict.update(
- {'股票名稱': re.findall('\s.*\(', name)[0].split()[0] + \
- re.findall('\>.*\<', name)[0][1:-1]})
- # 使用yield將函式定義為生成器傳遞資訊給後續處理的pipeline模組
- yield infoDict
· 編寫Pipelines
配置pipelines.py
定義對爬取項的處理類
- # -*- coding: utf-8 -*-
- # Define your item pipelines here
- #
- # Don't forget to add your pipeline to the ITEM_PIPELINES setting
- # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
- class BaidustocksPipeline(object):
- def process_item(self, item, spider):
- return item
- class BaidustocksInfoPipeline(object): # 嘗試定義新類
- def open_spider(self, spider): # 爬蟲呼叫時,對應啟動的方法
- self.f = open('BaiduStockInfo.txt', 'w') # 開啟檔案
- def close_spider(self, spider): # 爬蟲關閉時,對應啟動的方法
- self.f.close() # 關閉檔案
- def process_item(self, item, spider): # 對item項的處理方法
- try:
- line = str(dict(item)) + '\n'
- self.f.write(line) # 把每一個股票的字典資訊寫入檔案中
- except:
- pass
- return item # 讓其他函式也可以處理當前item
· 配置ITEM_PIPELINES選項
在settings.py找到以下程式碼塊
- # ITEM_PIPELINES = {
- # 'BaiduStocks.pipelines.BaidustocksPipeline': 300,
- # }
將指向的pipelines修改為剛才定義的處理類BaidustocksInfoPipeline
- ITEM_PIPELINES = {
- 'BaiduStocks.pipelines.BaidustocksInfoPipeline': 300,
- }
· 執行爬蟲
使用管理員許可權啟動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庫
· 程式碼實現
- import requests
- from bs4 import BeautifulSoup
- import traceback # 引用traceback庫方便除錯
- import re
- # 獲得url對應的頁面,第二個引數為編碼方式
- def getHTMLText(url, code="utf-8"):
- try: # 使用try...except規避錯誤資訊
- r = requests.get(url) # 通過get函式獲取url資訊
- r.raise_for_status() # 產生異常資訊
- r.encoding = code # 直接修改編碼方式提高效率
- return r.text # 將資訊返回給程式的其他部分
- except:
- return "" # 出現錯誤則返回空字串
- def getStockList(lst, stockURL):
- # 獲得股票的資訊列表,第一個引數為列表型別,第二個為獲得資訊的url
- html = getHTMLText(stockURL, "GB2312") # 獲得股票列表頁面
- # 使用beautifulsoup解析頁面
- soup = BeautifulSoup(html, 'html.parser')
- a = soup.find_all('a') # 找到頁面中所有<a>標籤
- for i in a:
- try: # 使用try...except規避錯誤資訊
- href = i.attrs['href'] # 找到<a>標籤中所有href屬性
- #