Rastrear informações do livro e revisar informações da leitura de Douban

Ao fazer o design da graduação recentemente, você precisa coletar dados de classificação do usuário para o algoritmo de filtragem colaborativa e, ao mesmo tempo, coletar dados de comentários para análise de sentimentos

Pit

  1. Os livros de Douban podem não ser classificados ou os usuários comentaram, mas não foram classificados. E o método de codificação dos livros de Douban é muito indefeso: os livros populares são sempre impopulares perto dos livros, sem classificações, sem comentários, com tanta frequência que a saída falha
  2. Não é possível rastrear muito rápido, apenas 40-50 páginas por minuto, uma solicitação pode ser acessada apenas mil vezes, caso contrário, ele relatará o código de status 403

fake_useragent

Nesse rastreador, fake_useragent foi usado para forjar o cabeçalho da solicitação, porque ouvi dizer que o mecanismo anti-rastreamento
de Douban é melhor.O uso de fake_useragent é simples da seguinte maneira: random é gerar aleatoriamente um cabeçalho de solicitação

from fake_useragent import UserAgent
import requests
ua=UserAgent()
url="https://www.baidu.com"    #请求的网址
headers={"User-Agent":ua.random}   #请求头
response=requests.get(url=url,headers=headers)   #请求网址
print(headers)
print(response.status_code)   #响应状态信息
text = response.headers
for line in text.items():
    print(line)

Rastrear informações do livro e revisar informações da leitura de Douban

A primeira coisa a observar são esses links
https://book.douban.com/subject/26953606/ página de informações do livro
https://book.douban.com/subject/26953606/comments/ página de comentários da primeira página
https: // book.douban.com/subject/26953606/comments/hot?p=2 Na segunda página da página de resenhas,
você pode ver que a frente é a mesma https://book.douban.com/subject/ mais um ID de livro, página de resenhas Seguida por / comments /, a segunda página de comentários é seguida por um hot? P = 2, então as 3 páginas recursivas são hot? P = 3
algumas das operações para escrever texto, porque eu sou o
segundo a coletar dados Eu a revisei novamente.A distribuição de livros populares é muito escassa, portanto, primeiro determine se o número total de comentários excede 1.000 no programa.Se exceder 1.000, continue rastreando, caso contrário, continue
alterando o bug, que é digital. A gravação no arquivo deve ser convertida em str

#coding=utf-8
#下载豆瓣图书的评分、评论,需要建立四张表。auther:wuyou
#表一:图书ID,图书名,平均分
#表二:用户ID,用户名
#表三:图书ID,热门评论
#表四:用户ID,图书ID,评分,评分时间
import requests
import time
import random
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
ua = UserAgent()
header = {
    'User-Agent': ua.random
}
def get_score(book_id,text):                   #获取(图书ID,图书名,图书评分)
    soup = BeautifulSoup(text,'lxml')
    try:
        book_name = soup.select("#wrapper > h1 > span")   #返回书名的列表
        name = book_name[0].string
        book_score = soup.select("#interest_sectl > div > div.rating_self.clearfix > strong")  #返回分数的列表
        score = book_score[0].string
        #print("book name is " + str(name)+" and score is "+str(score))  打印书名和分数
        line = str(book_id) + "," + name + "," + str(score) + "\n"   #拼接图书信息
        with open("BookInfo.txt","a",encoding="utf-8") as file:    #表一:图书ID,图书名,平均分
            file.write(line)
        file.close()
    except:
        print("book " + str(book_id) + "get score is  failed!")



def write_txt(soup,book_id):    #参与为url,图书id,和网页页码
    try:     #为了防止报错,因为有些人可以不打分,那么在user_info下只有一个span
        comment_list = soup.find_all("span","short")     #找到评论所在的区域
        comments = ""
        flag = 0
        for line in comment_list:       #把逗号全部替换成分号
            bc = line.string
            bc = bc.replace(",","。")     #将英文逗号替换成句号
            bc = bc.replace(",","。")    #将中文逗号替换成句号
            bc = bc .replace(";","。")    #将分号替换成句号
            if flag == 0:     #如果是第一条评论
                flag += 1
            else:
                comments += ";"      #评论之间用分号间隔
            comments += bc
        with open("BookComments.txt","a",encoding="utf-8") as file:    #表三:图书ID,热门评论
            BookComments = str(book_id) + "," +comments + "\n"
            file.write(BookComments)
        file.close()
        user_list = soup.find_all("span", "comment-info")   #找到用户和评分的所在区域
        user_info_txt = open("UserInfo.txt","a",encoding="utf-8")
        user_score_txt = open("UserScore.txt","a",encoding="utf-8")
        for user_info in user_list:
            user_name = user_info.find("a").string         #用户姓名所在的<a></a>
            user_url = user_info.find("a").attrs["href"]   #提取出超链接
            user_id = user_url.split("/")[-2]              #提取出用户id
            score = user_info.find_all("span")[0].attrs["title"]   #找到用户评分的区域,得到分数
            time_info = user_info.find_all("span")[1].string   #提取出评分的时间
            time_info = time_info.split("-")
            score_year = time_info[0]       #截取出评论时间的年份
            user_info_txt.write(user_id + "," +user_name + "\n")            #表二:用户ID,用户名
            user_score_txt.write(user_id + "," + str(book_id) + "," + score + "," + str(score_year) + "\n")  #表四:用户ID,图书ID,评分,评分时间
            #print("book_id is " + book_id +" user name is " + user_name + ",id is " + user_id + ",score is " + score_info + " " + time_info)   打印出一系列信息
        user_info_txt.close()
        user_score_txt.close()
    except:
        print("cannot find!")


def get_comments(soup, comment_url, book_id, page):         #获取(图书ID,图书评论),(图书ID,用户ID,用户评分),(用户ID,用户名)
    while page <= 2:           #爬取的页数
        if int(page) == 1:     #如果是第一页
            write_txt(soup, book_id)          #传入超链接
            page += 1           #页数加一
        else:
            comment_url += "hot?p=" + str(page)   #拼合链接
            time.sleep(random.uniform(3,6))
            html = requests.get(url=comment_url,headers=header)
            if html.status_code == 200:
                comment_text = html.text
                soup = BeautifulSoup(comment_text,"lxml")
                write_txt(soup, book_id)          #传入网页内容
                page += 1           #页数加一



#https://book.douban.com/subject/1007305/
if __name__ == '__main__':
    url="https://book.douban.com/subject/"
    startID=1007304  #起始的图书ID
    st = 0   #循环的起点
    lens=20000   #len=20000时,需要爬取的总书籍数
    while st < lens:           #设置st和lens是为了爬取热门书籍
        if startID-1007304 >=1000:
            print("stop! " + startID)
            break
        try:
            startID += 1           #图书id增长
            score_url = url + str(startID) + "/"       #图书信息的链接地址
            html = requests.get(url=score_url,headers=header)
            html.encoding = "utf-8"
            time.sleep(random.uniform(3, 6))  # 暂停几秒,随机数在2-4s之间
            if html.status_code == 200:
                comment_url = score_url + "comments/"  # 评论的链接地址
                comment_html = requests.get(url=comment_url, headers=header).text
                time.sleep(random.uniform(3, 6))  # 暂停几秒,随机数在2-4s之间
                soup = BeautifulSoup(comment_html, "lxml")
                total_comments = soup.select("#total-comments")[0].string
                comment_num = total_comments.replace("全部共 ","")
                comment_num = comment_num.replace(" 条","")
                if int(comment_num) >= 1000:
                    st +=1
                    print(str(startID)+" is success!" + score_url + " comment_num is " + comment_num)
                    text = html.text
                    get_score(startID,text)
                    get_comments(soup,comment_url,startID,1)       #获取评论信息
                else:
                    print(score_url + " is failed!" + " comment_num is " + comment_num)
            else:
                print(str(startID)+" is failed!")
        except:
            print(str(startID) + " is failed!",end='')
            print(html.status_code)

A saída é a seguinte (esta é a saída do código quando há instruções de saída anteriores). Um
Insira a descrição da imagem aqui
monte de dados no meio é omitido.
Isso é rastreado para alguns livros impopulares e o número de comentários é muito baixo, então eu ignorei diretamente
Insira a descrição da imagem aqui

Publicado 304 artigos originais · 51 elogios · 140.000 visualizações

Acho que você gosta

Origin blog.csdn.net/qq_39905917/article/details/104784103
Recomendado
Clasificación