【python数据分析实战】电影票房数据分析(一)数据采集

目录

  • 1、获取url
  • 2、开始采集
  • 3、存入mysql

本文是爬虫及可视化的练习项目,目标是爬取猫眼票房的全部数据并做可视化分析。

1、获取url

我们先打开猫眼票房http://piaofang.maoyan.com/dashboard?date=2019-10-22 ,查看当日票房信息,
但是在通过xpath对该url进行解析时发现获取不到数据。
于是按F12打开Chrome DevTool,按照如下步骤抓包

再打开获取到的url:http://pf.maoyan.com/second-box?beginDate=20191022

可以看到是json数据,并且url是以日期结尾的,也就是每日的票房数据都保存在对应日期的url中,这样我们就可以通过构造url来爬取每天的票房数据。

2、开始采集

先创建了两个函数,
一个用来获取制定年份的所有日期,例如,传入2019,返回[‘20190101‘, ‘20190102‘...‘20191230‘, ‘20191231‘]。
当然也可以传入多个年份的列表,如[2016,2017,2018‘],返回 [‘20160101‘,‘20160102‘, ...‘20170101‘,...‘20180101‘,...‘20181231‘]
这里没有使用任何库,用笨方法手动构造了全年的日期列表。

def get_calendar(years):
    """
    传入年份(可用list传入多个年份),得到年份中的所有日期
    :param years: 可传入list、int、str
    :return:  年份中全部日期的list,日期格式: "2019-09-30"
    """
    mmdd = []
    # 判断传入参数的格式,如果是list则排序,如果是str或int则转为list
    if isinstance(years, list):
        years.sort()
    else:
        years = [int(years)]

    # 先为每个月都加入31天,然后删掉2,4,6,9,11的31日和2月的30日,再判断闰年来删掉2月29日
    for year in years:
        for m in range(1, 13):
            for d in range(1, 32):
                mmdd.append(str(year) + str(m).zfill(2) + str(d).zfill(2))
        for i in [2, 4, 6, 9, 11]:
            mmdd.remove(str(year) + str(i).zfill(2) + "31")
        mmdd.remove(str(year) + "0230")
        if not calendar.isleap(year):
            mmdd.remove(str(year) + "0229")

    return mmdd

第二个函数很简单,传入上一个函数得到的日期列表,返回对应日期的url列表。

def get_urls(datas):
    """
    通过日历函数得到的每年全部日期,构造出全部日期的url
    :param datas: 全部日期
    :return: 全部url
    """
    urls = []
    for date in datas:
        url = "http://pf.maoyan.com/second-box?beginDate={}".format(date)
        urls.append(url)
    return urls

3、存入mysql

对于将数据存到mysql还是excel中,差别只在于写入的方法不同,前面对url的解析以及对数据的处理和获取都基本相同,
所以这里直接把存入mysql和存入excel写到了一个函数中,和后面的两个函数分别配合完成数据储存操作。

参数说明和判断储存方式在函数注释里写的很详细,这里简单说一下函数逻辑,
因json里的数据项很多,并且都以英文作为key,所有我们这里先手动创建要获取的数据项的中英文对照表,放到dict中,并根据这个dict来匹配主要的数据项。
最终返回一个由字典组成的list,返回的list其实没什么用,因为后面可视化的数据来源是直接通过sql取自mysql的,所以返回的list主要是调试时用着方便。


def get_movie_data(url, excel_or_db):
    """
    采集一个页面,并将数据写入excel或数据库,
    需要在函数外创建excel工作薄和工作表或连接好数据库,将worksheet或Connection类作为参数传入本函数
    如果传入的是worksheet类,函数会把数据保存到已创建excel中;
    如果传入的是Connection类,函数会把数据保存在已连接的数据库的movies_data表中,数据库表名手动在sql中调整,本函数内1处、get_data_save_db()函数内两处。
    :param url: 要采集的页面
    :param excel_or_db: openxl的worksheet类 或 pymysql的Connection类
    :return: 返回页面的全部数据
    """
    headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit'
                             '/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36'}
    main_key = {"avgSeatView": "上座率",
                "avgShowView": "场均人次",
                "boxInfo": "综合票房",
                "boxRate": "票房占比",
                "movieId": "影片ID",
                "movieName": "影片名称",
                "releaseInfo": "上映天数",
                "showInfo": "当日排片场次",
                "showRate": "排片占比",
                "sumBoxInfo": "综合票房总收入"}  # 用于数据分析的主要属性

    html = requests.get(url, headers=headers).text  # 获取页面信息,得到json对象
    result = json.loads(html, encoding="utf-8")  # 将json对象转为python对象

    main_data = []
    try:
        page_data = result["data"]["list"]  # 获取其中可用的数据部分,得到 [{电影1数据}, {电影2数据}, ...]
        if isinstance(excel_or_db, openpyxl.worksheet.worksheet.Worksheet):
            for dt in page_data:  # 对页面数据进行循环,匹配main_key中的主要属性,将数据放到main_data中,
                one_movie_data = {"日期": url[-8:]}  # 先把日期放入字典中
                for key in main_key.keys():
                    one_movie_data[main_key[key]] = dt[key]  # 将原数据的英文属性名,对照main_key转成中文
                excel_or_db.append(list(one_movie_data.values()))
                main_data.append(one_movie_data)

        elif isinstance(excel_or_db, pymysql.connections.Connection):
            for dt in page_data:  # 对页面数据进行循环,匹配main_key中的主要属性,将数据放到main_data中,
                one_movie_data = {"日期": url[-8:]}  # 先把日期放入字典中
                for key in main_key.keys():
                    one_movie_data[main_key[key]] = dt[key]  # 将原数据的英文属性名,对照main_key转成中文

                cursor = excel_or_db.cursor()
                sql_insert = '''insert into movies_data15 values(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s);'''
                cursor.execute(sql_insert, list(one_movie_data.values()))
                excel_or_db.commit()
                cursor.close()
                main_data.append(one_movie_data)
    except:
        pass

    return main_data

因为目标网站数据量较大,为了测试方便,这里写了个函数来限制采集数量:达到设定值则结束采集。

def go_limit(year, *, ws, max_line=float("inf")):  # float("inf")为无穷大
    """
    测试时用于限制爬取条数
    :return:
    """
    num = 1
    for url in get_urls(get_calendar(year)):
        if num <= max_line:
            print(num, get_movie_data(url, ws))
            time.sleep(1)
            num += 1
        else:
            break

下面是写入excel和写入mysql的函数,写成函数主要是为了看着简洁。

def get_data_and_save_excel():
    tittles = ['日期', '上座率', '场均人次', '综合票房', '票房占比', '影片ID', '影片名称', '上映天数', '当日排片场次', '排片占比', '综合票房总收入']
    workbook = openpyxl.Workbook()  # 创建工作簿
    worsheet = workbook.active  # 获取活跃工作表,即当前默认工作表
    worsheet.append(tittles)

    print(go_limit(2011, ws=worsheet, max_line=20)) # 限制输出行数,用于测试

    # 配置列宽
    for index in range(1, len(tittles) + 1):    # 将所有列列宽均设为20
        worsheet.column_dimensions[get_column_letter(index)].width = 20
    workbook.save("data.xlsx")

连接数据库,开始采集,写入数据库
这个函数里有一个逻辑错误,能找到问题的小伙伴可以在留言里指出。
还有就是sql里边包含表名称,本函数、get_movie_data()采集函数、以及后面的可视化函数,都用到相同的表名称,如有变动要分别修改,很麻烦,
如果把表名称作为参数传递也很麻烦,每个函数都要传一次,
可以把表名称作为全局变量,用外部耦合解决,用增加耦合度来换省事。

def get_data_save_db(years):
    """
    数据库表名需要手动在sql中调整,本函数内2处,get_movie_data()函数内1处,3处表名需要保持一致。
    """
    config = {'host': 'localhost',
              'port': 3306,
              'user': '***',
              'password': '***',
              'database': '***',
              'charset': 'utf8'}
    conn = pymysql.connect(**config)  # **config是将config字典拆开传入
    cursor = conn.cursor()
    sql_check = '''drop table if exists movies_data15;'''  # 判断movies_data表是否存在,存在则drop
    sql_create = '''create table movies_data15(date varchar(8),
                                        avgSeatView varchar(8),
                                        avgShowView varchar(8),
                                        boxInfo varchar(10),
                                        boxRate varchar(8),
                                        movieId varchar(10),
                                        movieName varchar(30),
                                        releaseInfo varchar(8),
                                        showInfo varchar(8),
                                        showRate varchar(8),
                                        sumBoxInfo varchar(8),
                                        primary key (date, movieID)) DEFAULT CHARSET=utf8;'''  # 创建movies_data表
    cursor.execute(sql_check)
    cursor.execute(sql_create)
    conn.commit()
    cursor.close()
    print(go_limit(years, ws=conn))
    # print(get_movie_data('http://pf.maoyan.com/second-box?beginDate=20110403', conn))
    conn.close()

get_data_save_db([i for i in range(2011,2020)])    # 采集2011年至今的所有数据

至此电影票房的数据采集工作已完成,接下来要进行数据可视化,
请看《【python数据分析实战】电影票房数据分析(二)数据可视化》

原文地址:https://www.cnblogs.com/cbowen/p/11725859.html

时间: 2024-10-07 16:16:38

【python数据分析实战】电影票房数据分析(一)数据采集的相关文章

【python数据分析实战】电影票房数据分析(二)数据可视化

目录 图1 每年的月票房走势图 图2 年票房总值.上映影片总数及观影人次 图3 单片总票房及日均票房 图4 单片票房及上映月份关系图 在上一部分<[python数据分析实战]电影票房数据分析(一)数据采集> 已经获取到了2011年至今的票房数据,并保存在了mysql中. 本文将在实操中讲解如何将mysql中的数据抽取出来并做成动态可视化. 图1 每年的月票房走势图 第一张图,我们要看一下每月的票房走势,毫无疑问要做成折线图,将近10年的票房数据放在一张图上展示. 数据抽取: 采集到的票房数据是

下载大数据实战课程第一季Python基础和网络爬虫数据分析

python语言近年来越来越被程序相关人员喜欢和使用,因为其不仅简单容易学习和掌握,而且还有丰富的第三方程序库和相应完善的管理工具:从命令行脚本程序到gui程序,从B/S到C/S,从图形技术到科学计算,软件开发到自动化测试,从云计算到虚拟化,所有这些领域都有python的身影:python已经深入到程序开发的各个领域,并且会越来越多的人学习和使用. 大数据实战课程第一季Python基础和网络爬虫数据分析,刚刚入手,转一注册文件,视频的确不错,可以先下载看看:链接:http://pan.baidu

大数据(实战型)数据分析专家、首席分析师高级视频教程

38套大数据,云计算,架构,数据分析师,Hadoop,Spark,Storm,Kafka,人工智能,机器学习,深度学习,项目实战视频教程 视频课程包含: 38套大数据和人工智能精品高级课包含:大数据,云计算,架构,数据挖掘实战,实时推荐系统实战,电视收视率项目实战,实时流统计项目实战,离线电商分析项目实战,Spark大型项目实战用户分析,智能客户系统项目实战,Linux基础,Hadoop,Spark,Storm,Docker,Mapreduce,Kafka,Flume,OpenStack,Hiv

R语言速成实战 R语言数据分析实战

详情请交流  QQ  709639943 00.R语言速成实战 00.R语言数据分析实战 00.Python+Django+Ansible Playbook自动化运维项目实战 00.Java深入微服务原理改造房产销售平台 00.Python3入门机器学习 经典算法与应用 00.老司机学python篇:第一季(基础速过.机器学习入门) 00.Python 从入门到精通 78节.2000多分钟.36小时的高质量.精品.1080P高清视频教程!包括标准库.socket网络编程.多线程.多进程和协程.

Python3实战Spark大数据分析及调度 (网盘分享)

Python3实战Spark大数据分析及调度 搜索QQ号直接加群获取其它学习资料:517432778 部分课程截图: 链接:https://pan.baidu.com/s/1YMmswv47fOUlt-z2A6691A 提取码:z5xv PS:免费分享,若点击链接无法获取到资料,若如若链接失效请加群 其它资源在群里,私聊管理员即可免费领取:群——517432778,点击加群,或扫描二维码   第1章 课程介绍 课程介绍 1-1 PySpark导学试看 1-2 OOTB环境演示 第2章 实战环境搭

数据分析实战

Edit 数据分析实战 数据准备 数据类型 数据结构 Series DataFrame数据框 向量化运算 数据处理 数据导入 导入CSV文件 导入文本文件 导入Excel文件 数据导出 导出文本文件 重复值处理 缺失值处理 空格值处理 字段抽取 字段拆分 记录抽取 随机抽样 记录合并 字段合并 字段匹配 简单计算 数据标准化 数据分组 时间处理 时间抽取 虚拟变量 dummy variables 数据分析 基本统计 分组分析 分布分析 交叉分析 结构分析 相关分析 RFM分析 矩阵分析 数据可视

python实现的、带GUI界面电影票房数据可视化程序

代码地址如下:http://www.demodashi.com/demo/14588.html 详细说明: Tushare是一个免费.开源的python财经数据接口包.主要实现对股票等金融数据从数据采集.清洗加工 到 数据存储的过程,能够为金融分析人员提供快速.整洁.和多样的便于分析的数据. 完成本项目后,可以进一步通过类似的方法实现股票数据的可视化操作. (代码在python2.7或python3.6下均能正常运行,已在以下环境中进行过测试: python2.7 + tushare0.9.8

Python 数据可视化工具以及数据分析开发架构

Python 数据可视化进阶 Python数据可视化教程:基于 plotly 动态可视化绘图 ?https://edu.51cto.com/sd/4bff8 ? Python数据可视化教程 Seaborn ?https://edu.51cto.com/sd/19627 Python 数据分析实战 视频课程https://edu.51cto.com/sd/63225 Python数据可视化: pyecharts实战 ????? pyecharts 是一个用于生成 Echarts 图表的类库.Ech

Python爬虫实战(4):豆瓣小组话题数据采集—动态网页

1, 引言 注释:上一篇<Python爬虫实战(3):安居客房产经纪人信息采集>,访问的网页是静态网页,有朋友模仿那个实战来采集动态加载豆瓣小组的网页,结果不成功.本篇是针对动态网页的数据采集编程实战. Python开源网络爬虫项目启动之初,我们就把网络爬虫分成两类:即时爬虫和收割式网络爬虫.为了适应各种应用场景,GooSeeker的整个网络爬虫产品线包含了四类产品,如下图所示: 本实战是上图中的"独立python爬虫"的一个实例,以采集豆瓣小组讨论话题(https://w