使用python爬蟲實(shí)現(xiàn)抓取動(dòng)態(tài)加載數(shù)據(jù)
確定網(wǎng)站類型
首先要明確豆瓣電影網(wǎng)站(movie.douban.com)的類型,即是動(dòng)態(tài)還是靜態(tài)。檢查方法:右鍵查看網(wǎng)頁源碼 —> 搜索“辛德勒的名單”關(guān)鍵字,如下圖所示:

圖1:分析網(wǎng)站類型
最終發(fā)現(xiàn)源碼頁中沒有出現(xiàn)想要抓取的數(shù)據(jù),只有一大堆的 JS 代碼,由此確定該網(wǎng)站為動(dòng)態(tài)網(wǎng)站。
影片詳情信息
接下來,使用快捷鍵 F12 打開控制臺(tái)進(jìn)行抓包,點(diǎn)擊NetWork選項(xiàng)卡 —>XHR選項(xiàng) —> Preview選項(xiàng)卡 —> 刷新當(dāng)前頁面抓取數(shù)據(jù)包,如下圖所示:

圖2:抓取動(dòng)態(tài)網(wǎng)站數(shù)據(jù)包
從圖 2 可知,我們想要抓取的數(shù)據(jù)取全部包含在當(dāng)前的數(shù)據(jù)包中。當(dāng)我們向下滾動(dòng)鼠標(biāo)滑輪時(shí),左側(cè)欄內(nèi)的數(shù)據(jù)包會(huì)實(shí)現(xiàn)自動(dòng)加載,這是使用 Ajax 異步加載技術(shù)實(shí)現(xiàn)的。
通過查看數(shù)據(jù) Headers 選項(xiàng)可以明確 url 地址、查詢參數(shù)等信息,如下所示:

圖3:分析Headers信息
從上圖可以得知請(qǐng)求的基準(zhǔn) URL (由于還未拼接查詢參數(shù),所以稱之為基準(zhǔn) URL),如下所示:
'https://movie.douban.com/j/chart/top_list?'
繼續(xù)滾動(dòng)鼠標(biāo)滑輪可知查詢參數(shù)具有如下規(guī)律:
type: 4 # 電影類型 interval_id: 100:90 #代表網(wǎng)頁上滑動(dòng)條的百分比(好于100%-90%的歷史片) action: '' # 空 start: 0 # 每次加載電影的起始索引值 0 20 40 60 limit: 20 # 每次加載的電影數(shù)量,1為初始值,后續(xù)加載時(shí)20固定不變
注意:尋找規(guī)律時(shí),后加載出來的數(shù)據(jù)包會(huì)排在最前面,除去第一個(gè)數(shù)據(jù)包外,其余數(shù)據(jù)包如下所示:

圖4:尋找查詢參數(shù)值的規(guī)律
影片總數(shù)量
注意:第一個(gè)數(shù)據(jù)包反映了每個(gè)類型中電影的總數(shù)量,其 url 與響應(yīng)信息如下:
請(qǐng)求的URL地址 : https://movie.douban.com/j/chart/top_list_count?type=4&interval_id=100%3A90
Response信息:{"playable_count":41,"total":104,"unwatched_count":104}
影片類型與類型碼
影片的類型與類型碼包含在電影排行榜的主界面中,如下所示:

圖5:影片類型與類型碼
分析上述頁面結(jié)構(gòu),然后使用正則表達(dá)式來提取想要的數(shù)據(jù),并定義選擇菜單“menu”,代碼如下所示:
import re
def get_all_type_films(self):
# 獲取影片類型和類型碼
url = 'https://movie.douban.com/chart'
headers = self.get_headers()
html = requests.get(url=url, headers=headers).text
re_bds = r'<a href=.*?type_name=(.*?)&type=(.*?)&.*?</a>'
pattern = re.compile(re_bds, re.S)
r_list = pattern.findall(html)
# 存放所有類型和對(duì)應(yīng)類型碼大字典
type_dict = {}
# 定義一個(gè)選擇電影類型的菜單
menu = ''
# r_list[{'劇情 , 11'},{},..]
for r in r_list:
type_dict[r[0].strip()] = r[1].strip()
# 獲取input的菜單,顯示所有電影類型
menu += r[0].strip() + '|'
#返回類型字典以供后續(xù)函數(shù)調(diào)用,并返回輸入菜單menu
# {'劇情': '11', '喜劇': '24',...}
return type_dict, menu
編寫完整程序
完成上述分析后,下面開始編寫 Python 爬蟲程序,代碼如下:
#coding:utf8
import requests
import time
import random
import re
import json
from ua_info import ua_list
class DoubanSpider(object):
def __init__(self):
self.url = 'https://movie.douban.com/j/chart/top_list?'
self.i = 0
# 獲取隨機(jī)headers
def get_headers(self):
headers = {'User-Agent':random.choice(ua_list)}
return headers
# 獲取頁面
def get_page(self,params):
# 將json轉(zhuǎn)換為 python 數(shù)據(jù)類型,并返回
html = requests.get(url=self.url,params=params,headers=self.get_headers()).text
html=json.loads(html)
self.parse_page(html)
# 解析并保存數(shù)據(jù)
def parse_page(self,html):
item = {}
# html列表類型: [{電影1},{電影2},{電影3}...]
for one in html:
# 名稱 + 評(píng)分
item['name'] = one['title'].strip()
item['score'] = float(one['score'].strip())
print(item)
self.i += 1
# 獲取電影總數(shù)
def total_number(self,type_number):
# F12抓包抓到的地址,type表示電影類型
url = 'https://movie.douban.com/j/chart/top_list_count?type={}&interval_id=100%3A90'.format(type_number)
headers = self.get_headers()
html = requests.get(url=url,headers=headers).json()
total = int(html['total'])
return total
# 獲取所有電影的類型和對(duì)應(yīng)type值
def get_all_type_films(self):
# 獲取類型與類型碼
url = 'https://movie.douban.com/chart'
headers = self.get_headers()
html = requests.get(url=url,headers=headers).text
re_bds = r'<a href=.*?type_name=(.*?)&type=(.*?)&.*?</a>'
pattern = re.compile(re_bds,re.S)
r_list = pattern.findall(html)
# 存放所有類型和對(duì)應(yīng)類型碼大字典
type_dict = {}
#定義一個(gè)選擇電影類型的菜單
menu = ''
for r in r_list:
type_dict[r[0].strip()] = r[1].strip()
# 獲取input的菜單,顯示所有電影類型
menu += r[0].strip() + '|'
return type_dict,menu
# 主程序入口函數(shù)
def main(self):
# 獲取type的值
type_dict,menu = self.get_all_type_films()
menu = menu + '\n你想了解什么類型電影:'
name = input(menu)
type_number = type_dict[name]
# 獲取電影總數(shù)
total = self.total_number(type_number)
for start in range(0,(total+1),20):
#構(gòu)建查詢參數(shù)
params = {
'type' : type_number,
'interval_id' : '100:90',
'action' : '',
'start' : str(start),
'limit' : '20'
}
# 調(diào)用函數(shù),傳遞params參數(shù)
self.get_page(params)
# 隨機(jī)休眠1-3秒
time.sleep(random.randint(1,3))
print('電影總數(shù)量:%d部'%self.i )
if __name__ == '__main__':
spider = DoubanSpider()
spider.main()
最后
以上就是使用python爬蟲實(shí)現(xiàn)抓取動(dòng)態(tài)加載數(shù)據(jù)的詳細(xì)內(nèi)容,更多關(guān)于python抓取動(dòng)態(tài)加載數(shù)據(jù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python的pdb調(diào)試命令的命令整理及實(shí)例
這篇文章主要介紹了python的pdb調(diào)試命令的命令整理及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-07-07
python對(duì)配置文件.ini進(jìn)行增刪改查操作的方法示例
.ini配置文件常被用作存儲(chǔ)程序中的一些參數(shù),通過它程序可以變得更加靈活。下面這篇文章主要給大家介紹了關(guān)于python對(duì)配置文件.ini進(jìn)行增刪改查操作的方法示例,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。2017-07-07
python生成并處理uuid的實(shí)現(xiàn)方式
這篇文章主要介紹了python生成并處理uuid的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03
python Tkinter版學(xué)生管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python Tkinter版學(xué)生管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02
使用Python實(shí)現(xiàn)操作控制鼠標(biāo)和鍵盤
Python 有很多的庫可以實(shí)現(xiàn)各種各樣的功能,比如使用 pynput 操作,下面小編就來和大家詳細(xì)介紹一下如何使用pynput進(jìn)行操作控制鼠標(biāo)和鍵盤吧2024-02-02

