爬取豆瓣

 此爬虫思想:

    1.在get_html 中根据url地址,获取目标数据,判断请求的是否为完整影评的json数据,如果是将返回的数据赋值给json属性,如果不是就赋值html属性
    2.在parse_list函数中,根据正则解析当前页的所有电影的链接,拼接完整的影评链接地址,发送请求,解析影评数据,  找到下一页的链接,发送请求,重新调用parse_list函数解析下一页数据....
    3.在parse_comments()函数中,根据正则解析当前页的所有影评信息,for遍历,找到每一个影评id,根据id拼接完整的影评地址,发送请求,解析完整影评,处理数据,提取分数,输出或保存..... 查找下一页的链接,拼接地址,发送请求,重新调用parse_comments()函数解析数据..

from urllib import request
import codecs
import re
import json
import time


class DBSpider(object):

    def __init__(self):

        # 读取本地文件,做数据的解析
        # with codecs.open('douban.html','r',encoding='utf-8') as f:
        #     self.html = f.read()

        self.html = ''
        self.headers = {
            'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Cookie':'viewed="26274202"; bid=pLJrB4vg3Ps; gr_user_id=708e2966-b9be-4f8a-a45c-bb9492c0b6d9; _vwo_uuid_v2=D3F37F324DBCD65B88AA4ABE9F29BA69A|71918066fff6b32ba4261010dd76f37b; ps=y; ll="128517"; dbcl2="175091692:Etw54wqJAog"; ck=ULZU; _pk_ref.100001.4cf6=%5B%22%22%2C%22%22%2C1520497524%2C%22https%3A%2F%2Fwww.douban.com%2Faccounts%2Flogin%3Fredir%3Dhttps%3A%2F%2Fmovie.douban.com%2F%26source%3DNone%26login_type%3Dsms%22%5D; _pk_id.100001.4cf6=843dca368da83e7b.1520497524.1.1520497524.1520497524.; _pk_ses.100001.4cf6=*; ap=1; push_noty_num=0; push_doumail_num=0'
        }
    # 获取html源代码
    def get_html(self,url):
        # 发请请求
        req = request.Request(url, headers=self.headers)
        response = request.urlopen(req)
        # 判断是否为json数据,包含的是完整影评
        if '/full' in url:
            self.json = response.read().decode('utf-8')
        else:
            self.html = response.read().decode('utf-8')
        time.sleep(2)

    # 解析首页列表
    def parse_list(self):
        pattern = re.compile('<div class="hd.*?href="(.*?)"',re.S)
        res = re.findall(pattern,self.html)
        # for循环遍历列表,取出每一个电影信息
        for link in res:
            # 拼接完整的电影影评地址
            url = link + 'reviews'
            # 发起请求,拿回影评页面
            self.get_html(url)
            # 解析详情
            self.parse_comments(url)

            # 读取本地文件,做数据解析
            # with codecs.open('detail.html','r',encoding='utf-8') as f:
            #     # 详情html
            #     self.html = f.read()
            #     # 解析详情页面的数据
            #     self.parse_comments(url)

        # 找下一页
        pattern = re.compile('<link rel="next" href="(.*?)"')
        res = re.search(pattern,self.html)
        if res:
            # 拼接下一页的url地址
            next_href= 'https://movie.douban.com/top250?'+res.group(1)
            # 发起请求,拿回下一页数据
            self.get_html(next_href)
            # 调用此函数,解析数据
            self.parse_list()
        else:
            print('没有下一页')


    # 解析影评页面
    def parse_comments(self,url):

        pattern = re.compile('<div class="main review-item.*?id="(.*?)".*?v:reviewer.*?>(.*?)</a>.*?<span.*?class="(.*?)".*?title="(.*?)".*?<span.*?>(.*?)</span',re.S)
        res = re.findall(pattern,self.html)
        # for循环遍历数据
        for ID,name,star,suggest,date in res:

            # 读取本地数据,做数据解析
            # with codecs.open('test.json','r',encoding='utf-8') as f:
            #     info = f.read()
            #     com_dict = json.loads(info)
            #     comment = com_dict.get('html')
            #     comment = re.sub(re.compile('<br>'),'\n',comment)

            # 根据url发送请求,拿回完整的影评信息
            url = 'https://movie.douban.com/j/review/%s/full' % ID
            self.get_html(url)
            com_dict = json.loads(self.json)
            comment = com_dict.get('html')
            # 处理数据
            comment = re.sub(re.compile('<br>'),'\n',comment)
            comment = re.sub(re.compile('<.*?>|\n| ',re.S),'',comment)
            # 把影评分数匹配出来
            sorce = re.search(re.compile('\d+'),star).group()

            print('作者:{}\n作者ID:{}\n分数:{}\n建议:{}\n发布日期:{}\n评价内容:{}'.format(name,ID,sorce,suggest,date,comment))


        # 找下一页
        pattern = re.compile('<link rel="next" href="(.*?)"')
        res = re.search(pattern,self.html)
        if res:
            # 拼接下一页的url地址
            next_href = url + res.group(1)
            # 发起请求,拿回下一页数据
            self.get_html(next_href)
            # 调用此函数,解析数据
            self.parse_comments(url)
        else:
            print('没有下一页')



    def start(self):

        self.get_html('https://movie.douban.com/top250?qq-pf-to=pcqq.group')
        self.parse_list()

if __name__ == '__main__':

    db = DBSpider()
    db.start()



运行结果:










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值