电影Top25数据分析
先去打开目标网页进行抓包分析:
目标网址:
https://movie.douban.com/top250?0&filter=
浏览器抓包分析
导入库:
import pandas as pd
import requests
from bs4 import BeautifulSoup
from matplotlib import pyplot as plt
完整代码如下:
import pandas as pd
import requests
from bs4 import BeautifulSoup
from matplotlib import pyplot as plt
'''
目的是爬取'电影排名','电影名','上映时间','导演','主演','电影类型','电影评分','评价人数','电影链接'
'''
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/92.0.4515.107 Safari/537.36 Edg/92.0.902.55'} # 用header伪装成浏览器访问而不是Python访问,这样能让网站接入
url1 = [] # 所有电影的URL
url = 'https://movie.douban.com/top250?0&filter=' # 每一个电影相当于有一个网站,把每个网址存在url1这个列表里面
print('正在处理url:', url)
response = requests.get(url=url, headers=headers) # 接入网址
soup = BeautifulSoup(response.text,
'html.parser') # BeautifulSoup是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式
url_mv_list = soup.select('#content > div > div.article > ol > li > div > div.info > div.hd > a') # 筛选元素的a标签,css语法
for index_url in range(len(url_mv_list)):
url_mv = url_mv_list[index_url]['href']
url1.append(url_mv)
def loading_mv(url, number): # 函数,爬取所有的电影信息
list_mv = [number + 1] # 存储电影信息
# 解析网页
response_mv = requests.get(url=url, headers=headers)
soup_mv = BeautifulSoup(response_mv.text, 'html.parser')
# 爬取电影名
mv_name = soup_mv.find_all('span', attrs={'property': 'v:itemreviewed'}) # 电影名
mv_name = mv_name[0].get_text() # 解析出名字,get_text
list_mv.append(mv_name) # 电影信息列表加入名字
# print(mv_name)
# 爬取电影的上映时间
mv_year = soup_mv.select('span.year') # 电影上映时间
mv_year = mv_year[0].get_text()[1:5] # 解析出上映时间
list_mv.append(mv_year) # 添加电影的年份
# print(mv_year)
# 爬取导演信息
list_mv_director = [] # 导演
mv_director = soup_mv.find_all('a', attrs={'rel': "v:directedBy"})
for director in mv_director:
list_mv_director.append(director.get_text())
string_director = '/'.join(list_mv_director) # 重新定义格式
list_mv.append(string_director)
# print(list_mv_director)
# 爬取主演信息
list_mv_star = [] # 主演
mv_star = soup_mv.find_all('span', attrs={'class': 'actor'})
mv_star = mv_star[0].get_text().strip().split('/')
mv_first_star = mv_star[0].split(':')
list_mv_star.append(mv_first_star[-1].strip())
del mv_star[0] # 去除'主演'字段
for star in mv_star:
list_mv_star.append(star.strip())
string = '/'.join(list_mv_star) # 重新定义格式
list_mv.append(string)
# 爬取电影类型
list_mv_type = [] # 电影类型
mv_type = soup_mv.find_all('span', attrs={'property': 'v:genre'})
for type in mv_type:
list_mv_type.append(type.get_text())
string_type = '/'.join(list_mv_type)
list_mv.append(string_type)
# print(list_mv_type)
# 爬取电影评分
mv_score = soup_mv.select('strong.ll.rating_num') # 评分
mv_score = mv_score[0].get_text()
list_mv.append(mv_score)
# 爬取评价人数
mv_evaluation_num = soup_mv.select('a.rating_people') # 评价人数
mv_evaluation_num = mv_evaluation_num[0].get_text().strip()
list_mv.append(mv_evaluation_num)
# 爬取剧情简介
mv_plot = soup_mv.find_all('span', attrs={"class": "all hidden"}) # 剧情简介
if mv_plot == []:
list_mv.append(None)
else:
string_plot = mv_plot[0].get_text().strip().split()
new_string_plot = ' '.join(string_plot)
list_mv.append(new_string_plot)
# 加入电影网址
list_mv.append(url)
return list_mv
list_all = []
dict_mv_info = {}
for number in range(len(url1)):
mv_info = loading_mv(url1[number], number)
list_all.append(mv_info)
df = pd.DataFrame(list_all, columns=['电影排名', '电影名', '上映时间', '导演', '主演', '电影类型', '电影评分', '评价人数', '电影简介', '电影链接'])
# 电影类型柱状图统计
df.to_excel(r'豆瓣电影Top25.xlsx')
y = df['电影类型']
dict_type = {}
for type in y:
line = type.split('/')
for t in line:
dict_type[t] = dict_type.get(t, 0) + 1
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.xticks(rotation=30)
plt.subplot(2, 1, 1)
plt.bar(dict_type.keys(), dict_type.values(), color='g')
plt.xlabel('类型', fontdict={'family': 'SimSun', 'color': 'black', 'size': 10}, labelpad=20)
plt.ylabel('个数', fontdict={'family': 'SimSun', 'color': 'black', 'size': 10}, labelpad=20)
plt.title(label='排行前25电影类型直方图', fontdict={'family': 'KaiTi', 'color': 'red', 'size': 10}, loc='center')
# 电影主演折线图统计
z = df['导演']
dict_actor = {}
for dir in z:
line = dir.split('/')
for t in line:
dict_actor[t] = dict_actor.get(t, 0) + 1
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.subplot(2, 1, 2)
plt.plot(dict_actor.keys(), dict_actor.values(), color='g')
plt.title(label='排行前25电影主演折线图', fontdict={'family': 'KaiTi', 'color': 'red', 'size': 10}, loc='center')
plt.xticks(rotation=290)
plt.xlabel('导演', fontdict={'family': 'SimSun', 'color': 'black', 'size': 10}, labelpad=20)
plt.ylabel('个数', fontdict={'family': 'SimSun', 'color': 'black', 'size': 10}, labelpad=20)
plt.tight_layout()
plt.show()
运行效果
第一次运行可以出结果,如果后面运行不行就是ip被封了,换ip,用ip代理池也行,
或者把里面数据分析出图的代码单独拿出来运行也行,因为ip第一次请求会请求爬取到数据,后面次数多了就不行了。