今天我們聊一聊動(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ù)類型是一個(gè)json類型随抠,所以我們只需要把數(shù)據(jù)抓取下來(lái)裁着,然后解析就能夠搞定啦!接下來(lái)開(kāi)始寫代碼:
首先是抓取得到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
類型二驰,所以我們導(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'電影名稱: '+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ù)寄症。