[Python] Используйте Python в качестве простого поискового робота для сканирования комментариев B-станции.

Оглавление

Введение

2. Анализ веб-страниц

3. Код

1. голова

2. Получить корневой комментарий

3. Получить дочерние комментарии

Четыре, общий код

V. Резюме


Введение

        В комментариях 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. Резюме

        Код, который я написал сам, — ерунда, пожалуйста, поправьте меня.

Guess you like

Origin blog.csdn.net/ClushioAqua/article/details/129834114