写在开头

豆瓣上有着大量的影视剧的评论,所以说,要是想要实现对广大人民群众的观点的分析,对一部片子的理解,综合来看大家的评论是很有必要的。而短评作为短小精干的快速评论入口,是值得一谈的。

所以先要实现对其的数据的爬取。

目前来看,基本内容是可以爬取的。最大的问题在于速度。后续考虑准备运用多线程的方式处理下。以及可以尝试其他提速的方法。

下面是这个程序的构思编写过程。

构思准备

爬取的思路,及反省与思考

盲目状态

最初,并不知道豆瓣对于未登陆用户的限制,盲目的爬取,看着评论文件,发现行数太少,也就是说评论内容太少,感觉不对劲。

我利用了即时打印写入内容的方式,发现,到了第十页左右的时候,出现无法获得页面内评论内容,思考了下后,试着将页面源代码打印出来,发现到了后面,就出现提示权限不足。我一下子知道了,是因为没有登录的原因。

登录

之前看过内容,明白这时候应该借助cookie的方式了。

但是又要处理验证码。而且,似乎初次登陆的时候并不需要验证码。为了方便,下面直接使用了存在验证码的方式。

由于开始不了解,不知道应该提交哪些信息,多方查找后,终于明白,就是在登录页面登陆后,打开浏览器的开发者工具里,查看里面的网络,注意关注里面的方法一列中的post所在行那项。在登陆点击后,随着页面的跳转,会出现一个post页面,点击后查看其参数,若是火狐的话有个专门的参数窗口,其中就有要提交的参数了。包括用户信息,还有登录跳转页面(redir)等等。

在最初,我直接将https://accounts.douban.com/login选作登录地址,当然也将从其登陆的信息复制了出来,但是发现登录到redir还可以,要是用opener.open()再登录 'https://movie.douban.com/subject/26934346/comments?start=' + str(start) + '&limit=20&sort=new_score&status=P' 这里构造的页面是登不上的。这里我也是测试了好久才发现的问题。具体原因我不清楚。可能是有哪些知识我是遗漏了的。

后来觉察到这一点后,我尝试使用现在的信息登录,如下。

main_url = 'https://accounts.douban.com/login?source=movie'
formdata = {
"form_email":"你的邮箱",
"form_password":"你的密码",
"source":"movie",
"redir":"https://movie.douban.com/subject/26934346/",
"login":"登录"
}
user_agent = r'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36'
headers = {'User-Agnet': user_agent, 'Connection': 'keep-alive'}

诶,竟然登上去了!

关于验证码的纠结思考

由于豆瓣的验证码是登一次变一次的。所以在发生上面的问题时,在没有找到正确的处理办法之时,我怀疑是因为验证码,在我获取上一次验证码图片,并将验证信息输入到formdata这个提交信息的字典中后,再次使用request.Request(url=main_url, data=logingpostdata, headers=headers)opener.open(req_ligin).read().decode('utf-8')的时候,会不会验证码发生了变化?而我提交的是刚才的验证码?

又开始查资料,后来终于明白,这里提交的信息中指定了验证码的图片的captchaID,这样使得提交信息时候,返回来的验证码图片也就是这个,图片id是唯一的,当你自己修改了提交内容,豆瓣也会使用你提供的这个id来获取服务器里的验证码图片,所以保证了图片的一致。(这是我的理解,觉得有问题,或者更精确的理解的,欢迎留言)

使用库的考虑

BeautifulSoup, re

准备尝试下beautiful soup这个库,对于拆解html页面很便利。但是在实践中,还是可能会用到正则表达式re模块。可见,正则表达式还是很重要的。掌握基本可以查表使用时必须的。

在代码中可以看出,我对于该库的使用还是有些粗,不巧妙,还有待加强。

不过,今天尝试了下,用CSS选择器还是很方便的。select()方法,很方便,可以参考从浏览器开发者工具里选择元素对应的CSS选择器,很直接。

urllib.request,http.cookiejar

借鉴之前使用urllib.request的经验,尝试直接使用urllib.request.Request(url, headers=headers)urllib.request.urlopen(request, data=None, timeout=3)发现,豆瓣的短评,最一开始还好,但是在爬取将近十多页的短评时,会报出Forbidden的异常,查询后得知,应该是豆瓣对于游客用户的限制,需要登录才可以。参考网上一些其他教程,可以使用设置cookie的方法来处理。

使用了cookiejar.CookieJar()声明对象,来保存cookie到了变量中。利用的request.HTTPCookieProcessor()来创建cookie处理器。利用request.build_opener()构造了一个 opener,后面利用opener.open()来打开直接网页或者处理请求。

socket

类似上一个爬虫里的设置,这里直接使用了全局的超时设定。

import socket
timeout = 3
socket.setdefaulttimeout(timeout)

限制三秒,超出就抛出socket.timeout异常。捕获后重新连接。

# 超时重连
state = False
while not state:
try:
html = opener.open(url).read().decode('utf-8')
state = True
except socket.timeout:
state = False

time

为了防止爬取过快,设置了循环的延时。

for ...:
...
time.sleep(3)

完整代码

# -*- coding: utf-8 -*-
"""
Created on Thu Aug 17 16:31:35 2017
@note: 为了便于阅读,将模块的引用就近安置了
@author: lart
""" # 用于生成短评页面网址的函数
def MakeUrl(start):
"""make the next page's url"""
url = 'https://movie.douban.com/subject/26934346/comments?start=' + str(start) + '&limit=20&sort=new_score&status=P'
return url # 登录页面信息
main_url = 'https://accounts.douban.com/login?source=movie'
formdata = {
"form_email":"你的邮箱",
"form_password":"你的密码",
"source":"movie",
"redir":"https://movie.douban.com/subject/26934346/",
"login":"登录"
}
user_agent = r'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36'
headers = {'User-Agnet': user_agent, 'Connection': 'keep-alive'} # 保存cookies便于后续页面的保持登陆
from urllib import request
from http import cookiejar cookie = cookiejar.CookieJar()
cookie_support = request.HTTPCookieProcessor(cookie)
opener = request.build_opener(cookie_support) # 编码信息,生成请求,打开页面获取内容
from urllib import parse logingpostdata = parse.urlencode(formdata).encode('utf-8')
req_ligin = request.Request(url=main_url, data=logingpostdata, headers=headers)
response_login = opener.open(req_ligin).read().decode('utf-8') # 获取验证码图片地址
from bs4 import BeautifulSoup try:
soup = BeautifulSoup(response_login, "html.parser")
captchaAddr = soup.find('img', id='captcha_image')['src'] # 匹配验证码id
import re reCaptchaID = r'<input type="hidden" name="captcha-id" value="(.*?)"/'
captchaID = re.findall(reCaptchaID, response_login) # 下载验证码图片
request.urlretrieve(captchaAddr, "captcha.jpg") # 输入验证码并加入提交信息中,重新编码提交获得页面内容
captcha = input('please input the captcha:')
formdata['captcha-solution'] = captcha
formdata['captcha-id'] = captchaID[0]
logingpostdata = parse.urlencode(formdata).encode('utf-8')
req_ligin = request.Request(url=main_url, data=logingpostdata, headers=headers)
response_login = opener.open(req_ligin).read().decode('utf-8') finally:
# 获得页面评论文字
soup = BeautifulSoup(response_login, "html.parser")
totalnum = soup.select("div.mod-hd h2 span a")[0].get_text()[3:-2] # 计算出页数和最后一页的评论数
pagenum = int(totalnum) // 20
commentnum = int(totalnum) % 20
print(pagenum, commentnum) # 设置等待时间,避免爬取太快
import time
# 用于在超时的时候抛出异常,便于捕获重连
import socket timeout = 3
socket.setdefaulttimeout(timeout) # 追加写文件的方式打开文件
with open('秘密森林的短评.txt', 'w+', encoding='utf-8') as file:
# 循环爬取内容
for item in range(pagenum):
print('第' + str(item) + '页')
start = item * 20
url = MakeUrl(start) # 超时重连
state = False
while not state:
try:
html = opener.open(url).read().decode('utf-8')
state = True
except socket.timeout:
state = False # 获得评论内容
soup = BeautifulSoup(html, "html.parser")
comments = soup.select("div.comment > p")
for text in comments:
file.write(text.get_text().split()[0] + '\n')
print(text.get_text())
limit_num = 0
if item == pagenum - 1:
limit_num =+ 1
if limit_num == commentnum:
break
time.sleep(3) print('采集写入完毕')

结果

可见至少也有9200条评论,不管是否有所遗漏,基数已经基本无差。

后续处理

数据已经到手,怎样玩耍就看自己的想法了,近期看到了一篇文章,讲了利用词频制作词云,生成图片,有点意思,决定模仿试试。

Python 爬虫实践:《战狼2》豆瓣影评分析

github:amueller/word_cloud

【Python】我的第一个豆瓣短评爬虫的更多相关文章

  1. 【Python】我的豆瓣短评爬虫的多线程改写

    对之前我的那个豆瓣的短评的爬虫,进行了一下架构性的改动.尽可能实现了模块的分离.但是总是感觉不完美.暂时也没心情折腾了. 同时也添加了多线程的实现.具体过程见下. 改动 独立出来的部分: MakeOp ...

  2. 哪吒票房超复联4,100行python代码抓取豆瓣短评,看看网友怎么说

    <哪吒之魔童降世>这部国产动画巅峰之作,上映快一个月时间,票房口碑双丰收. 迄今已有超一亿人次观看,票房达到42.39亿元,超过复联4,跻身中国票房纪录第三名,仅次于<战狼2> ...

  3. Java豆瓣电影爬虫——抓取电影详情和电影短评数据

    一直想做个这样的爬虫:定制自己的种子,爬取想要的数据,做点力所能及的小分析.正好,这段时间宝宝出生,一边陪宝宝和宝妈,一边把自己做的这个豆瓣电影爬虫的数据采集部分跑起来.现在做一个概要的介绍和演示. ...

  4. Python爬取《你好李焕英》豆瓣短评并基于SnowNLP做情感分析

    爬取过程在这里: Python爬取你好李焕英豆瓣短评并利用stylecloud制作更酷炫的词云图 本文基于前文爬取生成的douban.txt,基于SnowNLP做情感分析. 依赖库: 豆瓣镜像比较快: ...

  5. @1-5使用pandas保存豆瓣短评数据

    使用pandas保存豆瓣短评数据 Python爬虫(入门+进阶)     DC学院 本节课程的内容是介绍open函数和pandas两种保存已爬取的数据的方法,并通过实际例子使用pandas保存数据. ...

  6. @1-4使用Xpath解析豆瓣短评

    使用Xpath解析豆瓣短评 Python爬虫(入门+进阶)     DC学院 本节课程主要介绍解析神器Xpath是什么.Xpath如何安装及使用,以及使用实际的例子讲解Xpath如何解析豆瓣短评的网页 ...

  7. Python之路第一课Day1--随堂笔记

    课堂大纲: 一.Python介绍 二.发展史 三.Python 2 or 3? 四.安装 五.Hello World程序 六.变量 七.用户输入 八.模块初识 九..pyc是个什么鬼? 十.数据类型初 ...

  8. 想成为Python高手,必须看这篇爬虫原理介绍!(附29个爬虫项目)

    互联网是由一个个站点和网络设备组成的大网,我们通过浏览器访问站点,站点把HTML.JS.CSS代码返回给浏览器,这些代码经过浏览器解析.渲染,将丰富多彩的网页呈现我们眼前. 一.爬虫是什么? 如果我们 ...

  9. Python自动化 【第一篇】:Python简介和入门

    Python简介: 一.什么是python Python是一门动态解释性的强类型定义语言. pythonde 特点:“优雅”.“明确”.“简单”. 二.Python由来 python的创始人为吉多·范 ...

随机推荐

  1. linux命令历史

    本人qq群也有许多的技术文档,希望可以为你提供一些帮助(非技术的勿加). QQ群:   281442983 (点击链接加入群:http://jq.qq.com/?_wv=1027&k=29Lo ...

  2. Flask【第9篇】:Flask-script组件

    flask-script组件 Flask Script扩展提供向Flask插入外部脚本的功能,包括运行一个开发用的服务器,一个定制的Python shell,设置数据库的脚本,cronjobs,及其他 ...

  3. ps制作雾的效果

    制作雾的效果 方法一: 新建图层,将前景色设置为白色,背景色为黑色(因为雾的颜色是根据前景色决定的,也可根据这个原理制作火焰效果) 选择滤镜->渲染->云彩(也可选择其他效果的云彩) (选 ...

  4. 使用SpringBoot发邮件

    SpringBoot中已有发邮件的工具包,只需要引用即可使用 1,pom引用 <dependency> <groupId>org.springframework.boot< ...

  5. AQS源码分析笔记

    经过昨晚的培训.对AQS源码的理解有所加强,现在写个小笔记记录一下 同样,还是先写个测试代码,debug走一遍流程, 然后再总结一番即可. 测试代码 import java.util.concurre ...

  6. PHP 大文件上传,支持断点续传,求具体方案、源码或者文件上传插件

    文件夹数据库处理逻辑 publicclass DbFolder { JSONObject root; public DbFolder() { this.root = new JSONObject(); ...

  7. BZOJ 2217: [Poi2011]Lollipop 构造 + 思维

    Description 有一个长度为n的序列a1,a2,...,an.其中ai要么是1("W"),要么是2("T").现在有m个询问,每个询问是询问有没有一个连 ...

  8. 185.[USACO Oct08] 挖水井 (第三次考试大整理)

    185. [USACO Oct08] 挖水井 输入文件:water.in   输出文件:water.out   简单对比 时间限制:1 s   内存限制:128 MB 农夫约翰决定给他的N(1< ...

  9. java jts

    来自:UCMapForOpenGIS https://bbs.csdn.net/topics/380204896?list=992863 对比 其实geotools就是基于jts开发的,而geoser ...

  10. psdash-为开发、测试人员提供简单的方法,在web界面查看服务器的运行情况(网络,带宽,磁盘,CPU), 同时可以在web界面查看日志

    psdash是linux的系统信息web指示板主要由使用数据psutil——由此得名. github地址:https://github.com/Jahaja/psdash 特性 安装 开始 配置 截图 ...