溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Python股票數(shù)據(jù)定向爬蟲是怎么樣的

發(fā)布時(shí)間:2021-10-26 17:22:48 來源:億速云 閱讀:128 作者:柒染 欄目:編程語言

Python股票數(shù)據(jù)定向爬蟲是怎么樣的,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。

功能簡(jiǎn)介

  • 目標(biāo): 獲取上交所和深交所所有股票的名稱和交易信息。

  • 輸出: 保存到文件中。

  • 技術(shù)路線: requests—bs4–re

  • 語言:python3.5

說明

  • 網(wǎng)站選擇原則: 股票信息靜態(tài)存在于html頁(yè)面中,非js代碼生成,沒有Robbts協(xié)議限制。

  • 選取方法: 打開網(wǎng)頁(yè),查看源代碼,搜索網(wǎng)頁(yè)的股票價(jià)格數(shù)據(jù)是否存在于源代碼中。

如打開新浪股票網(wǎng)址:鏈接描述(http://finance.sina.com.cn/realstock/company/sz000877/nc.shtml),如下圖所示:

Python股票數(shù)據(jù)定向爬蟲是怎么樣的

上圖中左邊為網(wǎng)頁(yè)的界面,顯示了天山股份的股票價(jià)格是13.06。右邊為該網(wǎng)頁(yè)的源代碼,在源代碼中查詢13.06發(fā)現(xiàn)沒有找到。所以判斷該網(wǎng)頁(yè)的數(shù)據(jù)使用js生成的,不適合本項(xiàng)目。因此換一個(gè)網(wǎng)頁(yè)。

再打開百度股票的網(wǎng)址:鏈接描述(https://gupiao.baidu.com/stock/sz300023.html),如下圖所示:

Python股票數(shù)據(jù)定向爬蟲是怎么樣的

從上圖中可以發(fā)現(xiàn)百度股票的數(shù)據(jù)是html代碼生成的,符合我們本項(xiàng)目的要求,所以在本項(xiàng)目中選擇百度股票的網(wǎng)址。

由于百度股票只有單個(gè)股票的信息,所以還需要當(dāng)前股票市場(chǎng)中所有股票的列表,在這里我們選擇東方財(cái)富網(wǎng),網(wǎng)址為:鏈接描述(http://quote.eastmoney.com/stocklist.html),界面如下圖所示:

Python股票數(shù)據(jù)定向爬蟲是怎么樣的

原理分析

查看百度股票每只股票的網(wǎng)址:https://gupiao.baidu.com/stock/sz300023.html,可以發(fā)現(xiàn)網(wǎng)址中有一個(gè)編號(hào)300023正好是這只股票的編號(hào),sz表示的深圳交易所。因此我們構(gòu)造的程序結(jié)構(gòu)如下:

  • 步驟1: 從東方財(cái)富網(wǎng)獲取股票列表;

  • 步驟2: 逐一獲取股票代碼,并增加到百度股票的鏈接中,***對(duì)這些鏈接進(jìn)行逐個(gè)的訪問獲得股票的信息;

  • 步驟3: 將結(jié)果存儲(chǔ)到文件。

接著查看百度個(gè)股信息網(wǎng)頁(yè)的源代碼,發(fā)現(xiàn)每只股票的信息在html代碼中的存儲(chǔ)方式如下:

Python股票數(shù)據(jù)定向爬蟲是怎么樣的

因此,在我們存儲(chǔ)每只股票的信息時(shí),可以參考上圖中html代碼的存儲(chǔ)方式。每一個(gè)信息源對(duì)應(yīng)一個(gè)信息值,即采用鍵值對(duì)的方式進(jìn)行存儲(chǔ)。在python中鍵值對(duì)的方式可以用字典類型。因此,在本項(xiàng)目中,使用字典來存儲(chǔ)每只股票的信息,然后再用字典把所有股票的信息記錄起來,***將字典中的數(shù)據(jù)輸出到文件中。

代碼編寫

首先是獲得html網(wǎng)頁(yè)數(shù)據(jù)的程序,在這里不多做介紹了,代碼如下:

#獲得html文本  def getHTMLText(url):      try:          r = requests.get(url)          r.raise_for_status()          r.encoding = r.apparent_encoding          return r.text      except:          return ""

接下來是html代碼解析程序,在這里首先需要解析的是東方財(cái)富網(wǎng)頁(yè)面:鏈接描述(http://quote.eastmoney.com/stocklist.html),我們打開其源代碼,如下圖所示:

Python股票數(shù)據(jù)定向爬蟲是怎么樣的

由上圖可以看到,a標(biāo)簽的href屬性中的網(wǎng)址鏈接里面有每只股票的對(duì)應(yīng)的號(hào)碼,因此我們只要把網(wǎng)址里面對(duì)應(yīng)股票的號(hào)碼解析出來即可。解析步驟如下:

***步,獲得一個(gè)頁(yè)面:

html = getHTMLText(stockURL)

第二步,解析頁(yè)面,找到所有的a標(biāo)簽:

soup = BeautifulSoup(html, 'html.parser')  a = soup.find_all('a')

第三步,對(duì)a標(biāo)簽中的每一個(gè)進(jìn)行遍歷來進(jìn)行相關(guān)的處理。處理過程如下:

1.找到a標(biāo)簽中的href屬性,并且判斷屬性中間的鏈接,把鏈接后面的數(shù)字取出來,在這里可以使用正則表達(dá)式來進(jìn)行匹配。由于深圳交易所的代碼以sz開頭,上海交易所的代碼以sh開頭,股票的數(shù)字有6位構(gòu)成,所以正則表達(dá)式可以寫為[s][hz]\d{6}。也就是說構(gòu)造一個(gè)正則表達(dá)式,在鏈接中去尋找滿足這個(gè)正則表達(dá)式的字符串,并把它提取出來。代碼如下:

for i in a:      href = i.attrs['href']      lst.append(re.findall(r"[s][hz]\d{6}", href)[0])

2.由于在html中有很多的a標(biāo)簽,但是有些a標(biāo)簽中沒有href屬性,因此上述程序在運(yùn)行的時(shí)候出現(xiàn)異常,所有對(duì)上述的程序還要進(jìn)行try…except來對(duì)程序進(jìn)行異常處理,代碼如下:

for i in a:      try:          href = i.attrs['href']          lst.append(re.findall(r"[s][hz]\d{6}", href)[0])      except:          continue

從上面代碼可以看出,對(duì)于出現(xiàn)異常的情況我們使用了continue語句,直接讓其跳過,繼續(xù)執(zhí)行下面的語句。通過上面的程序我們就可以把東方財(cái)富網(wǎng)上股票的代碼信息全部保存下來了。

將上述的代碼封裝成一個(gè)函數(shù),對(duì)東方財(cái)富網(wǎng)頁(yè)面解析的完整代碼如下所示:

def getStockList(lst, stockURL):      html = getHTMLText(stockURL)      soup = BeautifulSoup(html, 'html.parser')      a = soup.find_all('a')      for i in a:          try:              href = i.attrs['href']              lst.append(re.findall(r"[s][hz]\d{6}", href)[0])          except:              continue

接下來是獲得百度股票網(wǎng)鏈接描述(https://gupiao.baidu.com/stock/sz300023.html)單只股票的信息。我們先查看該頁(yè)面的源代碼,如下圖所示:

Python股票數(shù)據(jù)定向爬蟲是怎么樣的

股票的信息就存在上圖所示的html代碼中,因此我們需要對(duì)這段html代碼進(jìn)行解析。過程如下:

1.百度股票網(wǎng)的網(wǎng)址為:https://gupiao.baidu.com/stock/

一只股票信息的網(wǎng)址為:https://gupiao.baidu.com/stock/sz300023.html

所以只要百度股票網(wǎng)的網(wǎng)址+每只股票的代碼即可,而每只股票的代碼我們已經(jīng)有前面的程序getStockList從東方財(cái)富網(wǎng)解析出來了,因此對(duì)getStockList函數(shù)返回的列表進(jìn)行遍歷即可,代碼如下:

for stock in lst:  url = stockURL + stock + ".html"

2.獲得網(wǎng)址后,就要訪問網(wǎng)頁(yè)獲得網(wǎng)頁(yè)的html代碼了,程序如下:

html = getHTMLText(url)

3.獲得了html代碼后就需要對(duì)html代碼進(jìn)行解析,由上圖我們可以看到單個(gè)股票的信息存放在標(biāo)簽為div,屬性為stock-bets的html代碼中,因此對(duì)其進(jìn)行解析:

soup = BeautifulSoup(html, 'html.parser')  stockInfo = soup.find('div',attrs={'class':'stock-bets'})

4.我們又發(fā)現(xiàn)股票名稱在bets-name標(biāo)簽內(nèi),繼續(xù)解析,存入字典中:

infoDict = {}  name = stockInfo.find_all(attrs={'class':'bets-name'})[0]  infoDict.update({'股票名稱': name.text.split()[0]})

split()的意思是股票名稱空格后面的部分不需要了。

5.我們從html代碼中還可以觀察到股票的其他信息存放在dt和dd標(biāo)簽中,其中dt表示股票信息的鍵域,dd標(biāo)簽是值域。獲取全部的鍵和值:

keyList = stockInfo.find_all('dt')  valueList = stockInfo.find_all('dd')

并把獲得的鍵和值按鍵值對(duì)的方式村放入字典中:

for i in range(len(keyList)):  key = keyList[i].text  val = valueList[i].text  infoDict[key] = val

6.***把字典中的數(shù)據(jù)存入外部文件中:

with open(fpath, 'a', encoding='utf-8') as f:  f.write( str(infoDict) + '\n' )

將上述過程封裝成完成的函數(shù),代碼如下:

def getStockInfo(lst, stockURL, fpath):      for stock in lst:          url = stockURL + stock + ".html"          html = getHTMLText(url)          try:              if html=="":                  continue              infoDict = {}              soup = BeautifulSoup(html, 'html.parser')              stockInfo = soup.find('div',attrs={'class':'stock-bets'})              name = stockInfo.find_all(attrs={'class':'bets-name'})[0]              infoDict.update({'股票名稱': name.text.split()[0]})                            keyList = stockInfo.find_all('dt')              valueList = stockInfo.find_all('dd')              for i in range(len(keyList)):                  key = keyList[i].text                  val = valueList[i].text                  infoDict[key] = val                            with open(fpath, 'a', encoding='utf-8') as f:                  f.write( str(infoDict) + '\n' )          except:              continue

其中try…except用于異常處理。

接下來編寫主函數(shù),調(diào)用上述函數(shù)即可:

def main():      stock_list_url = 'http://quote.eastmoney.com/stocklist.html'      stock_info_url = 'https://gupiao.baidu.com/stock/'      output_file = 'D:/BaiduStockInfo.txt'      slist=[]      getStockList(slist, stock_list_url)      getStockInfo(slist, stock_info_url, output_file)

項(xiàng)目完整程序

# -*- coding: utf-8 -*-     import requests  from bs4 import BeautifulSoup  import traceback  import re  def getHTMLText(url):      try:          r = requests.get(url)          r.raise_for_status()          r.encoding = r.apparent_encoding          return r.text      except:          return ""  def getStockList(lst, stockURL):      html = getHTMLText(stockURL)      soup = BeautifulSoup(html, 'html.parser')      a = soup.find_all('a')      for i in a:          try:              href = i.attrs['href']              lst.append(re.findall(r"[s][hz]\d{6}", href)[0])          except:              continue  def getStockInfo(lst, stockURL, fpath):      count = 0      for stock in lst:          url = stockURL + stock + ".html"          html = getHTMLText(url)          try:              if html=="":                  continue              infoDict = {}              soup = BeautifulSoup(html, 'html.parser')              stockInfo = soup.find('div',attrs={'class':'stock-bets'})              name = stockInfo.find_all(attrs={'class':'bets-name'})[0]              infoDict.update({'股票名稱': name.text.split()[0]})                            keyList = stockInfo.find_all('dt')              valueList = stockInfo.find_all('dd')              for i in range(len(keyList)):                  key = keyList[i].text                  val = valueList[i].text                  infoDict[key] = val                            with open(fpath, 'a', encoding='utf-8') as f:                  f.write( str(infoDict) + '\n' )                  count = count + 1                  print("\r當(dāng)前進(jìn)度: {:.2f}%".format(count*100/len(lst)),end="")          except:              count = count + 1              print("\r當(dāng)前進(jìn)度: {:.2f}%".format(count*100/len(lst)),end="")              continue  def main():      stock_list_url = 'http://quote.eastmoney.com/stocklist.html'      stock_info_url = 'https://gupiao.baidu.com/stock/'      output_file = 'D:/BaiduStockInfo.txt'      slist=[]      getStockList(slist, stock_list_url)      getStockInfo(slist, stock_info_url, output_file)  main()

上述代碼中的print語句用于打印爬取的進(jìn)度。執(zhí)行完上述代碼后在D盤會(huì)出現(xiàn)BaiduStockInfo.txt文件,里面存放了股票的信息。

看完上述內(nèi)容,你們掌握Python股票數(shù)據(jù)定向爬蟲是怎么樣的的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI