Python爬蟲實戰系列文章目錄
Python爬蟲實戰:東方財富網股吧資料爬取(一)
Python爬蟲實戰:東方財富網股吧資料爬取(二)
Python爬蟲實戰:東方財富網股吧資料爬取(三)
Python爬蟲實戰:東方財富網股吧資料爬取(四)
目錄
- Python爬蟲實戰系列文章目錄
- 前言
- 一、專案說明
- 二、實施程序
- 1.明確獲取網頁中哪些資料
- 2.查看網頁源代碼分析結構
- ① 網頁源代碼
- ② 網頁鏈接
- 3.爬蟲需要具備的功能
- 4.爬取結果
- 總結
前言
朋友托我寫個爬蟲,本身是個爬蟲小白的我還是接受了此次重任,總共歷時五天左右,程序中遇到過無數bug,好在一路披荊斬棘,還是大差不差的完成了此次委托!但感覺這次的經歷還是有必要和大家分享一下,正好最近也沒有寫博文了,趁這次機會趕趕進度!
【宣告】本人就是爬蟲小白,后續講解的代碼較為基礎,請大家不要嘲笑!謝謝配合!真心感謝!
一、專案說明
專案需求:股吧中人們的言論行為和股市漲跌的延遲相關性
資料來源:東方財富網、熱門個股吧
資料欄位:閱讀、評論、標題、作者、更新時間
實作功能:讀取每個公司股吧的全部頁面的資料并寫入excel表中
二、實施程序
以東方財富吧為例
1.明確獲取網頁中哪些資料

我們需要爬取的是東方財富吧中全部發帖資訊的閱讀、評論、標題、作者及最后更新時間這五個欄位的資料,我一開始想也不是很難,決議一下網頁匹配一下對應的標簽值就可以了,但后面還是出現了各種各樣的問題,需要大家注意一下,
2.查看網頁源代碼分析結構
① 網頁源代碼
首先打開網頁的開發者工具(Ctrl+Shift+i),在源代碼中查找對應欄位的標簽結構,

從圖中可以看出,這五個欄位分別位于<span></span>行標簽內,對應的屬性分別是"l1 a1"、"l2 a2"、"l3 a3"、"l4 a4"、"l5 a5",想必大家已經有思路了,我們可以通過先獲取網頁代碼,再決議網頁查詢對應的五個欄位,最后做一個提取就可以了,

② 網頁鏈接
【東方財富吧:300059】
首頁:https://guba.eastmoney.com/list,300059.html
第二頁:https://guba.eastmoney.com/list,300059_2.html
可以看出個股吧鏈接主要由三部分組成:list、名稱代碼、頁數
I.全部個股吧的數字代碼

II. 翻頁資料

如何得到不同股吧的所有翻頁資料,著實讓我找了好久,各種資源我都找了可惜還是沒有發現,突然無意之中我找到了解決辦法,我直接一個好家伙!
跟上述的五類欄位一樣,我們查看一下頁數的代碼欄位,如下圖所示:

我的第一個辦法是直接決議網頁后找到<span></span>標簽下的sumpage屬性,其內容即為總頁數,本來以為原來這么好獲取,結果決議完才發現,pagernums里的內容是動態的,即span.on是會隨頁而變化的,故直接requests并不能獲取到,但是還是被我發現了玄機!

大家可以看data-pager這里,里面的內容是list,300059_|452885|80|2,我對比了幾個頁面后發現其中數字分別代表的是:
300059:股吧數字代碼
452885:該股吧共發帖452885條
80:每個頁面分別有80條貼子
2:當前所處頁面為第2頁
那么這時候,我們就可以直接用累積多年的算力(小學除法)算出東方財富吧共有452885/80=5661.0625,向上取整共5662頁!如果你也脫口而出好家伙的話,請在螢屏下方打出來!

3.爬蟲需要具備的功能
基本問題解決了,我們可以開始撰寫爬蟲了,這部分不講代碼原理,只解釋代碼功能,自己也是小白,如果代碼存在問題或不清楚的話,歡迎大家在下方留言,我一定及時回復,
① 獲取網頁源代碼
def getHTMLText(url):
try:
r = requests.get(url, timeout=30)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
print("獲取網頁內容失敗!")
② 決議網頁并提取資料欄位
def parsePage(html):
list = [] # 我用的二維陣列存盤
read = []
comment = []
title = []
author = []
time = []
try:
# print(html)
soup = BeautifulSoup(html, "html.parser")
for each in soup.find_all('span', 'l1 a1'):
if '萬' in each.string:
each.string = each.string[:-2]
read.append(each.string)
read = read[1:] # read[0] == '閱讀'
list.append(read)
for each in soup.find_all('span', 'l2 a2'):
comment.append(each.string)
comment = comment[1:] # comment[0] == '評論'
list.append(comment)
for each in soup.find_all('span', 'l3 a3'):
first = each.select('a:nth-of-type(1)')
for i in first:
i.find_all("a")
# print(i.string)
title.append(i.string)
list.append(title)
for each in soup.find_all('span', 'l4 a4'):
first = each.select('font:nth-of-type(1)')
for i in first:
i.find_all("font")
# print(i.string)
author.append(i.string)
list.append(author)
for each in soup.find_all('span', 'l5 a5'):
time.append(each.string)
time = time[1:] # time[0] == '最后更新'
list.append(time)
except:
print("決議網頁欄位失敗!")
return list
③ 獲取貼吧總頁數
基于決議的網頁直接find_all也是可以的def get_total_pages_num(url):
try:
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('lang=zh_CN.UTF-8')
chrome_options.add_argument(
'User-Agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36"')
chrome_options.add_argument('--disable-extensions')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--no-sandbox')
driver = webdriver.Chrome(options=chrome_options)
driver.get(url)
page_data = driver.find_element_by_xpath(
'//div[@id="mainbody"]/div[@id="articlelistnew"]/div[@class="pager"]/span[@class="pagernums"]').get_attribute(
'data-pager')
# print(page_data)
if page_data:
# page_nums = re.findall('\|(\d+)', page_data[0])
page_nums = page_data.split("|")
# print(page_nums)
total_pages = math.ceil(int(page_nums[1]) / int(page_nums[2]))
driver.quit()
except Exception as e:
total_pages = 1
return int(total_pages)
4.爬取結果
上述代碼基本的欄位已經可以實作爬取了,結果如下:

可以看到,我這里的時間多了年份,這是由于朋友研究的需要,在基于一次爬取的結果上,進行二次爬取標題所帶的鏈接網頁獲得的,有關二次爬取的內容,我們再下一節再和大家分享,

總結
在爬取程序中,我還遇到了很多問題諸如:
① 部分帖子結構不同或存在冗余該如何處理(問董秘等鏈接)
② 爬取程序中ip被屏蔽自動跳轉頁面該如何處理(代理IP池)
… …
這些內容在后續章節中再和大家分享,下期再見啦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/255220.html
標籤:python
下一篇:windows pip安裝模塊出現Could not fetch URL https://mirrors.aliyun.com/pypi/simple/pip/
