国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁 > 營銷資訊 > 網(wǎng)站運營 > Python如何爬動態(tài)網(wǎng)頁,詳細(xì)教程,小菜鳥一個?

Python如何爬動態(tài)網(wǎng)頁,詳細(xì)教程,小菜鳥一個?

時間:2024-02-10 16:45:01 | 來源:網(wǎng)站運營

時間:2024-02-10 16:45:01 來源:網(wǎng)站運營

Python如何爬動態(tài)網(wǎng)頁,詳細(xì)教程,小菜鳥一個?:
在之前的推文中,我們介紹了如何爬取一個簡單的靜態(tài)網(wǎng)站——「Python 爬取靜態(tài)網(wǎng)站:以歷史天氣為例」,但是在實際過程中,常常會遇到需要爬取動態(tài)網(wǎng)站數(shù)據(jù)的情況。在本文中,我們也將通過一個比較簡單的案例,來介紹爬取動態(tài)網(wǎng)站數(shù)據(jù)的基本思路和步驟。

1. 動態(tài)網(wǎng)頁特征

首先,簡單回顧一下動態(tài)網(wǎng)頁的特征:

從源代碼看,動態(tài)網(wǎng)頁的數(shù)據(jù)不會出現(xiàn)在網(wǎng)頁源代碼中,而是被 “藏” 起來了; 從網(wǎng)址特征看,請求新數(shù)據(jù)時 (如翻頁),網(wǎng)址不會變化。

2. 動態(tài)網(wǎng)頁爬取的基本思路

動態(tài)網(wǎng)頁數(shù)據(jù)爬取通常有兩種方法:

分析數(shù)據(jù)接口,找到數(shù)據(jù)藏在哪,然后請求接口的數(shù)據(jù); 通過 Selenium 模擬瀏覽器點擊的方式獲取數(shù)據(jù)。 在本次介紹中,我們將通過獲取接口的方式來爬取動態(tài)網(wǎng)頁的數(shù)據(jù)。由于動態(tài)網(wǎng)頁結(jié)構(gòu)會更加復(fù)雜一些,我們主要的精力是在解析網(wǎng)頁結(jié)構(gòu)這一步。但是在找到了數(shù)據(jù)接口后 (知道數(shù)據(jù) “藏” 在哪),數(shù)據(jù)的爬取也比較簡單。具體來看,爬取動態(tài)網(wǎng)頁數(shù)據(jù)主要可分為以下幾步:

分析網(wǎng)頁結(jié)構(gòu),查找數(shù)據(jù)接口; 構(gòu)造請求頭,請求接口數(shù)據(jù); 解析接口數(shù)據(jù); 儲存數(shù)據(jù)。 同樣的,如果涉及多頁的數(shù)據(jù),需要分析接口的變化規(guī)律:

分析單頁網(wǎng)頁結(jié)構(gòu),查找數(shù)據(jù)接口; 分析接口變化規(guī)律,構(gòu)造接口參數(shù); 循環(huán)請求、獲取并解析數(shù)據(jù); 儲存數(shù)據(jù)。

3. 實戰(zhàn)案例

接下來,我們以爬取 bilibili 視頻評論為例,來具體介紹如何通過 Python 爬取動態(tài)網(wǎng)頁的數(shù)據(jù)。主要內(nèi)容包括:

如何分析動態(tài)網(wǎng)頁結(jié)構(gòu)、查找數(shù)據(jù)接口; 如何請求接口數(shù)據(jù); 如何解析 json 格式數(shù)據(jù); 如何把數(shù)據(jù)實時存入 csv 文件; 如何循環(huán)爬取多頁數(shù)據(jù)。

3.1 分析網(wǎng)頁結(jié)構(gòu)

在動態(tài)網(wǎng)頁的數(shù)據(jù)爬取中,分析網(wǎng)頁結(jié)構(gòu)至關(guān)重要。因為我們需要找到數(shù)據(jù) “藏” 在哪,否則不知道應(yīng)該去哪請求數(shù)據(jù)。在本案例中,我們將爬取「bilibili」的數(shù)據(jù),具體選擇 bilibili 入站第一名的視頻「【才淺】15 天花 20 萬元用 500 克黃金敲數(shù)萬錘純手工打造三星堆黃金面具」的評論數(shù)據(jù)。

按照慣例,我們先看一下網(wǎng)頁源代碼,由于信息太多了,可以直接使用搜索功能。在網(wǎng)頁源代碼頁面,搜索評論內(nèi)容,發(fā)現(xiàn)沒有這個數(shù)據(jù)。

那怎么辦呢?我們就要找一找這個數(shù)據(jù)到底藏在哪了。通常,查找動態(tài)網(wǎng)頁的數(shù)據(jù)接口有以下幾個步驟:

在頁面右鍵鼠標(biāo)選擇 檢查; 在檢查頁面選擇 Network; 在 Network 頁面選擇類型,數(shù)據(jù)接口一般藏在 Fetch/XHR 或者 JS 中; 找到數(shù)據(jù)接口。




問題又來了,動態(tài)網(wǎng)頁里的數(shù)據(jù)很多,有時候就算篩選了類型,也還是有很多頁面。要找到我們需要的數(shù)據(jù),真的是大海撈針,那怎么辦呢?有一個小技巧,就是利用搜索功能。在檢查頁面,搜索一下評論內(nèi)容,立馬就找到了數(shù)據(jù)藏在哪里!

3.2 請求接口數(shù)據(jù)

歷經(jīng)千辛萬苦,終于找到了數(shù)據(jù)藏的位置,接下來就是要把數(shù)據(jù)獲取下來。這里簡單三個步驟就可以完成:

查找接口的網(wǎng)址:分析接口網(wǎng)址的情況; 確定請求頭數(shù)據(jù):通常請求動態(tài)網(wǎng)頁數(shù)據(jù)需要比較完整的請求頭,這時可以直接把 Request Headers 里面的內(nèi)容直接復(fù)制; 請求數(shù)據(jù):在有了數(shù)據(jù)接口的位置后,先嘗試是否能夠成功獲取數(shù)據(jù),可以直接通過 requests 請求數(shù)據(jù)。

我們先來看看接口網(wǎng)址 (Request URL) 的情況,可以看到網(wǎng)址包括以下幾個部分:

主要結(jié)構(gòu):https://api.bilibili.com/x/v2/reply/main; 網(wǎng)址參數(shù):callback、jsonp、next、type、oid、mode、plat、_。 也就是說,這個數(shù)據(jù)接口由 1 個主結(jié)構(gòu)和 8 個參數(shù)構(gòu)成。關(guān)于參數(shù)需要注意兩點,一是有沒有這個參數(shù)會不會影響數(shù)據(jù)獲取,二是這個參數(shù)的含義和變化規(guī)律。具體的確定方法只有不斷嘗試:

通過增刪參數(shù)看是否會影響請求的結(jié)果,或者請求結(jié)果有何變化; 通過變化網(wǎng)頁看接口地址的變化規(guī)律,比如翻頁、評論排序等,看參數(shù)如何變化。 當(dāng)然,有時候不知道含義也可以爬取數(shù)據(jù),但是建議還是了解一下,一般不清楚含義但必需的參數(shù)保持默認(rèn)值即可。在這里,我們省略一下不斷嘗試的結(jié)果。最終,發(fā)現(xiàn)了部分參數(shù)的基本含義:

callback:代表一個獲取數(shù)據(jù)的查詢動作和時間戳,不是必需; jsonp:代表獲取的數(shù)據(jù)格式,不是必需; next:代表頁碼,翻頁循環(huán)時需要; type:含義暫時不明,但是必需,且不變,值為 1; oid:代表視頻的 av 號,如果需要爬取多個視頻的評論,需要從這個參數(shù)入手; mode:代表評論的排序方式,2 = 按時間倒序,3 = 按熱度排序 (默認(rèn)排序)。不是必需,默認(rèn)值為 3; plat:含義暫時不明,不是必需; _:代表當(dāng)前的 Unix 時間戳,不是必需。 接下來我們就可以復(fù)制請求頭,構(gòu)造請求參數(shù),請求需要的數(shù)據(jù)。

# 導(dǎo)入模塊import requestsimport time# 網(wǎng)址url = "https://api.bilibili.com/x/v2/reply/main" # 接口網(wǎng)址的主要結(jié)構(gòu)# 請求頭數(shù)據(jù)headers = { 'accept': '*/*', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8', 'referer': 'https://www.bilibili.com/video/BV16X4y1g7wT', 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': 'Windows', 'sec-fetch-dest': 'script', 'sec-fetch-mode': 'no-cors', 'sec-fetch-site': 'same-site', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' '(KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36' # 根據(jù)測試不需要 cookie 信息也可以獲取數(shù)據(jù) # 需要 cookie 的話在自己的瀏覽器中復(fù)制,這里涉及隱私就不放 cookie 信息了}# 構(gòu)造請求參數(shù)params = { # 'callback': 'jQuery17201888299578386794_' + str(round(time.time() * 1000)), # 'jsonp': 'jsonp', 'next': 0, # 頁碼 'type': 1, 'oid': 715024588, # 視頻av號 # 'mode': 3, # 評論排序方式 # 'plat': 1, # '_': str(round(time.time() * 1000)) # 生成當(dāng)前時間戳}# 通過get方法請求數(shù)據(jù)response = requests.get(url, headers=headers, params=params)查看返回結(jié)果,<Response [200]> 代表請求數(shù)據(jù)成功。如果是 403 或 404 則說明請求不成功,可能需要檢查電腦網(wǎng)絡(luò)是否通暢、目標(biāo)網(wǎng)址是否可以正常訪問、headers 是否有正確設(shè)置等。

3.3 解析網(wǎng)頁數(shù)據(jù)

請求成功后,我們再來看請求回來的數(shù)據(jù)是什么樣的,如何根據(jù)獲取自己需要的數(shù)據(jù)。回到數(shù)據(jù)接口中,我們可以看到數(shù)據(jù)是通過 json 格式存儲的,而每條評論的數(shù)據(jù)在 data 下面的replies中。

因此,我們用 json 解析請求到的數(shù)據(jù),并把需要的評論數(shù)據(jù)提取出來。

# 導(dǎo)入模塊import jsonimport timeresponse.encoding = 'utf-8' # 修改編碼格式data_json = json.loads(response.text) # 通過 json 解析數(shù)據(jù)comment_list = data_json['data']['replies'] # 獲取 data 下面的 replies 列表comments = [] # 構(gòu)建空列表保存每頁的評論數(shù)據(jù)for i in range(len(comment_list)): # 循環(huán)獲取每條評論的數(shù)據(jù) comment = { 'id': comment_list[i]['rpid'], # 評論id # 評論時間,由時間戳轉(zhuǎn)換 'time': time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(comment_list[i]['ctime'])), 'parent': comment_list[i]['parent'], # 父評論id 'like': comment_list[i]['like'], # 點贊數(shù) 'user_id': comment_list[i]['member']['mid'], # 評論用戶id 'user_name': comment_list[i]['member']['uname'], # 用戶名 'content': comment_list[i]['content']['message'] # 評論內(nèi)容 # 需要其他數(shù)據(jù)的可以再在 json 中查看并獲取對應(yīng)的名稱 } comments.append(comment) # 每頁的評論數(shù)據(jù)

3.4 儲存爬取數(shù)據(jù)

接下來,把爬取到的數(shù)據(jù)存入 csv 文件。當(dāng)然,還是建議爬取一頁保存一頁。同時,使用 utf-8 格式保存數(shù)據(jù),因此打開數(shù)據(jù)文件時,也要使用同樣的格式。

# 導(dǎo)入模塊import csv# 保存數(shù)據(jù)的文件路徑save_path = 'bilibili.csv'# 將數(shù)據(jù)寫入 csv with open(save_path, 'a', newline='', encoding='utf-8') as fp: csv_header = ['id', 'time', 'parent', 'like', 'user_id', 'user_name', 'content'] # 設(shè)置表頭,即列名 csv_writer = csv.DictWriter(fp, csv_header) # 如果文件不存在,則寫入表頭;如果文件已經(jīng)存在,則直接追加數(shù)據(jù)不再次寫入表頭 if fp.tell() == 0: csv_writer.writeheader() csv_writer.writerows(comments) # 寫入數(shù)據(jù)

3.5 循環(huán)爬取數(shù)據(jù)

終于成功獲取了一頁的數(shù)據(jù),接下來就要循環(huán)獲取更多數(shù)據(jù)了。這里也分為三個步驟:

分析接口網(wǎng)址的變化規(guī)律 (通常是參數(shù)的變化); 根據(jù)規(guī)律構(gòu)造網(wǎng)址; 循環(huán)獲取數(shù)據(jù)。 由于前面已經(jīng)詳細(xì)分析過接口的參數(shù)變化,這里不再具體說明。通過分析,翻頁變化的參數(shù)是 next,所以只要變化這個參數(shù)就可以進行翻頁。另外,如果要爬取不同視頻的評論,則要通過 av 號來循環(huán),也就是 oid 參數(shù)。

4. 完整代碼

# -*- coding: utf-8 -*-# Author: W.Y.# Email: wangyingchn@outlook.com# Date: 2022/4/12# 導(dǎo)入模塊import requests # 請求數(shù)據(jù)import time # 時間模塊import json # json 模塊,儲存數(shù)據(jù)import csv # 保存數(shù)據(jù)# 請求數(shù)據(jù)def get_response(page): url = 'https://api.bilibili.com/x/v2/reply/main' # 接口網(wǎng)址的主要結(jié)構(gòu) # 請求頭數(shù)據(jù) headers = { 'accept': '*/*', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8', 'referer': 'https://www.bilibili.com/video/BV16X4y1g7wT', 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': 'Windows', 'sec-fetch-dest': 'script', 'sec-fetch-mode': 'no-cors', 'sec-fetch-site': 'same-site', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' '(KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36' # 根據(jù)測試不需要 cookie 信息也可以獲取數(shù)據(jù) # 需要 cookie 的話在自己的瀏覽器中復(fù)制,這里涉及隱私就不放 cookie 信息了 } # 構(gòu)造請求參數(shù) params = { # 'callback': 'jQuery17201888299578386794_' + str(round(time.time() * 1000)), # 'jsonp': 'jsonp', 'next': page, # 頁碼 'type': 1, 'oid': 715024588, # 視頻av號 'mode': 3, # 評論排序方式 # 'plat': 1, # '_': str(round(time.time() * 1000)) # 生成當(dāng)前時間戳 } # 通過get方法請求數(shù)據(jù) response = requests.get(url, headers=headers, params=params) return response# 解析數(shù)據(jù)def parse_data(response): response.encoding = 'utf-8' # 修改編碼格式 data_json = json.loads(response.text) # 通過 json 解析數(shù)據(jù) comment_list = data_json['data']['replies'] # 獲取 data 下面的 replies 列表 comments = [] # 構(gòu)建空列表保存每頁的評論數(shù)據(jù) for i in range(len(comment_list)): # 循環(huán)獲取每條評論的數(shù)據(jù) comment = { 'id': comment_list[i]['rpid'], # 評論id 'time': time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(comment_list[i]['ctime'])), # 評論時間,由時間戳轉(zhuǎn)換 'parent': comment_list[i]['parent'], # 父評論id 'like': comment_list[i]['like'], # 點贊數(shù) 'user_id': comment_list[i]['member']['mid'], # 評論用戶id 'user_name': comment_list[i]['member']['uname'], # 用戶名 'content': comment_list[i]['content']['message'] # 評論內(nèi)容 # 需要其他數(shù)據(jù)的可以再在 json 中查看并獲取對應(yīng)的名稱 } comments.append(comment) # 每頁的評論數(shù)據(jù) return comments# 保存數(shù)據(jù)def save_data(comments, save_path): with open(save_path, 'a', newline='', encoding='utf-8') as fp: # 設(shè)置表頭,即列名 csv_header = ['id', 'time', 'parent', 'like', 'user_id', 'user_name', 'content'] csv_writer = csv.DictWriter(fp, csv_header) # 如果文件不存在,則寫入表頭;如果文件已經(jīng)存在,則直接追加數(shù)據(jù)不再次寫入表頭 if fp.tell() == 0: csv_writer.writeheader() csv_writer.writerows(comments) # 寫入數(shù)據(jù)# 定義爬取函數(shù)def crawler(page, save_path): time.sleep(2) # 暫停 2 秒,避免請求過于頻繁 response = get_response(page) # 請求數(shù)據(jù) comments = parse_data(response) # 解析數(shù)據(jù) save_data(comments, save_path) # 儲存數(shù)據(jù) print(f'成功爬取第{page+1}頁')if __name__ == '__main__': save_file = 'bilibili.csv' # 保存路徑 total_counts = 1000 # 爬取 1000 條評論 # 如果要爬取所有評論,可以改成全部評論數(shù)。 # 如果要爬取多個視頻的評論,可以通過下面的代碼,爬取第一頁的時候返回所有的評論數(shù) # total_counts = data_json['data']['cursor']['all_count'] # 頁碼循環(huán),每頁有 20 條評論,所以通過總評論數(shù)計算頁碼 for p in range(total_counts//20 + 1): crawler(p, save_file)詳細(xì)內(nèi)容參見連享會推文

相關(guān)推文

Note:產(chǎn)生如下推文列表的 Stata 命令為:
. lianxh Python
. songbl Python
安裝最新版 lianxh/ songbl 命令:
. ssc install lianxh, replace
. ssc install songbl, replace

關(guān)鍵詞:教程,詳細(xì),動態(tài),小菜

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點擊下載Chrome瀏覽器
關(guān)閉