Python爬取猫眼实时票房数据

  • A+
所属分类:网络爬虫
摘要

今天《复仇者联盟3:无限战争》在内地首映,但它早在半个月前就已经在其它国家上映了,并且成为全球最快破十亿美元的影片,IMDb 8.9高分,豆瓣评分 8.9分,看这架势内地3天12亿很正常。

猫眼实时票房数据可以在这查看:https://piaofang.maoyan.com/dashboard

要获取这些票房数据,直接请求上面这个 url 是无法获取到的,因为这些数据是通过 Ajax 异步加载进来的,需要从 Ajax 相关文件提取所需要的数据,如:某部电影的今日票房、票房占比、排片、排片占比、上映天数等。

在开发者工具中可以看到网页不断地接收到 second.json 这个文件,其实这个 json 文件就包含有票房数据,也就是数据接口: https://box.maoyan.com/promovie/api/box/second.json

一些基本信息在 data 这个字段,如 totalBoxtotalBoxUnit 是今日总票房及其单位(万),带有 split 关键字开头的都是分账数据

而具体每一部电影的详细信息则在 list 这个字段的子字段中,0 字段是今天票房排第一名的电影详细数据,如

  • movieName: 电影名称
  • boxInfo: 票房
  • boxRate: 票房占比
  • avgSeatView: 场均上座率
  • avgShowView: 场均人次
  • avgViewBox: 平均票价
  • releaseInfo: 上映天数
  • showInfo: 排片场次
  • showRate: 排片占比
  • sumBoxInfo: 总票房

思路

  • 请求接口。经过观察可以发现页面每隔 4 秒发送一次请求,所以可以构建一个死循环,每隔 4 秒(或以上)发送一次请求即可,然后 json() 方法将 response 以 dict 类型返回
  • 提取数据。利用 dict 对象的 get() 方法提取字段值
  • 输出控制台。以制表符 \t 作为字段间的分隔符,并且固定一些数据(字符串)的长度,以保证输出可以对齐
  • 清屏。使用了 os 模块的 system() 方法,传入命令行的清屏命令字符串,如 Win 下是 cls,Linux下是 clear

代码

以下代码还有很多需要改进优化的地方,只供参考。

 

  1. import os
  2. import time
  3. import requests
  4. class maoyan():
  5.     def __init__(self):
  6.         self.headers = {
  7.             'Host': 'piaofang.maoyan.com',
  8.             'Referer': 'https://piaofang.maoyan.com/dashboard',
  9.             'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER',
  10.             'X-Requested-With': 'XMLHttpRequest'
  11.         }
  12.     def get_page(self):
  13.         url = 'https://box.maoyan.com/promovie/api/box/second.json'
  14.         try:
  15.             response = requests.get(url, self.headers)
  16.             if response.status_code == 200:
  17.                 return response.json()
  18.         except requests.ConnectionError as e:
  19.             print('Error', e.args)
  20.     def parse_page(self, json):
  21.         if json:
  22.             data = json.get('data')
  23.             for index, item in enumerate(data.get('list')):
  24.                 self.piaofang = {}
  25.                 # 场均上座率
  26.                 self.piaofang['avgSeatView'] = item.get('avgSeatView')
  27.                 # 场均人次
  28.                 self.piaofang['avgShowView'] = item.get('avgShowView')
  29.                 # 平均票价
  30.                 self.piaofang['avgViewBox'] = item.get('avgViewBox')
  31.                 # 票房
  32.                 self.piaofang['boxInfo'] = item.get('boxInfo')
  33.                 # 票房占比
  34.                 self.piaofang['boxRate'] = item.get('boxRate')
  35.                 # 电影名称
  36.                 self.piaofang['movieName'] = item.get('movieName')
  37.                 # 上映天数
  38.                 self.piaofang['releaseInfo'] = item.get('releaseInfo')
  39.                 # 排片场次
  40.                 self.piaofang['showInfo'] = item.get('showInfo')
  41.                 # 排片占比
  42.                 self.piaofang['showRate'] = item.get('showRate')
  43.                 # 总票房
  44.                 self.piaofang['sumBoxInfo'] = item.get('sumBoxInfo')
  45.                 yield self.piaofang
  46. if __name__ == "__main__":
  47.     while True:
  48.         my = maoyan()
  49.         json = my.get_page()
  50.         results = my.parse_page(json)
  51.         os.system('cls')
  52.         print(json.get('data')['updateInfo'])
  53.         print('今日总票房: %s' % json.get('data')['totalBox']+json.get('data')['totalBoxUnit'])
  54.         x_line = '-' * 155
  55.         print(x_line)
  56.         print('电影名称\t综合票房(万)\t票房占比\t场均上座率\t场均人次\t平均票价\t排片场次\t排片占比\t累积总票房\t上映天数')
  57.         print(x_line)
  58.         for result in results:
  59.             print(
  60.                 result['movieName'][:7].ljust(8) + '\t' +
  61.                 result['boxInfo'][:8].rjust(8) + '\t' +
  62.                 result['boxRate'][:8].rjust(8) + '\t' +
  63.                 result['avgSeatView'][:8].rjust(8) + '\t' +
  64.                 result['avgShowView'][:8].rjust(8) + '\t' +
  65.                 result['avgViewBox'][:8].rjust(8) + '\t' +
  66.                 result['showInfo'][:8].rjust(8) + '\t' +
  67.                 result['showRate'][:8].rjust(8) + '\t' +
  68.                 result['sumBoxInfo'][:8].rjust(8) + '\t' +
  69.                 result['releaseInfo'][:8] +
  70.                 '\n'
  71.                 )
  72.         time.sleep(4)

来源:display3D(微信ID:display3D)

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

目前评论:1   其中:访客  0   博主  1

    • pydata pydata Admin

      原文链接:https://zhuanlan.zhihu.com/p/36748808