爬虫实战丨走进哈利波特的魔法世界
本文作者:温和铭,中南财经政法大学统计与数学学院
本文编辑:张孟晗
技术总编:陈 鼎
Stata&Python云端课程来啦!
为了感谢大家长久以来的支持和信任,爬虫俱乐部为大家送福利啦!!!Stata&Python特惠课程双双上线腾讯课堂~爬虫俱乐部推出了Python编程培训课程、Stata基础课程、Stata进阶课程、Stata文本分析、正则表达式、网络爬虫、基本字符串课程。报名课程即可加入答疑群,对报名有任何疑问欢迎在公众号后台和腾讯课堂留言哦。我们在这篇推文的最后提供了每门课程的课程二维码,大家有需要的话可以直接扫描二维码查看课程详情并进行购买哦~
引言
哈利波特这个IP一度风靡全球,今年九月,《哈利波特:魔法觉醒》手游的上线和北京环球影城的开园,为众多哈迷带来了一波又一波“回忆杀”。而对于那些只看过一遍小说或电影,甚至是对哈利波特仅仅只是听说过的“麻瓜”们,要想回忆或深入了解故事剧情却不太容易,毕竟,整个哈利波特系列共有七部小说和八部电影。如何快速走进哈利波特的魔法世界呢?爬虫“魔法”或许能助你一臂之力!
# 访问前10页的影评页面(翻页)
urls_page = list()
for i in range(0, 10, 1):
i *=20
url_page = "https://movie.douban.com/subject/1295038/reviews?start={}".format(i)
urls_page.append(url_page)
#查看每页中的影评
urls_movie = list()
for url in urls_page:
#获取页面中的所有影评页面的url
response = requests.get(url, headers=headers)
content = response.content.decode("utf-8")
#解析HTML文档并提取所有影评页面的url
html = etree.HTML(content)
url_movie = html.xpath("//h2/a/@href") #Xpath定位影评标题
urls_movie.append(url_movie)
根据网页信息,不难看出完整影评和摘要都放在一个id='link-report'的div标签下,故只需以此标签为起始,选择下级的所有p标签即可,注意此处要使用双斜杠\\。
确定好了每一步爬取的具体策略,接下来就可以开始施展爬虫“魔法”了,完整的代码如下:
import requests
from lxml import etree
import xlwt
import time
#设置请求头参数
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}
#访问前10页的影评页面(翻页)
urls_page = list()
for i in range(0, 10, 1):
i *=20
url_page = "https://movie.douban.com/subject/1295038/reviews?start={}".format(i)
urls_page.append(url_page)
#查看每页中的影评
urls_movie = list()
for url in urls_page:
#获取页面中的所有影评页面的url
response = requests.get(url, headers=headers)
content = response.content.decode("utf-8")
#解析HTML文档并提取所有影评页面的url
html = etree.HTML(content)
url_movie = html.xpath("//h2/a/@href")
urls_movie.append(url_movie)
movies = list()
#i用于记录页数
i = 0
#urls_movie中的每一个元素都是一个列表,每个列表都表示一页中所有电影的影评url
for page in urls_movie:
for url in page:
#对每一个url都进行一次爬虫操作
response_movie = requests.get(url, headers=headers)
content = response_movie.content.decode("utf-8")
html = etree.HTML(content)
#电影评论者
commenter = html.xpath("//header/a/span/text()")[0]
#评论者评分
rank = html.xpath("//header//span/@title")
if not rank:
rank = "无"
else:
rank = rank[0]
#剧透警告
spoiler = html.xpath("//div[@class='main-bd']//p/text()")
if not spoiler:
spoiler = "无"
else:
spoiler = spoiler[0]
# 影评及拼接
comment_list = html.xpath("//div[@id='link-report']//p/text()")
comment = "".join(comment_list)
movie = {
"commenter": commenter,
"rank": rank,
"spoiler": spoiler,
"comment": comment
}
movies.append(movie)
i +=1
print("第{}页已经爬取完成".format(i))
time.sleep(1.5)
print(len(movies)) #显示一共爬取了多少条影评
# 存储为excel
workbook = xlwt.Workbook(encoding="utf-8")
sheet1 = workbook.add_sheet("电影影评")
keys = list(movies[0].keys())
#表头
for i in range(len(keys)):
sheet1.write(0, i, keys[i])
#数据
for row in range(1, len(movies)+1):
for col, key in zip(range(len(keys)), keys):
sheet1.write(row, col, movies[row - 1][key])
workbook.save(r"C:\Users\Desktop\哈利波特与魔法石影评.xls")
import xlrd
import collections
from collections import Counter
import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
#读取表格
data=xlrd.open_workbook("哈利波特与魔法石影评.xls")
#获取表格的sheets
table=data.sheets()[0]
#获取第二列数据,即评分
rankdata = table.col_values(1,start_rowx=1) #去掉第一行标签值
counter = Counter(rankdata) #统计频数
print(counter) #显示计数结果
#绘制频数分布直方图
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
plt.style.use("ggplot")
x = ['无', '较差', '还行','推荐','力荐']
y = [37, 2, 6, 42, 113]
fig, ax = plt.subplots(figsize=(10, 7))
ax.bar(x=x, height=y)
ax.set_title("电影评分频数分布直方图", fontsize=15)
#加载所需包
import numpy as np
import pandas as pd
import jieba,codecs
import jieba.posseg as pseg #标注词性模块
import matplotlib.pyplot as plt
from wordcloud import WordCloud
from imageio import imread
#导入人名、停用词、特定词库
renmings = pd.read_csv('人名.txt',engine='python',encoding='utf-8',names=['renming'])['renming']
stopwords = pd.read_csv('stopword.txt',engine='python',encoding='utf-8',names=['stopwords'])['stopwords'].tolist()
comment = open('剧透影评.txt',encoding='utf-8').read()
jieba.load_userdict('哈利波特词库.txt')
#定义一个分词函数
def words_cut(comment):
words = list(jieba.cut(comment))
stopwords1 = [w for w in words if len(w)==1] #添加停用词
seg = set(words) - set(stopwords) - set(stopwords1) #过滤停用词,得到更为精确的分词
result = [i for i in words if i in seg]
return result
#初次分词
commentwords = words_cut(comment)
renming = [i.split(' ')[0] for i in set(renmings)] #只要人物名字,出掉词频以及词性
nameswords = [i for i in commentwords if i in set(renming)] #筛选出人物名字
#统计词频
commentwords_count = pd.Series(commentwords).value_counts().sort_values(ascending=False)
nameswords_count = pd.Series(nameswords).value_counts().sort_values(ascending=False)
commentwords_count[:100].index
#自定义部分词语
jieba.add_word('邓布利多',100,'nr')
jieba.add_word('哈利波特',100,'nr')
jieba.add_word('霍格沃茨',100,'n')
jieba.add_word('拉唐克斯',100,'nr')
jieba.add_word('伏地魔',100,'nr')
jieba.del_word('罗恩说')
jieba.del_word('地说')
jieba.del_word('斯内')
#再次分词
commentwords = words_cut(comment)
nameswords = [i for i in commentwords if i in set(renming)]
commentwords_count = pd.Series(commentwords).value_counts().sort_values(ascending=False)
nameswords_count = pd.Series(nameswords).value_counts().sort_values(ascending=False)
commentwords_count[:100].index
#绘制词云
#读取背景图片
back_picture = imread("cloud.jpg")
#设置词云参数
wc = WordCloud(font_path="simhei.ttf",
background_color="black",
max_words=2000,
mask=back_picture,
max_font_size=200,
random_state=42
)
wc2 = wc.fit_words(commentwords_count)
#绘制词云图
plt.figure(figsize=(20,10))
plt.imshow(wc2)
plt.axis("off")
plt.show()
wc.to_file("ciyun.png")
RECOMMEND
腾讯课堂课程二维码
对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!
往期推文推荐
数据集合并的新路子-frlink命令
Seminar丨附近的公司:利用卫星图像研究本地信息优势线性同余法生成伪随机数
[技能篇]多线程爬虫
“好哭”是衡量一部好电影的标准吗?
Stata&Python云端课程来啦!带你了解Stata中的矩阵
Seminar|总统的朋友:政治关联与企业价值爬虫实战 | 爬取中国天气网
爬虫实战 | 爬取东方财富网经济数据——以居民消费价格指数(CPI)为例
Seminar|媒体关联董事对融资和外部治理的影响神奇的组内交叉合并 PDF分章节转TXT并实现可视化——以胡景北知青日记1971至1978年为例万物皆可开——shellout妙用
无处不在的系列配置项|从零开始的Pyecharts(三)
使用Python制作自动聊天机器人
fillin一下,平衡回来~
order命令——快速改变变量顺序的利器 Ajax应用场景——以获取雪球网港股代码及公司名称为例播放列表中的歌单排行
在Stata中轻松运用program编写命令
Meta Analysis in Stata17芒果TV视频弹幕爬取之《我在他乡挺好的》
Stata中的判断神器——confirm命令
cngdf——名义GDP与实际GDP之间的摆渡船最近《扫黑风暴》有点火爆!我从豆瓣评论中发现了这些……
随机森林-Random Forest
复原之神--preserve&restore
合并,“纵”享新丝滑:frameappend & xframeappend什么是全局配置项?|从零开始的Pyecharts(二)帮你拿下数据可视化|从零开始的Pyecharts
Stata助力疫情打卡管理——是谁没有接龙呢?
关于我们
微信公众号“Stata and Python数据分析”分享实用的Stata、Python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
武汉字符串数据科技有限公司一直为广大用户提供数据采集和分析的服务工作,如果您有这方面的需求,请发邮件到statatraining@163.com,或者直接联系我们的数据中台总工程司海涛先生,电话:18203668525,wechat: super4ht。海涛先生曾长期在香港大学从事研究工作,现为知名985大学的博士生,爬虫俱乐部网络爬虫技术和正则表达式的课程负责人。
此外,欢迎大家踊跃投稿,介绍一些关于Stata和Python的数据处理和分析技巧。
投稿邮箱:statatraining@163.com投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。