Python爬取⾖瓣电影评论数据(通⽤模板代码)----以《中国医⽣》为例
中国医⽣⾖瓣电影评论获取
1 前⾔
⾖瓣是影迷评分。⾮视频⽹站,也⾮购票平台,能长期专门使⽤⾖瓣标记、评价电影的,相对来说是属于影迷性质较强的观众,相对普通观众⽽⾔,年轻化、阅⽚量⼤、对电影要求更⾼。同时,5星制的打分机制也让电影评分整体趋向平稳,⾼分电影出现得更少。
⼤部分⼈常常以⾖瓣都标准,以此为参考,判断电影的⼝碑如何。同时另外还有⼀个猫眼电影。但是⾖瓣参考的是影迷体⼝碑,猫眼参考的是路⼈观众⼝碑,看电影时该参考哪个?那就看你对⾃⼰⼝味偏向的认定了。
本篇⽂章是我针对 ⾖瓣电影短评 专门写的⼀篇⽂章,具有很强的通⽤性(在⾖瓣⽹站数据结构不改变的情况下,改变另说)。在本次爬取电影的评论过程中,不难发现每⼀部电影的数据存储结构其实都是⼀致的,除了 电影ID号 不同外。所以在本篇⽂章代码的基础上,我们只要通过改变很⼩⼀部分代码(即电影ID号)就能爬取其他你想爬取的电影短评了。具体的在后⾯将会讲解。
接下来,本⽂以 《中国医⽣》 为例,爬取他的电影评价,及其评价的 时间,⽤户,星级,短评,⽀持
数 来进⾏探索。
2 数据源分析
1. ⾸先打开⽹页 链接: ,到电影《中国医⽣》,你将会看见以下的页⾯
往往每⼀部电影的短评都会特别多,但是由于⾖瓣官⽅的限制,在不登录账号的情况下,我们只能爬取200余条的数据。登陆账号之后也只能爬取500条的数据。这肯定不是我们想要的结果。但是⼈在屋檐下,不得不低头。
也只能这样的。这也算是官⽅对爬⾍的⼀种限制吧。同时还能减少服务器的压⼒,限制了向我们这种会⽆节制 “ 骚扰” ⼈家服务器的家伙。再者说哪个⽤户真会⼀条⼀条的去查看评论,还TM的达到500条之多呢。所以说⼈家这样限制何乐⽽不为了。是我我也这样搞。
2. 点击了图⽚中的(全部xxx条) 之后,滑动到评论区的底部。就能够翻页查看评论了。
3. ⽇常 F12 键进⼊源代码查看页⾯。到 Network ,先点击翻页然后 Win + R 刷新。
4. 点击进⼊ Headers 选项,这⼉的 Url 才是我们访问真正要⽤到的,
5. Cookie,不会的话先⾃⾏百度了解⼀下。
6. 多翻看⼏次页⾯,⽐较⼀下 url 的变化
url 的⽐较
movie.douban/subject/35087699/comments?percent_type=&start=0&limit=20&status=P&sort=new_score&comments_only=1&ck=Cuyu movie.douban/subject/35087699/comments?percent_type=&start=20&limit=20&status=P
&sort=new_score&comments_only=1&ck=Cuyu movie.douban/subject/35087699/comments?percent_type=&start=40&limit=20&status=P&sort=new_score&comments_only=1&ck=Cuyu
不难发现这⼀串 url 的区别仅在于 start= xxx 的不同。所以我们只需要发现规律构造 url 即可。
3数据爬取(代码实现)
直接附上我运⾏成功的代码。具体代码的意思在源码中也说的还算⽐较清楚,有问题的朋友可以留⾔、或者私信我噢~
import requests
import json
import re
import os
import pandas as pd
import time
from bs4 import BeautifulSoup
def Agent_info():
"""⽤于保存Cookies、Url、user-agent、headers信息等"""
cookie ="""bid=9no_4gJG-5o; ll="118341"; _vwo_uuid_v2=D6141C70C03D0BC588BA7686AE0394CD8|fce743832252586e86d91da46a148850; __yad k_uid=8zqclqObqrPjxvsfPLMQjtqAtL06Wfox; __utmc=30149280; __utmc=223695111; dbcl2="242201158:KyUAnlqlyFM"; ck=Cuyu; push_noty_num=0; pus h_doumail_num=0; __utma=30149280.1002249445.1626451473.1626495018.1626497210.5; __utmz=30149280.1626497210.5.3.utmcsr=accounts.doub an|utmccn=(referral)|utmcmd=referral|utmcct=/; __utmb=30149280.2.10.1626497210; __utmv=30149280.24220; _pk_ref.100001.4cf6=%5B%22%22 %2C%22%22%2C1626497217%2C%22https%3A%2F%2Fwww.douban%2F%22%5D; _pk_ses.100001.4cf6=*; __utma=223695111.839260749.1626 451473.1626495018.1626497217.5; __utmb=223695111.0.10.1626497217; __utmz=223695111.1626497217.5.3.utmcsr=douban|ut
mccn=(referral)|
utmcmd=referral|utmcct=/; __gads=ID=959412129efce07a-22e944bf5eca00ee:T=1626497219:RT=1626497219:S=ALNI_MaIy_OZsR-Ds2xa5qdJ2ZBeQ9 4Pww; ap_v=0,6.0; _pk_id.100001.4cf6=5b7867dea6ed024b.1626451473.5.1626502711.1626495035"""
headers ={
"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.67",
"Cookie": cookie
}
return headers
def get_html(url):
"""获取⽹页全部数据"""
headers = Agent_info()
try:
r = (url=url, headers=headers, timeout=30)
status = r.status_code # 爬⾍的状态
datas = json.)["html"]
str_html ="<html>{}</html>".format(datas)
# 注意:.prettify()会将数据格式转换为 str 格式,所以这⾥放弃格式化标签处理
html = BeautifulSoup(str_html,"html.parser")
print("爬⾍状态码: "+str(status))
# print(type(html))
# 此时返回的是⼀个 html标签的全部内容,且经过格式化处理(str格式)
return html
except Exception as e:
print("很遗憾,数据爬取失败!")
print(e)
def etl_data(html):
"""提取出我们想要的数据"""
# 将所有⽤户的评论单独存放在列表, .find_all⽅法需要数据为<class 'bs4.BeautifulSoup'>格式
comments = html.find_all('div','comment-item')
# print(comments[0])
# 获取电影的评论并保存到列表(时间,⽤户,星级,短评,⽀持数)
datas =[]
for span in comments:
# 短评发表的时间
times = span.find('span','comment-time').attrs['title']
# ⽤户名
name = span.find('a').attrs["title"]
# ⽤户评分星级
# 可⽤.attrs['class'][0][-2:]获取星级(为末尾的两位数,)
try:
level = span.find('span','rating').attrs['class'][0][-2:]
if(level =='10'):
level ="⼀星"
elif(level =='20'):
level ="⼆星"
elif(level =='30'):
level ="三星"
elif(level =='40'):
level ="四星"
elif(level =='50'):
level ="五星"
except Exception as e:
# 因为会存在有⽤户写评价但是不打星级的情况
level ="⽆评价"
# 短评, .strip()去出评论两端的换⾏符
content = span.find('span','short').string.strip()
# 将评论中存在的换⾏符删除(替换为⽆空格符)
content = re.sub(r'\n','', content)
# 短评⽀持数
love_point = span.find('span','vote-count').string.strip()
arr =[times, name, level, content, love_point]
datas.append(arr)
df = pd.DataFrame(datas)
# print(arr)
return df
def get_nextUrl(html):
"""抓取下⼀个页⾯的 url"""
try:
# 到下⼀页的 url
url = html.find('a','next').attrs['href']
# print(url)
next_start = re.search(r'[0-9]\d{0,5}', url).group(0)
print("已经到 "+str(next_start)+" 了哦~, 客官稍等⼀会⼉\n")
next_url ="movie.douban/subject/35087699/comments?percent_type=" \
"&start={}&limit=20&status=P&sort=new_score&comments_only=1&ck=Cuyu".format(next_start) # print(next_url)
return next_url
except:
print("客官,已经没有短评数据了~ 欢迎下次再来哦~")
def save_data(data, fileName, Flag):
"""持久化存储数据"""
file_name = fileName +"_"+ time.strftime("%Y_%m_%d", time.localtime(time.time()))+".csv"
# print(file_name)
# 存储为csv格式⽂件
<_csv(file_name, index=False, header=Flag, mode='a', encoding="utf_8_sig")
# 检查是否保存成功,并打印提⽰⽂本
if ists(file_name):
print(file_name +" 数据爬取并保存成功!")
else:
print('数据保存失败,请再次尝试!')
if __name__ =="__main__":
"""程序⼊⼝"""
# 将要访问的Url
url ="movie.douban/subject/35087699/comments?percent_type=" \
"&start={}&limit=20&status=P&sort=new_score&comments_only=1&ck=Cuyu".format(0)
# 1.获取⽹页数据
html = get_html(url)
评价最高的电影# 2.抽取数据(时间,⽤户,星级,短评,⽀持数)
data = etl_data(html)
# 3.保存⾸页的数据
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论