【python--爬虫】豆瓣读书用户评分爬虫

豆瓣读书用户评分爬虫

最近有好友不会做豆瓣读书的评论和评分的爬虫求助博主,博主做完后发给了该好友,本着造福小白的心理,博主在这里给大家分享自己写的豆瓣爬虫。

1.分析网页

这里我们先随便打开一本书的评论,由于通过csdn访问豆瓣时会自动添加referer,请手动复制网址在新标签页中打开
(https://book.douban.com/subject/30442488/comments/)
在这里插入图片描述在页面源代码中查找评论的位置,在class属性为"short"的<span>标签中
在这里插入图片描述在页面源代码中查找评分的位置,在class属性为"vote-count的<span>标签中
在这里插入图片描述

2.代码解析

首先我们先创建接下来需要用的的东西

import requests 
#导入requests模块用于请求网页
from lxml import etree
#从lxml模块中导入etree模块用于解析网页

class Userspinfen():  
#定义一个Douban类,用于承载后面的代码
    def __init__(self,url): 
    #定义__init__方法,并且设置形参url
    #设置类中的私有变量
        self.url = url          #设置请求的url
        self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:65.0) Gecko/20100101 Firefox/65.0",}
        #创建requests请示网页时使用的请求头
        self.pinfen = 0         #用于计算评分
        self.sub_page_url = []  #用于承载品论页的url
        self.pinlun = []        #用于承载评论信息
      · 
        #Python类创建实例时默认就会调用__init__方法,也就是说给__init__方法使用的形参需要在创建实例时传递进来,       

这里我们创建一个专门用于请求网页的方法,要求每次调用时需要传递进来一个url地址,发起requests.get请求,使用传递进来的url作为请求地址,使用类中的私有变量self.headers,作为请求头。并且将网页返回内容作为get_html方法的返回值.

def get_html(self,page_url):
        return requests.get(url=page_url,headers=self.headers).text

在创建一个用于检测返回的评论页面url是否存在于定义的私有变量sub_page_url中,如果没有则存入

def test_more(self,sub_page_url):
#要求每次调用时需要传递进来评论页面的url地址
    for url in sub_page_url:
    #使用for循环将评论页面url地址列表中的url依此取出
        if not (url in self.sub_page_url):
           self.sub_page_url.append(url)
           #检测url是否存在于私有变量sub_page_url,如果没有则存入

定义一个专门用于提取评论和评分的方法

def get_info(self,page_url):
#定义一个get_info方法,并且要求调用时传递page_url
    html_etree = etree.HTML(self.get_html(page_url))
    #调用之前定义的get_html方法,并将本方法的page_url传递进入,将返回值转换为etree格式   
    pinfen = html_etree.xpath('//span[@class="vote-count"]/text()')
    #在网页代码etree对象中使用xpath匹配出class属性为"vote-count的\<span>标签中的内容
    self.pinlun += html_etree.xpath('//span[@class="short"]/text()')
    #在网页代码etree对象中匹配出class属性为"short"的\<span>标签中的内容
    for i in pinfen:
        self.pinfen += int(i)
    #使用for循环提取出评分

定义一个用于检测评论页面url的函数

def test_page_number(self,main_url):
#定义一个get_info方法,并且要求调用时传递main_url
    html_etree = etree.HTML(self.get_html(main_url))
    #调用get_html方法将返回的内容转换为etree格式
    sub_page_url = html_etree.xpath('//li[@class="p"]/a[@class="page-btn"]/@href')
    #匹配出第一页,上一页,下一页的选项的内容
    if not (len(sub_page_url) == 2):
        self.test_more(sub_page_url)
        #传递进test_more方法检测是否有重复的
        self.test_page_number(self.url+"{}".format(sub_page_url[-1]))
        #将刚刚爬取到的下一页的url和定义的私有变量self.url拼接起来,然后作为调用本函数的实参,调用自身
    else:
        for url  in self.sub_page_url:
            self.get_info(self.url+"{}".format(url))
            #当检测的到的页面url数量等于2时,证明已经到达了品论的最后一页,说明此时已经拥有了全部评论页面的url,此时就可以补齐评论页url调用爬取信息的方法,获取信息

(由于豆瓣读书的评论不显示总的评论页数,仅仅只有第一页,上一页,下一页的选项,只能通过不停的爬取下一页选项,直到爬取不到下一页选项时说明到评论最后一页了)

3.代码分享

import requests
from lxml import etree

class Douban():
    def __init__(self,url):
        self.url = url
        self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:65.0) Gecko/20100101 Firefox/65.0",}
        self.pinfen = 0
        self.sub_page_url = []
        self.pinlun = []
        
    def get_html(self,page_url):
        return requests.get(url=page_url,headers=self.headers).text

    def test_more(self,sub_page_url):
        for url in sub_page_url:
            if not (url in self.sub_page_url):
               self.sub_page_url.append(url)

    def get_info(self,page_url):
        html = self.get_html(page_url)
        html_etree = etree.HTML(html)
        pinfen = html_etree.xpath('//span[@class="vote-count"]/text()')
        self.pinlun += html_etree.xpath('//span[@class="short"]/text()')
        for i in pinfen:
            self.pinfen += int(i)                

    def test_page_number(self,main_url):
        html_etree = etree.HTML(self.get_html(main_url))
        sub_page_url = html_etree.xpath('//li[@class="p"]/a[@class="page-btn"]/@href')
        if not (len(sub_page_url) == 2):
            self.test_more(sub_page_url)
            self.test_page_number(self.url+"{}".format(sub_page_url[-1]))
        else:
            for url  in self.sub_page_url:
                self.get_info(self.url+"{}".format(url))      

        
douban = Douban("https://book.douban.com/subject/30442488/comments/")
douban.test_page_number("https://book.douban.com/subject/30442488/comments/")
print ("该书用于总评分{}".format(douban.pinfen))
print (douban.pinlun)

  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值