1:先查看豆瓣的官网

 

 2:按f12进行解析,分析

 

 3::实现对豆瓣top250的影片信息爬取

 

 4: 建立Mongodb连接,用于数据保存

 

 

 5:抓取top250电影的上映时间、国家、评分、类型、评价人数

 

def get_movie_list(url,headers):

    # 实例化soup对象, 便于处理

    soup = requests.get(url,headers=headers) #向网站发起请求,并获取响应对象

    response = BeautifulSoup(soup.text,'lxml')#利用xml html解析器,具有容错功能

    lists = response.select('div.info')

    #循环获取信息

    for list in lists:

        #获取链接, 也就是获取a链接中href对应的值;

        sing_url =list.select('a')[0].get('href')

        #获取影片名称

        name =list.select('div.hd .title')[0].text

        #导演及主演

        type_list = list.select('div.bd p')[0].text.strip('').split('...')[-1].replace(' ','').split('/')

        #上映时间

        year =type_list[0]

        #国家

        country = type_list[1]

        #影片所属类别

        category = type_list[2]

        #获取影片评分

        star = list.select('div.bd .star .rating_num')[0].text.replace(' ','')

        #获取引述

        quote =list.select('div.bd .quote')[0].text

        #获取评论人数

        people_num = list.select('div.bd .star span:nth-of-type(4)')[0].text.split('')[0]

        get_detail_movie(sing_url,name,year,country,category,star,quote,people_num,headers)

6: 抓取top250电影的执导导演、参演演员,并保存数据到mongodb中

 

 7:我们将获取到影片信息数据保存到数据库中,以便后面对数据的分析,效果如下:

 

 8:Top250影片华语电影类型数量

 

 

 

 

 

 9:对爬取到的信息进行分类整理,统计作品数前10的导演,以及数据可视化

 

 10:统计作品数前10导演

 

 11:绘制柱状图

 

 

 

12:2000年上映影片类型比重

1)统计和提取2000年上映影片数量类型与华语上映电影类型相同,

2)绘制环形图

 

 

 

13:作品与评分折线图

 

 

 

import time
import pandas as pd
import matplotlib.pyplot as plt

from pip._vendor import requests
from pip._vendor.progress.bar import Bar
from pip._vendor.progress.counter import Pie

if __name__=='main':
    for i in range(0,10):
        num = str(i*25)
        url = 'https://move.douban.com/top250?start{}&filter='.format(num)
        time.sleep(2)
        get_move_list(url,headers)


class BeautifulSoup(object):
    pass


item_info = []

def get_movie_list(url,headers):

    # 实例化soup对象, 便于处理

    soup = requests.get(url,headers=headers) #向网站发起请求,并获取响应对象

    response = BeautifulSoup(soup.text,'lxml')#利用xml html解析器,具有容错功能

    lists = response.select('div.info')

    #循环获取信息

    for list in lists:

        #获取链接, 也就是获取a链接中href对应的值;

        sing_url =list.select('a')[0].get('href')

        #获取影片名称

        name =list.select('div.hd .title')[0].text

        #导演及主演

        type_list = list.select('div.bd p')[0].text.strip('').split('...')[-1].replace(' ','').split('/')

        #上映时间

        year =type_list[0]

        #国家

        country = type_list[1]

        #影片所属类别

        category = type_list[2]

        #获取影片评分

        star = list.select('div.bd .star .rating_num')[0].text.replace(' ','')

        #获取引述

        quote =list.select('div.bd .quote')[0].text

        #获取评论人数

        people_num = list.select('div.bd .star span:nth-of-type(4)')[0].text.split('')[0]

        get_detail_movie(sing_url,name,year,country,category,star,quote,people_num,headers)

def get_detail_movie(movie_url,name,year,country,category,star,quote,people_num,headers):
    response = requests.get(movie_url,headers = headers)
    soup = BeautifulSoup(response.text,'lxml')
    daoyan = soup.select('#info > span:nth-of-type(1) > span.attrs')[0].text
    yanyuan =[]
    for i in soup.select('#info > span.actor > span.attrs '):
        yanyuan.append(i.text.replace('/',' '))

    list1 = str(yanyuan).respace('[','').respace(']','').split(' ')
    yanyuan =  list1
    data = {'name':name,
            'year':year,
            'country':category,
            'star':star,
            'quote':quote,
            'people_num':people_num,
            'daoyan':daoyan,
            'yanyuan':yanyuan
            }
    print(data)

def pie_chart():


    chinese_list = []
    for i in item_info.find():
        if '中国大陆' in i['country']:
    chinese_list.append(str(i).strip('\xa0'))
    a = str(i['category'].strip('\n').strip(' '))
    chinese_list.append(a)
    print(str(i['category']).strip(('\n').strip(' ')))
    list1 = ['爱情', '犯罪', '悬疑', '动画', '剧情', '战争', '喜剧', '动作']
    count_list = []

    for j in range(0, 8):
        count = 0
    for i in chinese_list:
        if str(list1[j]) in i:
            count += 1
    count_list.append(count)

    c = (Pie().add("",
                   [list(z) for z in zip(list1, count_list)],
                   center=["55%", "50%"])
         .set_global_opts(
        title_opts=opts.TitleOpts(title="豆瓣top250电影中华语电影类型数量占比", pos_left="30%"),
        legend_opts=opts.LegendOpts(pos_buttom='0'))
         .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{c}")
                          )).c.render('chinese.html')



def daoyan():
    daoyan_list = []
    for i in item_info.find():
        print(i['daoyan'])
        if '/' in str(i['daoyan']):
            a = str(i['daoyan']).split('/')
            daoyan_list.append(a[0])
            daoyan_list.append(a[1])
        else:
            daoyan_list.append(i['daoyan'])
    daoyan_list1 = list(set(daoyan_list))

    count_list = []  #count_list:统计所有导演作品数
    daoyan_dict = {}

    for i in daoyan_list1:
        count_list.append(daoyan_list.count(i))
        daoyan_dict[str(i).strip(' ')] = daoyan_list.count(i)
    print(count_list)
    print(daoyan_dict)
    daoyan_dict1 = sorted(daoyan_dict.items(),key=lambda item:item[1],reverse=True)
    print(daoyan_dict1)
    daoyan_list2 = []  #daoyan_list2:前十名导演
    count_list2 = []    #count_list2:  前十导演作品数量

    for i in daoyan_dict1:
        daoyan_list2.append(i[0])
        daoyan_list2.append(i[1])


    bar = (
        Bar(init_opts=opts.InitOps(theme=ThemeType.LIGHT,width="900px",height='600px'))
        .add_xaxis([a for  a in daoyan_list2[:15]])
        .add_yaxis('导演作品数量',[a for a in count_list2[:15]],category='60%',color=range(1,10))
        .set_series_opts(label_opts=opts.LabelOpts(font_size=12))
        .set_global_opts(xaxis_opts=opts.AxisOpts(axislabel_opts=opt.LabelOpts(rotate=60,font_size=12,)),
                         title_opts=opts.TitleOpts(title))
    )
    bar.render('top10导演.html')

    num = count_list
    c = (
        Pie()
        .add(
            "",
            [list(z) for z in zip(list1,num)],
            radius = ["40%","75%"],
        )
        .set_global_opts(
            title_opts = opts.TitleOpts(title="2000年上映电影类型数量",pos_left="30%"),
            legend_opts = opts.LabelOpts(
                orient = "vertical",pos_top = "5%",pos_left="2%"
            )
        )
        .set_series_opts(label_opts=opts.LabelOpts.LabelOpts(formatter="{b}:{c}"))
    )
    c.render("2000年上映电影的数量.html")

    tb = pd.read_csv("douban.csv",encoding='utf-8')
    plt.rcParam['font.sans-serif'] = ['SimHei']
    plt.figure(figsize=(10,5),dpi=80)

    plt.style.use('ggplot')
    plt.plot(tb["name"],tb["star"],label='评分')
    plt.title("top250影片作品评分折线")
    plt.xlabel("影片名")
    plt.ylabel("评分")

    for a,b in zip(tb["name"],tb["star"]):
        plt.text(a,b,b,ha="center",va="bottom",fontsize=10)
    plt.legend()
    plt.grid(True)
    plt.savefig("top250影片作品评分折线")
    plt.show()

总结:

特点:利用不同的技术,实现爬取,数据保存,数据可视化。使用mongodb存放数据,利用pyecharts包实现数据可视化。使用 render() 渲染生成html文件后,创建index文件将所有渲染的html文件进行连接。

不足:

1.爬取数据数量有限。
2.数据量大,爬取速度慢。

3:打代码的速度太慢了,不熟练,经常会出现错误。有时会出现bug,然后要通过长时间的研究才能解决。

收获:

1:通过这次的python爬虫可视化,对于python有了更加深刻的了解

2:通过写项目,能够更加清楚整个项目的结构,和流程,对于以后的工作帮助非常的大。

posted on 2020-07-26 14:01  .Stewart  阅读(392)  评论(0)    收藏  举报