Оглавление
2. Получить корневой комментарий
3. Получить дочерние комментарии
Введение
В комментариях Bilibili нет функции поиска, поэтому я написал краулер для сканирования комментариев Bilibili и сохранения их в локальном txt.
Во-первых, вам нужно установить библиотеку запросов Python и библиотеку BeautifulSoup.
запросы на установку pip
пип установить bs4
Если появляется успешно, значит установка прошла успешно
Вот все необходимые библиотеки
import requests
from bs4 import BeautifulSoup
import re
import json
from pprint import pprint
import time
2. Анализ веб-страниц
Пример веб-страницы Ланьина "Исследуя окно" BV18T411G7xJ
Мы проверили исходный код страницы и обнаружили, что в исходном коде нет информации о комментариях. Мы продолжили скользить вниз к позиции комментария и обнаружили, что комментарий загружается некоторое время, прежде чем он появляется.В это время я догадался, что нам нужно захватить пакет, чтобы получить информацию о комментарии.
Откройте F12, запросите параметры ответа в сети и найдите информацию о комментарии.
Я извлек URL-адрес и проверил различные данные внутри
Я не знаю, почему URL-адрес здесь должен удалять данные обратного вызова, чтобы нормально его просматривать.
Загрузите Json Formatter в Edge для лучшего просмотра.
Обнаружил, что пакет не может отображать все комментарии, продолжаем скользить вниз, ищем данные об ответе по F12 и извлекаем URL
Выясняется, что изменится только next, так что же next=1? На практике оказывается, что данные next=1 и next=0 одинаковы, поэтому при программировании мы можем начинать непосредственно с 1.
Но мы обнаружили, что есть только корневой комментарий и нет подкомментариев.Мы подозреваем, что подкомментарии находятся в другом пакете.Проверив подкомментарии одного из комментариев, мы поймали новый пакет в F12.
Точно так же мы извлекаем URL-адрес и наблюдаем, что ответы являются обязательными подкомментариями. Точно так же все ответы не могут быть отображены на одной странице.После наблюдения обнаруживается, что отличается только pn каждого комментария.
Так как же связаны подкомментарии и корневые комментарии?
Наблюдая за URL-адресом, мы обнаружили , что URL-адрес подкомментария имеет корень, поэтому мы изучили согласованность между корнем и подкомментарием и обнаружили, что rpid корня является корнем подкомментария , поэтому мы нашел отношения.
Наконец, при написании кода я также обнаружил проблему, то есть некоторые корневые комментарии не нужно расширять, поэтому элемент ответов в пакете подкомментариев пустой, а информация об этих комментариях существует в основном комментарии. пакет, нам нужно только просто просто судить об этом.
Как только вы поймете структуру, программирование станет намного проще.
3. Код
1. голова
#网页头
headers = {
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36",
"referer" : "https://www.bilibili.com/"
}
2. Получить корневой комментарий
def get_rootReply(headers):
num = 1
replay_index = 1
while True:
URL = (f"https://api.bilibili.com/x/v2/reply/main?&jsonp=jsonp&next={num}&type=1&oid=470113786&mode=3&plat=1&_=1680096302818") #获得网页源码
respond = requests.get(URL , headers = headers) # 获得源代码 抓包
# print(respond.status_code)
reply_num = 0
if(respond.status_code == 200): # 如果响应为200就继续,否则退出
respond.encoding = "UTF-8"
html = respond.text
json_html = json.loads(html) # 把格式转化为json格式 一个是好让pprint打印,一个是好寻找关键代码
if json_html['data']['replies'] is None or len(json_html['data']['replies']) == 0 :
break
for i in range(0,len(json_html['data']['replies'])): #一页只能读取20条评论
reply = json_html['data']['replies'][reply_num]['content']['message']
root = json_html['data']['replies'][reply_num]['rpid']
reply = reply.replace('\n',',')
# print(reply)
file.write(str(replay_index) + '.' + reply + '\n')
if json_html['data']['replies'][reply_num]['replies'] is not None:
if(get_SecondReply(headers,root) == 0):
for i in range(0,len(json_html['data']['replies'][reply_num]['replies'])):
reply = json_html['data']['replies'][reply_num]['replies'][i]['content']['message']
reply = reply.replace('\n',',')
file.write(" " + reply + '\n')
reply_num += 1
replay_index += 1
num += 1
time.sleep(0.5)
else :
print("respond error!")
break
file.close()
3. Получить дочерние комментарии
def get_SecondReply(headers,root):
pn = 1
while True:
URL = (f"https://api.bilibili.com/x/v2/reply/reply?jsonp=jsonp&pn={pn}&type=1&oid=824175427&ps=10&root={root}&_=1679992607971")
respond = requests.get(URL , headers = headers) # 获得源代码 抓包
reply_num = 0
if(respond.status_code == 200):
respond.encoding = "UTF-8"
html = respond.text
json_html = json.loads(html)
if json_html['data']['replies'] is None:
if(pn == 1):
return 0
else :
return 1
for i in range(0,len(json_html['data']['replies'])):
if json_html['data']['replies'] is None:
break
reply = json_html['data']['replies'][reply_num]['content']['message']
reply = reply.replace('\n',',')
# print(reply)
reply_num += 1
file.write(" " + reply + '\n')
pn += 1
time.sleep(0.5)
else:
print("Sreply error!")
exit(-1)
Таким образом собираются все модули
Четыре, общий код
import requests
from bs4 import BeautifulSoup
import re
import json
from pprint import pprint
import time
#网页头
headers = {
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36",
"referer" : "https://www.bilibili.com/"
}
file = open('lanyin.txt', 'w',encoding='utf-8')
def get_SecondReply(headers,root):
pn = 1
while True:
URL = (f"https://api.bilibili.com/x/v2/reply/reply?jsonp=jsonp&pn={pn}&type=1&oid=824175427&ps=10&root={root}&_=1679992607971")
respond = requests.get(URL , headers = headers) # 获得源代码 抓包
reply_num = 0
if(respond.status_code == 200):
respond.encoding = "UTF-8"
html = respond.text
json_html = json.loads(html)
if json_html['data']['replies'] is None:
if(pn == 1):
return 0
else :
return 1
for i in range(0,len(json_html['data']['replies'])):
if json_html['data']['replies'] is None:
break
reply = json_html['data']['replies'][reply_num]['content']['message']
reply = reply.replace('\n',',')
# print(reply)
reply_num += 1
file.write(" " + reply + '\n')
pn += 1
time.sleep(0.5)
else:
print("Sreply error!")
exit(-1)
def get_rootReply(headers):
num = 1
replay_index = 1
while True:
URL = (f"https://api.bilibili.com/x/v2/reply/main?&jsonp=jsonp&next={num}&type=1&oid=470113786&mode=3&plat=1&_=1680096302818") #获得网页源码
respond = requests.get(URL , headers = headers) # 获得源代码 抓包
# print(respond.status_code)
reply_num = 0
if(respond.status_code == 200): # 如果响应为200就继续,否则退出
respond.encoding = "UTF-8"
html = respond.text
json_html = json.loads(html) # 把格式转化为json格式 一个是好让pprint打印,一个是好寻找关键代码
if json_html['data']['replies'] is None or len(json_html['data']['replies']) == 0 :
break
for i in range(0,len(json_html['data']['replies'])): #一页只能读取20条评论
reply = json_html['data']['replies'][reply_num]['content']['message']
root = json_html['data']['replies'][reply_num]['rpid']
reply = reply.replace('\n',',')
# print(reply)
file.write(str(replay_index) + '.' + reply + '\n')
if json_html['data']['replies'][reply_num]['replies'] is not None:
if(get_SecondReply(headers,root) == 0):
for i in range(0,len(json_html['data']['replies'][reply_num]['replies'])):
reply = json_html['data']['replies'][reply_num]['replies'][i]['content']['message']
reply = reply.replace('\n',',')
file.write(" " + reply + '\n')
reply_num += 1
replay_index += 1
num += 1
time.sleep(0.5)
else :
print("respond error!")
break
file.close()
if __name__ == '__main__':
get_rootReply(headers)
print("sucessful")
V. Резюме
Код, который я написал сам, — ерунда, пожалуйста, поправьте меня.