Python爬蟲實戰系列文章目錄
Python爬蟲實戰:東方财富網股吧資料爬取(一)
Python爬蟲實戰:東方财富網股吧資料爬取(二)
Python爬蟲實戰:東方财富網股吧資料爬取(三)
Python爬蟲實戰:東方财富網股吧資料爬取(四)
目錄
- Python爬蟲實戰系列文章目錄
- 前言
- 一、項目說明
- 二、問題重述
- 二、實施過程
-
- 1.二次爬取獲得年份資料
-
- Ⅰ 檢視原始頁面網頁結構
- Ⅱ 檢視跳轉頁面網頁結構
- Ⅲ 二次爬取思路如下:
- 2.完整爬取标題内容,避坑!
- 總結
- 寫在最後
前言
昨天有一位朋友私信我如何爬取股吧的年份資料,這才想起來很長時間沒有更新這個系列了,十分抱歉。目前項目已經基本結束,已經成功爬取到東方财富網中共
2785個
股吧的熱帖資料。由于目前仍在研究階段,資料和代碼暫時不會公布,之後會上傳到Github上,有需要的朋友先可以關注一下~
我的GitHub位址:LeoWang91
一、項目說明
項目需求:股吧中人們的言論行為和股市漲跌的延遲相關性
資料來源:東方财富網、熱門個股吧
資料字段:閱讀、評論、标題、作者、更新時間
實作功能:讀取每個公司股吧的全部頁面的資料并寫入excel表中
二、問題重述
Python爬蟲實戰:東方财富網股吧資料爬取(一)
在上篇部落格中,我們已經可以初步爬取到東方财富吧中全部發帖資訊的閱讀、評論、标題、作者及最後更新時間這五個字段的資料,但是由于該網站本身結構的原因,導緻我在爬取的過程中踩坑無數,簡單歸納為以下幾點:
-
股吧中全部發帖資訊較多,很容易在爬取過程中被屏蔽IP導緻爬取失敗,如果你在爬取過程中發現,任意打開一個股吧的網址,出來的都是股市實戰吧、财經評論吧,那麼很不幸,你的IP也被屏蔽了!解決辦法就是使用IP代理池,感謝下面這位大神的分享。時間問題,關于IP代理池的詳細使用我們留到下篇部落格再說,請大家見諒。
Python爬蟲代理IP池(proxy pool))
- 簡單看過我第一篇部落格的朋友應該都知道,在股吧的頁面中,最後更新時間這一個字段沒有出現年份資料,沒有年份資料做研究也就失去了意義,今天就和大家分享一下如何進行二次爬取。
- 在我爬取過程中,部分标題的網頁結構很奇怪,導緻我們利用比對規則不能擷取到标題資訊,今天和大家分享一下我的解決辦法。
二、實施過程
以東方财富吧全部股吧的熱帖資料為例
1.二次爬取獲得年份資料
Ⅰ 檢視原始頁面網頁結構
在股吧的熱帖頁面中,我們可以看到最後更新這一字段并沒有年份資訊,點選檢視網頁結構:
我們可以看到,該标題标簽為:
Ⅱ 檢視跳轉頁面網頁結構
點選網頁中這條貼吧,檢視網址連結及字段内容:
連結:https://guba.eastmoney.com/news,000980,1012733179.html
Ⅲ 二次爬取思路如下:
我們在一次爬取标題時,可以先擷取标題
title
及所帶的連結
whole_url
:
注意:由于
<a><a/>
标簽中的連結是不完整的,是以需要拼接兩個網址
# 需要使用的庫
from bs4 import BeautifulSoup
from urllib import parse
# 字段聲明
title = [] # 存放目前頁面所有标題資訊
post_urls = [] # 存放目前頁面所有跳轉頁面的完整連結資訊
## 部分代碼,不可直接複制
# html是經過解析後的網頁内容
# url是目前某一股吧熱帖的頁面連結
soup = BeautifulSoup(html, "html.parser")
for each in soup.find_all('span', 'l3 a3'):
first = each.select('a:nth-of-type(1)')# 選擇器
for i in first:
title.append(i.title)
news_comment_urls = i.get('href')
# print(news_comment_urls)
# 用 urllib 的 urljoin() 拼接兩個網址
# 第一個參數是基礎母站的url,第二個是需要拼接成絕對路徑的url
whole_url = parse.urljoin(url, news_comment_urls)
# print(whole_url)
post_urls.append(whole_url)
現在
whole_url
中已經擷取到該帖的網址連結,則隻需解析該網頁結構,捕捉到含有年份的資料字段,重新寫入
time清單
中即可:
注意:由于我們隻需要時間資訊,是以需要對
div
中的字段做個提取
# 擷取網頁内容
def getHTMLText(url):
try:
r = requests.get(url, timeout=(3,7))
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
print("擷取" + str(url) + "網頁内容失敗!")
# 擷取年份時間的完整代碼
def getTime(html):
time = ''
try:
soup = BeautifulSoup(html, "html.parser")
time = soup.find('div', 'zwfbtime')# 從網頁結構得出
if time is None:
time = ''
else:
# 發表于 2021-03-14 08:09:22 東方财富Android版
# ["發表于","2021-03-14","08:09:22","東方财富Android版"]
# 提取時間資訊
time = ' '.join(time.string.split(' ')[1:3])
except:
print("未擷取到動态時間")
return time
## 部分代碼,不可直接複制
time = [] # 存放目前頁面所有時間資訊
# 先擷取到原始頁面的時間資訊
for each in soup.find_all('span', 'l5 a5'):
time.append(each.string)
time = time[1:] # 除去頁面開始含有的“最後更新”字元串
# 二次爬取含有年份的時間資訊
for t in range(len(time)):
text = getHTMLText(post_urls[t])
gettime = getTime(text)
# print(time)
time[t] = gettime
這時候我們的最後更新時間字段就全部變成有年份資訊的啦!
2.完整爬取标題内容,避坑!
在爬取标題内容的過程中,中間出現很多錯誤,但是由于忘記列印日志了,一時半會找不到具體例子,是以直接把自己的解決辦法拿出來分享啦,主要改變的是上面說的标題
title
及所帶的連結
whole_url
的代碼部分。
# 部分代碼,不可直接複制
for each in soup.find_all('span', 'l3 a3'):
first = each.select('a:nth-of-type(1)')
if not first:
title.append('None')
post_urls.append('None')
continue
count = 0
for i in first:
count = count + 1
for i in first:
i.find_all("a")
if i.get('href')[:5] == '//ask':
continue
if i.title== '問董秘' and i.get('href')[:5] != '/news':
continue
if count >= 2:
if i.get('href')[:5] != '/news':
continue
title.append(i.title)
news_comment_urls = i.get('href')
# print(news_comment_urls)
# 用 urllib 的 urljoin() 拼接兩個網址
# 第一個參數是基礎母站的url,第二個是需要拼接成絕對路徑的url
whole_url = parse.urljoin(url, news_comment_urls)
# print(whole_url)
post_urls.append(whole_url)
總結
說到這裡,爬取東方财富網股吧資料的細節部分說的差不多了,如果我想到新的内容再和大家分享,關于IP代理池的詳細使用說明,就在下一章節中再和大家分享啦,下期再見啦!
寫在最後
【學習交流】
WX:WL1498544910
【文末小宣傳】
----部落客自己開發的小程式,希望大家的點贊支援一下,謝謝!-----