這裏以優酷《哪吒》的用戶評論爲目標
大家應該都翻過電影評論,隨着往下翻越來越多的評論逐個加載出來,頁面無需刷新。所以這是典型的AJAX網頁
先上代碼
import requests
import json
import re
# 構建評論列表的URL,接下來用以得到傑森格式的評論內容
comment_url = "https://p.comments.youku.com/ycp/comment/pc/commentList?jsoncallback=n_commentList&\
app=100-DDwODVkv&objectId=1097963004&objectType=1&listType=0¤t\
Page={}&pageSize=30&sign=8fc6ac73638d4f0263358f1ae323489b&time=1572784759".format(input("請輸入,來獲取本頁的評論:"))
# 得到json數據
head = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) \
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"}
html = requests.get(comment_url, headers=head).text
html_json = re.findall("n_commentList(.*)", html, re.S)[0].strip(")").replace("(", "")
print(len(html_json))
# 轉化爲json後,通過debug調試,發現是一個由列表和字典混合組成多層嵌套的字典,需要層層挖掘信息
json_content = json.loads(html_json)
content_data = json_content["data"]
comment_data = content_data["comment"]
number = 1
for each_comment in comment_data:
print("第{}條評論\n".format(number), "賬號:", each_comment["userId"])
print("用戶名:", each_comment["user"]["userName"])
if len(each_comment["user"]["vipInfo"]) == 0:
print("VIP等級:非會員")
else:
print("VIP等級:", each_comment["user"]["vipInfo"]["name"])
print("評論內容:".format(number), each_comment["content"], "\n", "--"*25)
number += 1
過程:
首先在電影頁面往下滑,評論將會加載
的確在源代碼中我們可以看到用戶評論,但是用戶信息將無能爲力
這裏我使用Chrome瀏覽器,監控network的變化
我們首先要找到:
沒錯,就是評論列表,comment是評論的意思
接着我們在新頁面中打開他的URL
可以看出來,這是一個json格式
通過對比多個頁面的URL,發現他們並沒有很大的差別,只有頁數產生了變化,如我的代碼中使用format來加入頁碼。
在處理這段json時有個坑
報錯信息如下:
"""raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)"""
最終原因折磨了我好久,是因爲這段json被一組不易察覺的圓括號包裹了,而這會導致無法解碼
一開始我是這樣寫的 :
非貪心算法
re.findall("n_commentList(.*?)", html, re.S)
實際上這樣什麼也提取不出來!!!
首先這裏的括號並不會作爲標識元素,也就是說你提取的文本依然會有括號
其次非貪心算法將會提取最短字符串,而且本段文本又是以")"爲結尾,所以提取公式中將會沒有結尾,那麼非貪心算法什麼也不會提取
作如下修改
re.findall("n_commentList(.*)", html, re.S)[0].strip(")").replace("(", "")
終於可以成功轉換爲json
用戶信息一覽無餘:
每一條展開都很複雜