python爬虫实践(二)——爬取张艺谋导演的电影《影》的豆瓣影评并进行简单分析
学了爬虫之后,都只是爬取一些简单的小页面,觉得没意思,所以我现在准备爬取一下豆瓣上张艺谋导演的“影”的短评,存入数据库,并进行简单的分析和数据可视化,因为用到的只是比较多,所以写一篇博客当做笔记。
第一步:想要存入数据库就必须与数据库进行链接,并建立相应的数据表,这里我是在win10下使用oracle数据库。
经过思考,我认为我们爬取一个短评的时候,只需要用到几个字段:
1.用户名
2.评论的日期
3.这个评论有多少人点赞
4.这个用户给电影打几分
5.用户的评价
接下来写一个函数,这个函数的功能是:根据传入的参数来判断在指定用户下是否存在指定的表,如果存在,就先删除表,再创建表,如果不存在,就直接创建表。这样做可以保证你创建表的时候不会报错,因为函数会根据传入的参数进行建表,代码如下
import cx_Oracle #导入连接oracle需要的包
def begin(table_name): #参数是你要创建的表的名称
db = cx_Oracle.connect('scott/tiger@localhost:1521/mldn')
#连接数据库scott是用户名,tiger是密码,@localhost:1521/mldn是监听,根据自己实际情况来填写
cr = db.cursor() #创建sursor
drop_sql="drop table " + table_name
#这个sql语句是删除表
gudge_sql = "SELECT COUNT(*) FROM ALL_TABLES WHERE OWNER = UPPER('scott') AND TABLE_NAME = UPPER('"+ table_name +"')"
#这个sql语句是判断在scott用户下下是否存在table_name表,不存在,则返回值为0
s = "(name varchar2(50),comment_date varchar2(50),vote varchar2(40),star varchar2(40),user_comment varchar2(3000))"
create_sql = "create table " + table_name + s
#这是创建表的sql语句
cr.execute(gudge_sql) #查询table_name表是否存在
rs = cr.fetchall() #接收返回值
t = str(rs)[2:-3] #把返回值转化为字符串
if t not in [ '0',]: #如果返回值不为零,即table_name表存在
cr.execute(drop_sql) # 执行删除语句
cr.execute(create_sql) #创建table_name表
db.close() #关闭数据库连接
这个函数根据你传入的表名来创建数据表
第二步:构造请求头
现在有了数据表,你以为可以开始编写爬了?并不能,经过我实践,发现如果以游客身份爬取,爬不了多少数据,需要登录后才可以爬取更多的数据,我不想去爬虫来模拟登录,第一,太繁琐,第二,因为有图片验证码,目前我还不会用算法来自动识别图片。所以我的方法是:首先用浏览器人工登陆一次,然后按下F12或者Fn+F12,选中Network,刷新一下页面,在Name栏选中最顶上的一项点击,就会如下图所示,

把这个Request Headers下的内容复制下来,做成一个字典,再装载成请求头,就可以爬取所有数据了
设置headers的代码如下:
from urllib import request
def set_hesders(url):
'''
设置请求头
:param url: url链接
:return: 装载后的url链接
'''
heraders = {
'Accep': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Cookie': 'll="108310"; bid=DPJxH93sKZk; ps=y; push_noty_num=0; push_doumail_num=0; __utmz=30149280.1539566865.1.1.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; __utmv=30149280.18590; _ga=GA1.2.1546841640.1539566865; _gid=GA1.2.971937718.1539566892; __utmz=223695111.1539567345.1.1.utmcsr=douban.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __yadk_uid=9XHtMuB2idRYlXP8XsRsmPElvO1oUwKN; _vwo_uuid_v2=DDCDE0957ED07334B61B397CFEF020CDF|2e3c5addb3d627db5895e452f22fa302; gr_user_id=a617c8a3-166c-4cd2-960e-381f28945fb6; ap_v=0,6.0; _pk_ref.100001.4cf6=%5B%22%22%2C%22%22%2C1539599000%2C%22https%3A%2F%2Fwww.douban.com%2F%22%5D; _pk_ses.100001.4cf6=*; __utma=30149280.1546841640.1539566865.1539588868.1539599000.4; __utma=223695111.1546841640.1539566865.1539588868.1539599001.4; __utmb=223695111.0.10.1539599001; ue="3203655760@qq.com"; __utmc=30149280; __utmt=1; dbcl2="185909990:9qcuJLLcZVo"; ck=HKvy; __utmb=30149280.4.10.1539599000; __utmc=223695111; _pk_id.100001.4cf6=39d7c14ac0d6bd63.1539567345.4.1539600176.1539589195.',
'Host': 'movie.douban.com',
'Referer': 'https://movie.douban.com/',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3'
}
return request.Request(url,headers = heraders)
第三步:生成url
通过观察,我们知道,在影评的每一页的url链接都差不多,所以用一个函数来生成每一页的url
代码如下:
def get_pageurl():
pageurl_list = []
for i in range(25):
url = "https://movie.douban.com/subject/4864908/comments?start=" + str(i * 20) + "&limit=20&sort=new_score&status=P"
pageurl_list.append(url)
return pageurl_list
第四步:爬取页面并解析页面,运用xpath解析,然后把数据存入数据库
此过程需要用到sqlalchemy库、pandas库
from sqlalchemy import create_engine
from urllib import request
from lxml import etree
import pandas as pd
import os
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
#我这行代码是因为我向数据库写入或者读取时有中文会报错,所以才写这行代码
def spyder_and_insert(table_name,url):
engjine = create_engine('oracle://scott:tiger@localhost:1521/mldn')
url = set_hesders(url)
try:
rsp = request.urlopen(url) #url请求
except:
print("url错误")
html = rsp.read()
html = etree.HTML(html)
try:
comment_List = html.xpath("//div[@class='comment']")
except:
print("cookie错误")
for i in range(len(comment_List)):
name = str(comment_List[i].xpath("./h3/span[@class = 'comment-info']/a/text()"))[2:-2]
comment_date = str(comment_List[i].xpath("./h3/span[@class = 'comment-info']/span[@class='comment-time ']/text()"))[24:-20]
vote = str(comment_List[i].xpath("./h3/span[@class='comment-vote']/span/text()"))[2:-2]
star = str(comment_List[i].xpath("./h3/span[@class = 'comment-info']/span[last()-1]/@title"))[2:-2]
user_comment = str(comment_List[i].xpath("./p/span/text()"))[2:-2]
if star not in ['很差','还行','较差','力荐','推荐']:
star = "未打分"
d = [{"comment_date": comment_date, "name": name, "vote": vote, "star": star, "user_comment": user_comment},]
df = pd.DataFrame(d) #转化为DataFrame类型
try:
#向数据库写入数据
df.to_sql("douban_comments", con=engjine, index=False, if_exists="append")
except:
print("向数据库插入数据出错")
第五步:爬取所有评论并存入数据库,为了更直观的查看爬虫爬取的进度,我编写了一个进度条代码,效果如下

函数的代码如下:
def gather():
print("开始爬取".center(30, "-"))
start = time.perf_counter()
print(" 0 %[->************************.]0.45s",end="")
table_name = "douban_comments"
user_name = "scott"
begin(user_name, table_name)
douban_pageurls = get_pageurl()
lo = len(douban_pageurls)
for i in range(lo):
spyder_and_insert(table_name,douban_pageurls[i])
a = '*' * i
b = '.' * (lo - i)
c = (i / lo) * 100
dur = time.perf_counter() - start
print("\r{:^3.0f}%[{}->{}]{:.2f}s".format(c, a, b, dur), end='')
time.sleep(0.1)
print("\n" + "爬取结束".center(30, '-'))
现在数据已经存入数据库了,现在我们用代码对数据进行简单分析,使数据可视化
该过程会用到numpy库、matplotlib库,
首先,我们对评价进行统计,分别画出直方图和饼状图,代码如下
from sqlalchemy import create_engine
import cx_Oracle
import pandas as pd
import numpy as np
import os
import matplotlib.pyplot as plt
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
engjine = create_engine('oracle://scott:tiger@localhost:1521/mldn')
def begin():
aaa = pd.read_sql_table("douban_comments",con=engjine)
s1 = aaa.loc[aaa["star"]=="很差",["star"]].count()["star"]
s2 = aaa.loc[aaa["star"]=="较差",["star"]].count()["star"]
s3 = aaa.loc[aaa["star"]=="还行",["star"]].count()["star"]
s4 = aaa.loc[aaa["star"]=="推荐",["star"]].count()["star"]
s5 = aaa.loc[aaa["star"]=="力荐",["star"]].count()["star"]
s6 = aaa.loc[aaa["star"]=="未打分",["star"]].count()["star"]
a = np.array([s1,s2,s3,s4,s5,s6])
b = np.array(["一星","两星","三星","四星","五星","未打分"])
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
return a,b
def zhifangtu(a,b):
plt.bar(b,a,width = 0.8)
plt.title("“影”的评分")
#plt.show()
plt.savefig('./ying1.png',dpi=200)
def bingzhuangtu(a,b):
plt.figure(figsize=(6, 6))
plt.pie(a, labels=b, autopct='%1.1f%%')
plt.title("“影”的评分")
plt.savefig('./ying2.png', dpi=200)
运行函数后,得到下面两幅图:

还可以对评论进行统计,这里我用jieba库和wordcloud库来对所有评论进行中文分词并生成词云
代码如下:
import jieba
from sqlalchemy import create_engine
import pandas as pd
import numpy as np
import os
import re
import wordcloud
def ciying():
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
engjine = create_engine('oracle://scott:tiger@localhost:1521/mldn')
aaa = pd.read_sql_table("douban_comments",con=engjine)
a = ""
for i in range(len(aaa['user_comment'])): #循环取出所有评论并拼接字符串
a += str(aaa.loc[i,'user_comment'])
ls = jieba.lcut(a) #用jieba库分词
txt = " ".join(ls)
w = wordcloud.WordCloud(
width=1000, height=700,
background_color="white",
font_path="msyh.ttc"
)
w.generate(txt) #生成词云
w.to_file("ying3.png") #保存图片
ciying()
运行函数后的图片如下:

通过上面几个图面,我们发现其实评价也还好,打三分四分的占了近60%,毕竟可是从豆瓣爬取的评论,豆瓣大家都懂的。。。
总结:因为涉及到的知识点比较杂,所以我就想着写篇博客,当作自己的学习笔记了,我的代码还有许多写的差的的地方,函数命名也不专业,但是这是我第一个把数据写入数据库的爬虫,自己心里还是有点小激动的....
python爬虫实践(二)——爬取张艺谋导演的电影《影》的豆瓣影评并进行简单分析的更多相关文章
- Python 爬虫入门(二)——爬取妹子图
Python 爬虫入门 听说你写代码没动力?本文就给你动力,爬取妹子图.如果这也没动力那就没救了. GitHub 地址: https://github.com/injetlee/Python/blob ...
- Python爬虫学习(二) ——————爬取前程无忧招聘信息并写入excel
作为一名Pythoner,相信大家对Python的就业前景或多或少会有一些关注.索性我们就写一个爬虫去获取一些我们需要的信息,今天我们要爬取的是前程无忧!说干就干!进入到前程无忧的官网,输入关键字&q ...
- 【转载】教你分分钟学会用python爬虫框架Scrapy爬取心目中的女神
原文:教你分分钟学会用python爬虫框架Scrapy爬取心目中的女神 本博文将带领你从入门到精通爬虫框架Scrapy,最终具备爬取任何网页的数据的能力.本文以校花网为例进行爬取,校花网:http:/ ...
- Python爬虫实例:爬取豆瓣Top250
入门第一个爬虫一般都是爬这个,实在是太简单.用了 requests 和 bs4 库. 1.检查网页元素,提取所需要的信息并保存.这个用 bs4 就可以,前面的文章中已经有详细的用法阐述. 2.找到下一 ...
- Python 爬虫入门之爬取妹子图
Python 爬虫入门之爬取妹子图 来源:李英杰 链接: https://segmentfault.com/a/1190000015798452 听说你写代码没动力?本文就给你动力,爬取妹子图.如果 ...
- Python爬虫实例:爬取B站《工作细胞》短评——异步加载信息的爬取
很多网页的信息都是通过异步加载的,本文就举例讨论下此类网页的抓取. <工作细胞>最近比较火,bilibili 上目前的短评已经有17000多条. 先看分析下页面 右边 li 标签中的就是短 ...
- Python爬虫实例:爬取猫眼电影——破解字体反爬
字体反爬 字体反爬也就是自定义字体反爬,通过调用自定义的字体文件来渲染网页中的文字,而网页中的文字不再是文字,而是相应的字体编码,通过复制或者简单的采集是无法采集到编码后的文字内容的. 现在貌似不少网 ...
- python爬虫-基础入门-爬取整个网站《3》
python爬虫-基础入门-爬取整个网站<3> 描述: 前两章粗略的讲述了python2.python3爬取整个网站,这章节简单的记录一下python2.python3的区别 python ...
- python爬虫-基础入门-爬取整个网站《2》
python爬虫-基础入门-爬取整个网站<2> 描述: 开场白已在<python爬虫-基础入门-爬取整个网站<1>>中描述过了,这里不在描述,只附上 python3 ...
随机推荐
- 转化.vdi到.vmdk
OracleVirtualBox转化.vdi到.vmdk E:\Genymotion-deployed\CentOS_7_64>"D:/Program Files/Oracle/Vir ...
- javascript 正则test、exec、search、match区别?
都可以放正则表达示 exec是RegExp类的匹配方法 match是字符串类的匹配方法 test() 方法用于检测一个字符串是否匹配某个模式.返回 true,否则返回 false. var resul ...
- 关于ElementUI中MessageBox弹框的取消键盘触发事件(enter,esc)关闭弹窗(执行事件)的解决方法
好久没见了 在项目中遇到一个小小的需求,总结了一下! 详细我就不介绍了,相信大家用过的话,很了解.详见文档-----------> http://element-cn.eleme.io/#/zh ...
- java Socket实例
可以实现客户端与服务端双向通信,支持多客户端连接,客户端断开连接,服务端不会出现异常 服务端代码: package com.thinkgem.jeesite.modules.socketTest.de ...
- JAVA进阶15
间歇性混吃等死,持续性踌躇满志系列-------------第15天 1.TCP网络程序 package code0329; import java.io.BufferedReader; import ...
- 2018-2019-2 《网络对抗技术》Exp0 Kali安装 Week1 20165237
2018-2019-2 <网络对抗技术>Exp0 Kali安装 Week1 20165237 安装虚拟机 首先创建虚拟机 创建好虚拟机后,打开虚拟机进行安装.第一步选择Graphcal i ...
- [经验交流] k8s mount 文件到容器目录
docker 的 volume 可以 mount 单个文件(比如单个配置文件)到容器目录.同时保留原目录的内容.放到 k8s 中,结果却变成了这样:k8s 的 volume 把文件mount 到容器目 ...
- Redis缓存穿透和缓存雪崩以及解决方案
Redis缓存穿透和缓存雪崩以及解决方案 Redis缓存穿透和缓存雪崩以及解决方案缓存穿透解决方案布隆过滤缓存空对象比较缓存雪崩解决方案保证缓存层服务高可用性依赖隔离组件为后端限流并降级数据预热缓存并 ...
- United States Department of Agriculture 美国农业部网站数据自动下载小脚本
帮对象写的自动点击页面的小脚本,如果有需要的可以试试,(#^.^#) https://apps.fas.usda.gov/gats/ExpressQuery1.aspx var year = '199 ...
- centos修改SSH端口并禁用root远程登录
1.使用 root 用户执行以下步骤:只在 CentOS 6.5 下验证. 2.先查看下服务器端口号范围: # sysctl -a|grep ip_local_port_range 3.修改端口 vi ...