Python3爬取豆瓣短评——以好剧《白鹿原》为例

背景:

近期刚看完电视剧《白鹿原》。”自信平生无愧事,死后方敢对青天“的白嘉轩虽显执拗,但仍令人倾服,朱先生提到的“凡物之骤为之而遽成者,其器小也;凡物之一览者而易尽也,其中无有也”更是令人警醒三分。
剧是好剧,看完后想了解下豆友的反响,遂写了个简单的爬虫,爬取了豆瓣《白鹿原》的短评。 爬虫内容以分析和梳理为主,只给出代码片段 。整合后的完整代码见github:https://github.com/Bamboo314/Douban_comments/blob/master/spider.py


数据说明

因为在登录账号的情况下,豆瓣也只提供500条展示的数据,又有20条数据缺少“评分”该变量。故最后爬取了480条数据。
在这里插入图片描述
昵称 文本数据,说明评论是谁写的
时间 时间变量
评分 离散变量
短评 文本数据,评论者对《白鹿原》简短的评价
被点赞数 连续变量


事前分析

1.翻页

《白鹿原》短评的URL:https://movie.douban.com/subject/26322644/comments?status=P
翻页后,URL变为:https://movie.douban.com/subject/26322644/comments?start=20&limit=20&sort=new_score&status=P
多次翻页后发现仅仅在参数start上有差异,第一页参数start=0,第二页为20,以此类推,直到480(第20页),之后的数据不再展示。
所以可以用一个for循环来实现类似翻页来爬取每一页信息的操作:

for pageIndex in range(0, 500, 20):
	url = 'https://movie.douban.com/subject/26322644/comments?\
	start={0}&limit=20&sort=new_score&status=P'.format(pageIndex)
    pass     # 省略的是爬取单页信息的内容
2.使用Cookies直接请求登陆

当start设置到220(第10页)时,豆瓣就提醒需要登陆后才能查看更多信息。我们可以用post传递登录信息、get传递Cookies等操作进行模拟登录。
这里用get传递Cookies的方法,更为简便。先登录,F12打开浏览器审查元素,选择Network,刷新后获取 Cookie(如下图所示),然后将该 Cookie 添加到 Headers 中去,然后用 GET 方法请求即可。

在这里插入图片描述

3.信息获取

需要爬取的信息藏在网页的html里。
当然可以使用正则表达式提取我们需要的信息,也可以用各类网页解析库进行解析。
这里用网页解析库BeautifulSoup的select方法,直接传入CSS选择器即可完成(审查元素来帮助我们选择)。
如以获取短评内容为例:

# 信息初始化
comments = []
# 在用BeautifulSoup规范化的html里,使用css选择器获取信息
for comment in soup.select('#comments span.short'):
	comments.append(comment.get_text().replace('\n', ''))
	
print(comments)

爬取流程

在这里插入图片描述

1.发起请求

通过requests库以GET向url发起请求。
请求中包含额外的headers等信息,等待服务器响应。

import requests

headers = {
	'Host': 'movie.douban.com',
    'Referer': 'https://movie.douban.com/subject/26322644/',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36',
    'Cookie':'你的cookie'        
}
response = requests.get(url, headers=headers)

万一被封禁,可以尝试在get请求加入参数proxies={‘http’:random.choice(pro)},其中pro是个列表,存放从网页上找到的免费代理。当然也可以自己搭建一个代理池。

2.获取响应内容

若服务器能正常相应,会得到一个Response,其中的内容便是所要获取的页面内容(HTML)。

# 输出html内容
html = response.text
print(html)
3.解析内容

需要用网页解析库规范后再用select方法传入css选择器获取信息。

from bs4 import BeautifulSoup
import time

soup = BeautifulSoup(html, 'lxml')  # 'lxml'解析方法速度快、文档容错能力强(前提需要装C语言库)

# 初始化数据
nicknames = []
dates = []
evaluates = []
comments = []
supports = []
    
# 提取数据
for nickname in soup.select('#comments a.'):
    nicknames.append(nickname.get_text())
# print(nicknames)
# print(len(nicknames))
for date in soup.select('#comments span.comment-time'):
    dates.append(date.get('title')) 
for evaluate in soup.select('#comments span.rating'):
    evaluates.append(evaluate.get('title'))
print('start=%i有:' %pageIndex, len(soup.select('#comments span.rating')))  # 因为存在不打分的人
for comment in soup.select('#comments span.short'):
    comments.append(comment.get_text().replace('\n', ''))
for support in soup.select('#comments span.votes'):
    supports.append(support.get_text())      
# 最后爬完是单页所有指定的数据,可以用for循环完成爬取指定页数的数据
# print('爬取第%i页的数据完成' % (pageIndex / 20 + 1))
time.sleep(1)
4.保存数据

直接使用pandas库将爬下的数据(列表)组成一个数据框,直接用.to_excel的方式将数据保存到Excel内。
(当然也可以存到MySQL、MongDB等数据库中,或.txt, .csv, .json等格式的文件中。但抓下来的数据较小,且这个方法比较方便。若有必要完全可以将文件另存为utf-8的csv文件)

# 将数据整合到数据框
df = pd.DataFrame(list(zip(nicknames, dates, evaluates, comments, supports)),
                      columns=['昵称', '日期', '评价', '短评', '被点赞数'])
# 将数据框保存为Excel文件
df.to_excel("你想保存的位置/bailuPlace_short.xlsx")

总结

如果有纰漏还望指出,也感激大家能给出更好的方法。当然,如果有任何疑问,可以私信我。谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值