爬蟲爬取網頁信息的思路:發送網頁端請求—>獲取響應內容—>解析內容—> 獲取想要的數據—>保存數據

這次我們要實現的是爬取靜態網頁的股票數據,首先是獲取滬深A股的所有股票代碼,再用這些股票代碼獲取相應股票的信息

東方財富網有所有個股的股票代碼(滬深A股所有股票)

查看其網頁源代碼

python爬蟲實戰——爬取股票個股信息_第1張圖片

在網頁源代碼中可以搜索到相應的元素,判斷其是數據是靜態的

接下來是獲取每只個股的信息,由于周六日沒開市,東方財富網的個股信息沒有顯示

python爬蟲實戰——爬取股票個股信息_第2張圖片

這里改用百度股市通(個股)

python爬蟲實戰——爬取股票個股信息_第3張圖片

同樣地檢查元素可以發現個股的信息也是靜態的
準備工作:通過pip導入beautifulsoup4模塊
查看python目錄下的文件 scripts/easy_install 存不存在
如果存在執行 easy_install.exe pip
安裝成功后執行 pip install beautifulsoup4
首先獲取所有股票的列表
一、獲取東方財富網股票列表的網頁源代碼:

#- -coding:utf-8 - -

from urllib import request

對于python 3來說,urllib是一個非常重要的一個模塊 ,可以非常方便的模擬瀏覽器訪問互聯網,對于python 3 爬蟲來說, urllib更是一個必不可少的模塊,它可以幫助我們方便地處理URL.
urllib.request是urllib的一個子模塊,可以打開和處理一些復雜的網址

from bs4 import BeautifulSoup

Beautiful Soup將復雜HTML文檔轉換成一個復雜的樹形結構,每個節點都是Python對象,所有對象可以歸納為4種:Tag、NavigableString、BeautifulSoup、Comment|**

模擬瀏覽器爬取信息

在訪問某些網站的時候,網站通常會用判斷訪問是否帶有頭文件來鑒別該訪問是否為爬蟲,用來作為反爬取的一種策略。

Python中urllib中的request模塊提供了模擬瀏覽器訪問的功能

url=r'http://quote.eastmoney.com/stocklist.html'
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'}
page = request.Request(url, headers=headers)

其中headers是一個字典,通過這種方式可以將爬蟲模擬成瀏覽器對網站進行訪問。

page_info=request.urlopen(page).read()

urllib.request.urlopen()方法實現了打開url,并返回一個 http.client.HTTPResponse對象,通過http.client.HTTPResponse的read()方法,獲得response body,轉碼最后通過print()打印出來.

page_info=page_info.decode('GB2312',errors='ignore')

decode('GB2312',errors='ignore')用來將頁面轉換成GB2312-8的編碼格式,否則會出現亂碼,編碼的格式取決于網頁的編碼形式,可在網頁源代碼head查看
獲得網頁的html代碼后,自然就是要將我們所需要的部分從雜亂的html代碼中分離出來。這里#使用Python中一種比較友好且易用的數據提取方式——BeautifulSoup

soup=BeautifulSoup(page_info,'html.parser')

將獲取到的內容轉換成BeautifulSoup格式,并將html.parser作為解析器,這是Python標準庫中的解析器
用開發者查看網頁源碼發現股票代碼包含在 標簽中

python爬蟲實戰——爬取股票個股信息_第4張圖片

股票代碼

由于百度股市通個股的網址信息使用的是完整的股票代碼,深圳交易所的代碼以sz開頭,上海交易所的代碼以sh開頭,股票的數字有6位構成,因此我們要從a標簽的鏈接中獲取股票代碼,而不是直接獲取a標簽的文本數據。

#從獲取的內容中找到所有a標簽
cnt=soup.find_all('a')
import re
#儲存完整股票代碼
lst=[]
#for循環歷遍獲取的a標簽
for i in cnt:
try:
#獲取a標簽中的鏈接
href=i.attrs['href']
#正則表達式提取完整的股票代碼
lst.append(re.findall(r'[s][hz]\d{6}',href)[0])
#這里[0]的作用是把獲取到的列表轉化為字符串添加到列表中
except:
continue

對文件操作,把獲取的股票代碼列表寫入文檔中,打開的文件一定要關閉,否則會占用相當大的系統資源,python中的with語句可以幫我們自動調用close()而不需要我們寫出來,'w'以只寫的方式打開文件,如果文件存在的話會先刪除再重新創建
#寫入D盤d.txt文件

with open(r'D:d.txt','w') as file:

file.write(str(lst))

python爬蟲實戰——爬取股票個股信息_第5張圖片

二、獲取股票信息
首先查看股票信息的網頁源碼

個股信息

百度股票網的網址為:由于平臺文章限制請自行查找
個股信息的網址為:由于平臺文章限制請自行查找
想要獲取每只個股的網址只需要歷遍股票代碼列表,再與首頁網址拼接即可,代碼如下

stockUrl='https://gupiao.baidu.com/stock/'

接下來是通過網址獲取網頁html數據,解析獲取股票信息

#歷遍股票代碼列表構造個股網址
count=0
for stock in lst:
url=stockUrl+stock+'.html'
try:
#獲取個股網頁html代碼
page = request.Request(url, headers=headers)
page_info=request.urlopen(page).read()
page_info=page_info.decode('utf-8','ignore').replace(u'\xa9', u'')
#直接解碼這里會報錯,原因是?不能直接解碼,這里將?替換成空格
if page_info=='':
continue
#解析網頁內容
soup=BeautifulSoup(page_info,'html.parser')
#字典儲存股票信息
infoDict = {}
#查找包含個股信息的div標簽
stockInfo = soup.find('div',attrs={'class':'stock-bets'})
#查找股票名字存入字典
name = stockInfo.find_all(attrs={'class':'bets-name'})[0]
infoDict.update({'股票名稱': name.text.split()[0]})
#split()對字符串進行切片,去除后面的空格
#股票的其他信息存放在 dt dd 標簽中,查找標簽
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(r'D:f.txt', 'w') as f:
f.write( str(infoDict) + '\n' )
count = count + 1
#打印當前進度
print("\r當前進度: {:.2f}%".format(count 100/len(lst)),end="")
except:
count = count + 1
print("\r當前進度: {:.2f}%".format(count
100/len(lst)),end="")
continue

            
                                  由于股票信息太多,這里只爬取其中一百只股票的信息
            
          

爬取結果如下:

python爬蟲實戰——爬取股票個股信息

整個實現過程的完整代碼如下:

from urllib import request
from bs4 import BeautifulSoup
url = r'http://quote.eastmoney.com/stocklist.html'
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'}
page = request.Request(url, headers=headers)
page_info=request.urlopen(page).read()
page_info=page_info.decode('GB2312',errors='ignore')
soup=BeautifulSoup(page_info,'html.parser')
cnt=soup.find_all('a')
import re
lst=[]
for i in cnt:
try:
href=i.attrs['href']
lst.append(re.findall(r'[s][hz]\d{6}',href)[0])
except:
continue

stockUrl='https://gupiao.baidu.com/stock/'
count=0
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'}
for stock in lst[350:400]:
url=stockUrl+stock+'.html'
try:
page = request.Request(url, headers=headers)
page_info=request.urlopen(page).read()
page_info=page_info.decode('utf-8','ignore').replace(u'\xa9', u'')
if page_info=='':
continue
soup=BeautifulSoup(page_info,'html.parser')
infoDict = {}
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(r'D:f.txt', 'a') as f:
f.write( str(infoDict) + '\n' )
count = count + 1
print("\r當前進度: {:.2f}%".format(count 100/len(lst[:100])),end="")
except:
count = count + 1
print("\r當前進度: {:.2f}%".format(count
100/len(lst[:100])),end="")
continue