python爬虫+数据分析完整流程--豆瓣电影分类排行榜

整体思路:利用requests,BeautifulSoup爬虫豆瓣电影分类排行榜数据;数据输出到本地csv文件;构建mongodb数据库,将数据存放入mongodb;利用pandas,matplotlib画图分析数据。

1.利用BeautifulSoup爬虫豆瓣电影分类排行榜数据

第一步:分析url规律,不同的电影分类对应url循环代入requests和BeautifulSoup中解析,再分析解析到的网站结构,提取想要的信息

获取电影分类的网页,传入函数douban中

python爬虫+数据分析完整流程--豆瓣电影分类排行榜_第1张图片

分析网站结构,提取信息,并存放到对应的列表中

python爬虫+数据分析完整流程--豆瓣电影分类排行榜_第2张图片

**这里踩了一个坑是for循环的范围,后来通过print S2列表发现长度不一,所以这里改成了range(len(s2))严谨一点(ip被封过一次,所以这里在请求头后面还加上了代理ip)

 **由于电影类别不止一个,这里想把它们都放到dataframe中的同一列,所以用了.join合并。

2.数据输出到本地csv文件

3.文件保存mongodb数据库

4.画图数据分析

 python爬虫+数据分析完整流程--豆瓣电影分类排行榜_第3张图片

 **这里由于某些电影是多个国家共同出品,国家这个列表的元素中可能还嵌入了列表,导致报错:列表类型不可哈希,为了程序简练一点,这里我直接取了电影国家的第一个元素,由于plot函数的x,y的维度需要一致,在x轴国家那里构造了集合与列表的嵌套样式。

调试最久的地方是在mean()函数那里,由于评分之前没有定义字符类型,导致评分的‘9.7’等元素的类型为‘str’,非数字类型,describe()函数中没有平均值属性

源代码如下

python源代码

import requests
from bs4 import BeautifulSoup
import json
import pandas as pd
import pymongo
import matplotlib.pyplot as plt
title_list=[]
lianjie_list=[]
rank_list=[]
leibie_list=[]
s2_list=[]
pingfen_list=[]
didian_list=[]
actors_list=[]
sum=0
#解析网页
headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36 Edg/90.0.818.66'}
def douban(urls):#针对不同分类不同链接,创建爬虫函数
    response=requests.get(urls,headers=headers,proxies={'http':'http://47.100.207.26:8080'})#获取网页
    soup=BeautifulSoup(response.text,'lxml')#解析网页
    s=soup.get_text()#去除网页标签,s为字符串格式,所以用json.loads变成python对象中的list
    s2=json.loads(s)#格式化,字符串格式变成集合格式list,方便提取数据
    s2_list.append(len(s2))
    for j in range(len(s2)):#循环处理集合元素中的信息
        s3=s2[j]#提取集合的第i个元素,此集合中的元素本质为字典
        title=s3.get('title')#提取电影题目
        title_list.append(title)
        rank=int(s3.get('rank'))#提取电影排名
        rank_list.append(rank)
        lianjie=s3.get('url')#提取电影链接
        lianjie_list.append(lianjie)
        leibie=s3.get('types')#提取电影类型
        leibie=''.join(leibie)
        leibie_list.append(leibie)
        pingfen=float(s3.get('rating')[0])#提取电影评分
        pingfen_list.append(pingfen)
        didian=s3.get('regions')[0]#提取电影国家,有的电影存在多个制作地点,为了方便后面plot,取第一个地点
        didian_list.append(didian)
        actors=s3.get('actors')#提取电影主演
        actors=''.join(actors)
        actors_list.append(actors)
for i in range(1,32):
    if i==31:
        urls='https://movie.douban.com/j/chart/top_list?type=31&interval_id=100%3A90&action=&start=0&limit=11'
    else:
        urls = 'https://movie.douban.com/j/chart/top_list?type={}&interval_id=100%3A90&action=&start=0&limit=50'.format(i)  # 观察豆瓣链接格式的编码规则,创建爬虫
    douban(urls)
dict={'题目':title_list,'分类排名':rank_list,'链接':lianjie_list,'电影类别':leibie_list,'评分':pingfen_list,'国家':didian_list,'演员':actors_list}
dt=pd.DataFrame(dict)#变成dataframe
dt.to_csv(r'C:\Users\asus\Desktop\douban.csv',mode='a')#导出到本地表格
for k in range(len(s2_list)):
    sum+=s2_list[k]
print('总条数:',sum)#记录抓取条数
#导入mongodb数据库
client=pymongo.MongoClient('mongodb://localhost:27017/')#链接mongodb数据库
db=client['dianying']#创建数据库dianying
db.collection.insert_one(dict)#数据库中插入字典型数据dict
#plot函数画图
print(list(set(dt['国家'])))
plt.plot(list(set(dt['国家'])),dt['评分'].groupby(dt['国家']).mean())
plt.title('各国电影评分')
plt.xlabel('国家分类')
plt.ylabel('评分')
plt.show()
print('运行完成')

你可能感兴趣的:(python,爬虫,数据分析,mongodb)