本文作者:hang
本文來源:https://segmentfault.com/a/1190000010520835
功能簡介
目標: 擷取上交所和深交所所有股票的名稱和交易資訊。
輸出: 儲存到檔案中。
技術路線: requests—bs4–re
語言:python3.5
說明
網站選擇原則: 股票資訊靜態存在於html頁面中,非js代碼產生,沒有Robbts協議限制。
選取方法: 開啟網頁,查看原始碼,搜尋網頁的股票價格資料是否存在於原始碼中。
如開啟新浪股票網址:連結描述(http://finance.sina.com.cn/realstock/company/sz000877/nc.shtml),如下圖所示:
上圖中左邊為網頁的介面,顯示了天山股份的股票價格是13.06。右邊為該網頁的原始碼,在原始碼中查詢13.06發現沒有找到。所以判斷該網頁的資料使用js產生的,不適合本項目。因此換一個網頁。
再開啟百度股票的網址:連結描述(https://gupiao.baidu.com/stock/sz300023.html),如下圖所示:
從上圖中可以發現百度股票的資料是html代碼產生的,符合我們本項目的要求,所以在本項目中選擇百度股票的網址。
由於百度股票只有單個股票的資訊,所以還需要當前股票市場中所有股票的列表,在這裡我們選擇東方財富網,網址為:連結描述(http://quote.eastmoney.com/stocklist.html),介面如下圖所示:
原理分析
查看百度股票每隻股票的網址:https://gupiao.baidu.com/stock/sz300023.html,可以發現網址中有一個編號300023正好是這隻股票的編號,sz表示的深圳證券交易所。因此我們構造的程式結構如下:
步驟1: 從東方財富網擷取股票列表;
步驟2: 逐一擷取股票代號,並增加到百度股票的連結中,最後對這些連結進行逐個的訪問獲得股票的資訊;
步驟3: 將結果儲存到檔案。
接著查看百度個股資訊網頁的原始碼,發現每隻股票的資訊在html代碼中的儲存方式如下:
因此,在我們儲存每隻股票的資訊時,可以參考上圖中html代碼的儲存方式。每一個資訊源對應一個資訊值,即採用索引值對的方式進行儲存。在python中索引值對的方式可以用字典類型。因此,在本項目中,使用字典來儲存每隻股票的資訊,然後再用字典把所有股票的資訊記錄起來,最後將字典中的資料輸出到檔案中。
代碼編寫
首先是獲得html網頁資料的程式,在這裡不多做介紹了,代碼如下:
#獲得html文本
def getHTMLText(url):
try:
r = requests.get(url)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return ""
接下來是html代碼解析程式,在這裡首先需要解析的是東方財富網頁面:連結描述(http://quote.eastmoney.com/stocklist.html),我們開啟其原始碼,如下圖所示:
由上圖可以看到,a標籤的href屬性中的網址連結裡面有每隻股票的對應的號碼,因此我們只要把網址裡面對應股票的號碼解析出來即可。解析步驟如下:
第一步,獲得一個頁面:
html = getHTMLText(stockURL)
第二步,解析頁面,找到所有的a標籤:
soup = BeautifulSoup(html, 'html.parser')
a = soup.find_all('a')
第三步,對a標籤中的每一個進行遍曆來進行相關的處理。處理過程如下:
1.找到a標籤中的href屬性,並且判斷屬性中間的連結,把連結後面的數字取出來,在這裡可以使用Regex來進行匹配。由於深圳證券交易所的代碼以sz開頭,上海證券交易所的代碼以sh開頭,股票的數字有6位構成,所以Regex可以寫為[s][hz]\d{6}。也就是說構造一個Regex,在連結中去尋找滿足這個Regex的字串,並把它提取出來。代碼如下:
for i in a:
href = i.attrs['href']
lst.append(re.findall(r"[s][hz]\d{6}", href)[0])
2.由於在html中有很多的a標籤,但是有些a標籤中沒有href屬性,因此上述程式在啟動並執行時候出現異常,所有對上述的程式還要進行try…except來對程式進行異常處理,代碼如下:
for i in a:
try:
href = i.attrs['href']
lst.append(re.findall(r"[s][hz]\d{6}", href)[0])
except: