今天我們聊一聊動(dòng)態(tài)抓取,所謂的動(dòng)態(tài)抓取其實(shí)就是我們?cè)谧ト【W(wǎng)頁(yè)數(shù)據(jù)的時(shí)候,要抓取的數(shù)據(jù)在查看網(wǎng)頁(yè)源代碼時(shí)是找不到對(duì)應(yīng)的數(shù)據(jù)的,就比如我們今天要爬取的騰訊視頻的VIP電影

如上圖所示,網(wǎng)頁(yè)中有,但是在查看源代碼時(shí),源代碼中沒(méi)有;這事怎么回事呢,這其實(shí)就是因?yàn)樗臄?shù)據(jù)是動(dòng)態(tài)加載的,一般都是通過(guò)js代碼來(lái)向服務(wù)器實(shí)時(shí)獲取數(shù)據(jù)的,接下來(lái)我們就抓取一下這樣的網(wǎng)站。
既然要獲取數(shù)據(jù),那我們肯定要先找到請(qǐng)求數(shù)據(jù)的代碼在哪兒,打開(kāi)Chrome瀏覽器的開(kāi)發(fā)者工具,我們選中network選項(xiàng)

接著我們刷新一下我們要抓取的網(wǎng)頁(yè),可以看到下面多出來(lái)很多的東西,一般請(qǐng)求的代碼都是在XHR或者JS中的,所以我們直接在這兩項(xiàng)中去找,通過(guò)查找我們能看到如下結(jié)果:

看來(lái)就是這個(gè)文件請(qǐng)求的數(shù)據(jù)啦,接下來(lái)我們選擇Headers查看它的請(qǐng)求地址

我們把這個(gè)請(qǐng)求鏈接復(fù)制下來(lái),然后直接在瀏覽器中打開(kāi)呢

看來(lái)確實(shí)是我們要找的內(nèi)容,它的數(shù)據(jù)類(lèi)型是一個(gè)json類(lèi)型,所以我們只需要把數(shù)據(jù)抓取下來(lái),然后解析就能夠搞定啦!接下來(lái)開(kāi)始寫(xiě)代碼:
首先是抓取得到j(luò)son數(shù)據(jù):
# -*- coding:utf-8 -*-
import requests
url = 'http://list.video.qq.com/fcgi-bin/list_common_cgi?otype=json&novalue=1&platform=1&version=10000&intfname=web_vip_movie_new&tid=687&appkey=c8094537f5337021&appid=200010596&type=1&sourcetype=1&itype=-1&iyear=-1&iarea=-1&iawards=-1&sort=17&pagesize=30&offset=0&callback=jQuery19108734160972013745_1494380383266&_=1494380383271'
data = requests.get(url).content
print data

數(shù)據(jù)抓取下來(lái)后接下來(lái)就是解析數(shù)據(jù)了,由于是json類(lèi)型,所以我們導(dǎo)入json包來(lái)解析,首先利用正則表達(dá)式去除前面不相干的jQuery1910...那一串,只留下{"cgi_cost_time:...}的數(shù)據(jù),從我們剛剛復(fù)制請(qǐng)求鏈接打開(kāi)的網(wǎng)頁(yè)結(jié)果可以看出,所要的數(shù)據(jù)是在{...;'jsonvalue':{...;'results':[...];...};...},也就是在字典中的key為jsonvalue的里面的,jsonvalue的值又是一個(gè)字典,又在這個(gè)字典里的key值為results里面才是真正的數(shù)據(jù),而results對(duì)應(yīng)的value是一個(gè)列表,分析清楚了接下來(lái)獲取數(shù)據(jù)就簡(jiǎn)單了,直接上代碼:
# -*- coding:utf-8 -*-
import requests
import json
import re
url = 'http://list.video.qq.com/fcgi-bin/list_common_cgi?otype=json&novalue=1&platform=1&version=10000&intfname=web_vip_movie_new&tid=687&appkey=c8094537f5337021&appid=200010596&type=1&sourcetype=1&itype=-1&iyear=-1&iarea=-1&iawards=-1&sort=17&pagesize=30&offset=0&callback=jQuery19108734160972013745_1494380383266&_=1494380383271'
data = requests.get(url).content
# print data
#正則表達(dá)式去除不相干數(shù)據(jù)
data = re.search(re.compile(r'jQuery.+?\((.+)+\)'),data)
if data is not None:
a = json.loads(data.group(1))
data = a['jsonvalue']['results'] #找到results這個(gè)列表
#遍歷列表
for i in data:
#列表中的值為字典,所以用字典取對(duì)應(yīng)的值
print u'電影名稱(chēng): '+i['fields']['title']
print u'電影簡(jiǎn)介: '+i['fields']['second_title']
print u'電影封面: '+i['fields']['vertical_pic_url']
print u'電影評(píng)分: '+i['fields']['score']['score']
print u'電影ID: '+i['id']
print '\n'

這樣數(shù)據(jù)就得到了,當(dāng)然這只是抓取了一頁(yè)的內(nèi)容,如果要抓取所有頁(yè),我們可以通過(guò)多點(diǎn)擊幾次網(wǎng)頁(yè)的下一頁(yè),然后對(duì)比一下請(qǐng)求鏈接,你就能發(fā)現(xiàn)請(qǐng)求鏈接的規(guī)律

通過(guò)對(duì)比可以發(fā)現(xiàn),每增加一頁(yè),這個(gè)數(shù)字對(duì)應(yīng)的增加30,所以只需要?jiǎng)討B(tài)的改變請(qǐng)求鏈接,就能抓取所有的數(shù)據(jù)。