網(wǎng)絡(luò)爬蟲(Web Spider),根據(jù)網(wǎng)頁(yè)地址爬取網(wǎng)頁(yè)內(nèi)容,從而獲取各類數(shù)據(jù),實(shí)現(xiàn)多種多樣的功能。下面就以爬取東方財(cái)富網(wǎng)的數(shù)據(jù)為例,談?wù)勛詈?jiǎn)單的爬蟲的實(shí)現(xiàn)。爬蟲的核心有三個(gè):請(qǐng)求、解析、存儲(chǔ)。
環(huán)境配置
Python安裝使用Anaconda包,包里已經(jīng)包含了必須的requests模塊
請(qǐng)求html頁(yè)面
import requests
url = 'http://www.eastmoney.com/'
req = requests.get(url)
html = req.content
這樣我們就把html網(wǎng)頁(yè)的源代碼下下來了,我們執(zhí)行
print(html)
就能把網(wǎng)頁(yè)顯示出來
此時(shí),我們發(fā)現(xiàn)網(wǎng)頁(yè)有亂碼現(xiàn)象,這是編碼的問題,這時(shí)我們指定網(wǎng)頁(yè)的編碼
req.encoding = req.apparent_encoding
就會(huì)發(fā)現(xiàn)網(wǎng)頁(yè)顯示恢復(fù)正常了
當(dāng)然,如果我們沒有顯示的需要,完全沒必要指定網(wǎng)頁(yè)的編碼。
解析
獲取網(wǎng)頁(yè)源碼后,我們可以對(duì)網(wǎng)頁(yè)的源碼進(jìn)行解析,提取我們想要的信息。使用得較多的是BeautifulSoup模塊。我們以提取東方財(cái)富網(wǎng)首頁(yè)的消息為例,右鍵點(diǎn)擊對(duì)應(yīng)的元素,選擇檢查,然后我們就可以看到網(wǎng)頁(yè)的源代碼了。
我們發(fā)現(xiàn)對(duì)應(yīng)的元素都被<div class="nlist">選定,相應(yīng)的我們可以把相應(yīng)的代碼篩選出來。
from bs4 import BeautifulSoup
bf = BeautifulSoup(html, 'lxml')
nmlist = bf.find_all(class_ = 'nlist')
發(fā)現(xiàn)得到的是一個(gè)list文件,每個(gè)list包含若干條消息
我們發(fā)現(xiàn)消息的標(biāo)題和鏈接被<a>給限定出來,于是我們同樣可以用find_all方法獲取,以list[0]的消息提取為例,而鏈接用get方法得到。
a = nlist.find_all('a')
for each in a:
print(each.string, each.get('href'))
我們看看得到了什么結(jié)果
可以看到標(biāo)題和鏈接成功提取出來了。
存儲(chǔ)
一般采用csv文件進(jìn)行存儲(chǔ),可以使用excel等軟件打開
date = open('test.csv','w')
writer = csv.writer(date)
date.close()
這樣就保存到csv文件了。
全部的代碼如下所示
import requests
from bs4 import BeautifulSoup
import csv
date = open('test.csv','w')
writer = csv.writer(date)
url = 'http://www.eastmoney.com/'
req = requests.get(url)
# req.encoding = req.apparent_encoding
html = req.text
bf = BeautifulSoup(html, 'lxml')
nlist = bf.find_all(class_ = 'nlist')[0]
a = nlist.find_all('a')
for each in a:
a_list = []
a_list.append(each.string)
a_list.append(each.get('href'))
writer.writerow(a_list)
date.close()
這樣短短的幾行程序,就完成了一個(gè)爬蟲,但是以上程序只能爬取靜態(tài)網(wǎng)頁(yè),對(duì)于javascript動(dòng)態(tài)網(wǎng)頁(yè)就無能為力。
JS爬蟲
解析JS網(wǎng)頁(yè)一般有兩種方法,一種是在網(wǎng)頁(yè)源碼中找到JS腳本數(shù)據(jù),爬取到本地解析,另一種是使用Selenium模擬瀏覽器登錄獲取。這里介紹第一種,第二種以后有時(shí)間再介紹。
獲取JS腳本
以chrome瀏覽器為例,目標(biāo)網(wǎng)頁(yè)選擇 http://quote.eastmoney.com/web/BK04751.html,以獲取銀行板塊的今日開盤數(shù)據(jù)為例,當(dāng)我們使用檢查查看網(wǎng)頁(yè)源碼時(shí)會(huì)發(fā)現(xiàn)數(shù)據(jù)是空白,如下所示:
這是由于數(shù)據(jù)被js動(dòng)態(tài)腳本加載,直接采取上面的方法無法獲取數(shù)據(jù)。我們首先要看看js腳本地址。
我們首先右鍵頁(yè)面點(diǎn)擊檢查,標(biāo)簽切到Network,按ctrl + R重新加載
我們會(huì)發(fā)現(xiàn)出現(xiàn)了很多JS腳本。接下來按ctrl + F搜索當(dāng)日開盤點(diǎn)位'3147.83',我們依次點(diǎn)擊每個(gè)搜索結(jié)果,找到符合包含開盤/最高等數(shù)據(jù)的腳本,在Response標(biāo)簽下
然后切換到Headers標(biāo)簽,獲取Request URL
于是我們得到了JS腳本的地址
http://nufm.dfcfw.com/EM_Finance2014NumericApplication/JS.aspx?type=CT&cmd=BK04751&sty=FDPBPFB&st=z&sr=&p=&ps=&cb=jQuery172040627517238278443_1551425982764&js=([[(x)]])&token=7bc05d0d4c3c22ef9fca8c2a912d779c&_=1551425982799
類似的,我們可以獲得結(jié)果
import requests
url = 'http://nufm.dfcfw.com/EM_Finance2014NumericApplication/JS.aspx?type=CT&cmd=BK04751&sty=FDPBPFB&st=z&sr=&p=&ps=&cb=jQuery172040627517238278443_1551425982764&js=([[(x)]])&token=7bc05d0d4c3c22ef9fca8c2a912d779c&_=1551425982799'
wbdata = requests.get(url).text
我們來看看print的結(jié)果
可以看到是字符串類型的數(shù)據(jù),并且在數(shù)據(jù)中出現(xiàn)了3147.83,也就是我們的目標(biāo)數(shù)據(jù)——開盤點(diǎn)位。為了獲取這個(gè)數(shù)據(jù),我們可以用split()函數(shù),如下所示
data_n = wbdata.split(',')
open_n = data_n[7]
于是我們就得到了開盤點(diǎn)位3147.83。