分析

由于时光网中电影的票房、排名等大部分信息是通过Ajax异步加载的,所以,使用常规的静态网站抓取技术,
无法获取到这些信息。

要获取这些信息,必须从Ajax请求中查找。

先点开一个正在上映的电影 《前任3》
首先,找到是哪个Ajax请求用于获取这些信息

发现,以下url返回了所需要的数据

Ajax请求URL

http://service.library.mtime.com/Movie.api?Ajax_CallBack=true&Ajax_CallBackType=Mtime.Library.Services&Ajax_CallBackMethod=GetMovieOverviewRating&Ajax_CrossDomain=1&Ajax_RequestUrl=http%3A%2F%2Fmovie.mtime.com%2F230788%2F&t=201811115619396&Ajax_CallBackArgument0=230788

Ajax响应数据

var result_201811115619396 = { "value":{"isRelease":true,"movieRating":{"MovieId":230788,"RatingFinal":6.6,"RDirectorFinal":6.6,"ROtherFinal":6.9,"RPictureFinal":6.6,"RShowFinal":0,"RStoryFinal":6.4,"RTotalFinal":0,"Usercount":2209,"AttitudeCount":2184,"UserId":0,"EnterTime":0,"JustTotal":0,"RatingCount":0,"TitleCn":"","TitleEn":"","Year":"","IP":0},"movieTitle":"前任3:再见前任","tweetId":0,"userLastComment":"","userLastCommentUrl":"","releaseType":1,"boxOffice":{"Rank":1,"TotalBoxOffice":"15.60","TotalBoxOfficeUnit":"亿","TodayBoxOffice":"2151.1","TodayBoxOfficeUnit":"万","ShowDays":14,"EndDate":"2018-01-11 15:10","FirstDayBoxOffice":"6413.11","FirstDayBoxOfficeUnit":"万"},"hotValue":{"MovieId":230788,"Ranking":38,"Changing":8,"YesterdayRanking":46}},"error":null};var movieOverviewRatingResult=result_201811115619396;

再看一个即将上映的电影《大寒》
同样的方法,找到Ajax请求URL

http://service.library.mtime.com/Movie.api?Ajax_CallBack=true&Ajax_CallBackType=Mtime.Library.Services&Ajax_CallBackMethod=GetMovieOverviewRating&Ajax_CrossDomain=1&Ajax_RequestUrl=http%3A%2F%2Fmovie.mtime.com%2F233735%2F&t=20181111604467678&Ajax_CallBackArgument0=233735

Ajax响应数据

var result_20181111604467678 = { "value":{"isRelease":true,"movieRating":{"MovieId":233735,"RatingFinal":-1,"RDirectorFinal":0,"ROtherFinal":0,"RPictureFinal":0,"RShowFinal":0,"RStoryFinal":0,"RTotalFinal":0,"Usercount":1,"AttitudeCount":11,"UserId":0,"EnterTime":0,"JustTotal":0,"RatingCount":0,"TitleCn":"","TitleEn":"","Year":"","IP":0},"movieTitle":"大寒","tweetId":0,"userLastComment":"","userLastCommentUrl":"","releaseType":2},"error":null};var movieOverviewRatingResult=result_20181111604467678;

接下来要做2件事:

1.构造Ajax请求URL

比较刚才找到的2个Ajax URL,发现,不同电影只有最后三个参数是不同的,其它都一样:
Ajax_RequestUrl 是当前电影页面的URL
t 是当前时间字符串,由年月日时分秒,接着是4个任意数字,例如20181111604460000
Ajax_CallBackArgument0 是电影id,可以从当前页面的URL中截取

2.从Ajax响应中提取票房、排行等数据

观察目标数据。发现等号 = 和第一个分号 ; 之间的数据为标准json格式。所以,可以使用正则提取json数据。
正则表达式为 "= (.*?);"
需要注意的是,正在上映和即将上映的电影,Ajax响应的json数据格式不同。已上映的多了关于票房的“boxOffice”
字段。在解析数据时,可以根据是否有“boxOffice”字段来区分已上映和未上映的电影。

整理思路:
1.从电影列表页提取所有电影的链接url
2.遍历提取到的url,构造每个电影详情页中的Ajax请求url,获取Ajax响应数据
3.提取Ajax数据中的json字符串,解析、保存。

源码

下载器

# !/usr/bin/env python
# -*- coding:utf-8 -*-import requestsclass HTMLDownloader(object):"""HTML网页下载器"""def download(self,url):if url:headers={"User-Agent" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"}resp=requests.get(url,headers=headers)if resp.status_code==requests.codes.ok:resp.encoding='utf-8'return resp.text

解析器

# !/usr/bin/env python
# -*- coding:utf-8 -*-import re
import jsonclass HTMLParser(object):"""网页解析器get_movie_links() : 获取多有电影详情页的链接urlget_movie_detail() : 获取Ajax加载的电影详情数据"""def get_movie_links(self,html):"""提取所有电影链接"""parttern=re.compile(r'http://movie.mtime.com/\d+/')links=parttern.findall(html)if links:return list(set(links))def get_movie_detail(self,text):"""从Ajax响应中提取当前电影的详细信息"""# 提取json字符串parttern=re.compile(r'= (.*?);')result=parttern.findall(text)[0]if result:detail_json=json.loads(result,encoding='utf-8')# print(detail_json)# 获取boxOffice字段,如果为空,说明还未上映;否则,已上映boxOffice=detail_json.get('value').get('boxOffice')if boxOffice:# 正在上映return self.__get_release_movie_detail(detail_json)else:# 即将上映return self.__get_norelease_movie_detail(detail_json)def __get_release_movie_detail(self,detail_json):"""获取正在上映的影片信息"""# 电影名movieTitle=detail_json.get('value').get('movieTitle')# 上映类型isRelease=u'正在上映'# 评分RatingFinal=detail_json.get('value').get('movieRating').get('RatingFinal')# 多少人评价Usercount=detail_json.get('value').get('movieRating').get('Usercount')# 多少人想看AttitudeCount=detail_json.get('value').get('movieRating').get('AttitudeCount')# 票房排行Rank=detail_json.get('value').get('boxOffice').get('Rank')# 上映时长ShowDays='{}天'.format(detail_json.get('value').get('boxOffice').get('ShowDays'))# 实时(今日)票房TodayBoxOffice=detail_json.get('value').get('boxOffice').get('TodayBoxOffice')+detail_json.get('value').get('boxOffice').get('TodayBoxOfficeUnit')# 累计票房TotalBoxOffice=detail_json.get('value').get('boxOffice').get('TotalBoxOffice')+detail_json.get('value').get('boxOffice').get('TotalBoxOfficeUnit')# 数据更新时间EndDate=detail_json.get('value').get('boxOffice').get('EndDate')return {u'电影名':movieTitle,u'上映类型': isRelease,u'评分': RatingFinal,u'多少人评价': Usercount,u'多少人想看': AttitudeCount,u'票房排行': Rank,u'上映时长': ShowDays,u'今日票房': TodayBoxOffice,u'累计票房': TotalBoxOffice,u'数据更新时间': EndDate,}def __get_norelease_movie_detail(self,detail_json):"""获取即将上映的影片信息"""# 电影名movieTitle=detail_json.get('value').get('movieTitle')# 上映类型isRelease=u'即将上映'# 评分RatingFinal=detail_json.get('value').get('movieRating').get('RatingFinal')# 多少人评价Usercount=detail_json.get('value').get('movieRating').get('Usercount')# 多少人想看AttitudeCount=detail_json.get('value').get('movieRating').get('AttitudeCount')return {u'电影名': movieTitle,u'上映类型': isRelease,u'评分': RatingFinal,u'多少人评价': Usercount,u'多少人想看': AttitudeCount,}

数据存储器

# !/usr/bin/env python
# -*- coding:utf-8 -*-import pymongoclass DataStore(object):"""数据存储器将HTML解析器提取到的电影详情数据,保存到MongoDB数据库中"""def __init__(self):# 连接数据库服务器client=pymongo.MongoClient('localhost',27017)# 获取数据库对象db=client.mtimeDB# 获取集合对象self.movies=db.moviesdef save(self,data):self.movies.insert(data)

调度器

# !/usr/bin/env python
# -*- coding:utf-8 -*-import timefrom html_downloader import HTMLDownloader
from html_parser import HTMLParser
from data_store import DataStoreclass Scheduler(object):"""爬虫调度器负责调度各组件,并构造Ajax请求url链接"""def __init__(self):self.html_downloader=HTMLDownloader()self.html_parser=HTMLParser()self.data_store=DataStore()def crawl(self,start_url):try:# 获取电影列表页HTML数据html=self.html_downloader.download(start_url)# 获取所有电影的链接movie_links=self.html_parser.get_movie_links(html)# 遍历,构造ajax请求urlfor link in movie_links:"""http://service.library.mtime.com/Movie.api?Ajax_CallBack=true&Ajax_CallBackType=Mtime.Library.Services&Ajax_CallBackMethod=GetMovieOverviewRating&Ajax_CrossDomain=1&Ajax_RequestUrl=http%3A%2F%2Fmovie.mtime.com%2F230788%2F&t=201811115619396&Ajax_CallBackArgument0=230788http://service.library.mtime.com/Movie.api?Ajax_CallBack=true&Ajax_CallBackType=Mtime.Library.Services&Ajax_CallBackMethod=GetMovieOverviewRating&Ajax_CrossDomain=1&Ajax_RequestUrl=http%3A%2F%2Fmovie.mtime.com%2F233735%2F&t=20181111604467678&Ajax_CallBackArgument0=233735        """print('正在获取>>>',link)t=time.strftime('%Y%m%d%H%M%S0000',time.localtime())id=link.split('/')[-2]ajax_url=r'http://service.library.mtime.com/Movie.api' \r'?Ajax_CallBack=true&Ajax_CallBackType=Mtime.Library.Services' \r'&Ajax_CallBackMethod=GetMovieOverviewRating' \r'&Ajax_CrossDomain=1' \r'&Ajax_RequestUrl={link}' \r'&t={t}' \r'&Ajax_CallBackArgument0={id}'.format(link=link,t=t,id=id)# 下载ajax数据ajax_data=self.html_downloader.download(ajax_url)# 解析Ajax数据movie_data=self.html_parser.get_movie_detail(ajax_data)# 保存到数据库self.data_store.save(movie_data)print('获取成功')time.sleep(1)except Exception as e:print('爬取出错',e)# raise eif __name__ == '__main__':start_url='http://theater.mtime.com/China_Beijing/'Scheduler().crawl(start_url)

运行结果

...
正在获取>>> http://movie.mtime.com/240424/
获取成功
正在获取>>> http://movie.mtime.com/211981/
获取成功
正在获取>>> http://movie.mtime.com/235012/
获取成功
正在获取>>> http://movie.mtime.com/235349/
获取成功
正在获取>>> http://movie.mtime.com/251245/
获取成功
正在获取>>> http://movie.mtime.com/228404/
获取成功
正在获取>>> http://movie.mtime.com/106997/
获取成功
正在获取>>> http://movie.mtime.com/254017/
获取成功
正在获取>>> http://movie.mtime.com/253867/
获取成功Process finished with exit code 0

动态网站数据采集 - 时光网电影信息爬虫相关推荐

  1. python爬虫之爬取时光网电影影评

    最近看了美国往事这部电影.于是就想到最近刚学的爬虫,就像试试把时光网影评爬取下来,并按照影评的名字存放在本地文件夹. 在长影评页面可以看到每篇文章的标题对应都有一个blogid,并且这个id对应该影评 ...

  2. Python实现可视化界面多线程豆瓣电影信息爬虫,并绘制统计图分析结果

    完整代码见链接:https://github.com/kuronekonano/python_scrapy_movie 实现时使用图形界面.多线程.文件操作.数据库编程.网络编程.统计绘图六项技术. ...

  3. 爬取TOP100榜猫眼电影信息 爬虫实战

    写在前面 最近在学爬虫,跟着崔庆才大佬的个人网站学习. 今天跟着做了一个爬虫来爬取猫眼电影top100榜的电影信息.其中遇到了一些问题,这里就写成博客记录下来. 遇到的问题 反爬虫机制:在进行html ...

  4. python项目实战分析:爬取时光网电影TOP100

    前言 相信大家在各种看到的都是爬取猫眼,豆瓣电影排行榜TOP100的案例,下面为大家介绍爬取时光网的案例分析,用另一个方式来获取电影TOP100,下面就开始看看实现的过程吧 导入第三方库 用来显示信息 ...

  5. 基于80s电影下载网的电影信息爬虫

    最近由于需要使用ElasticSearch进行学习,其中用到了Spring Data ElasticSearch框架,为了准备测试的数据,这里使用了jsoup去爬虫80s电影网站上的电影信息用于测试, ...

  6. html 时光网播放视频,mtime时光网电影资料库采集规则

    经过分析发现,时光网的这个筛选结果页面html中,是用 在筛选结果页面通过抓去HTML代码发现电影URL的常规方法在这里不管用,当然筛选结果页的翻页也不管用,因此需要用抓包工具把筛选结果的内部列表页U ...

  7. 动态网站数据采集 - 去哪儿网火车票查询爬虫

    分析 在去哪儿网火车票查询页面,需要用户填写出发站.目的地站.出发时间等信息,然后,点击搜索按钮, 页面通过Ajax获取并显示查询结果数据. 这里用Selenium+PhantomJS模拟这一过程. ...

  8. 使用WebCollector爬取时光网电影数据

    数据源http://video.mtime.com/search 原数据是json格式的,其中i标示页码 http://video.mtime.com/api/videoSearch/getFilte ...

  9. Mtime美好时光网 盈利模式

    一.Mtime时光网的基本情况 (一)简介 Mtime时光网是北京动艺时光网络科技有限公司的网站,公司CEO侯凯文曾任微软公司高级总监.大中华区副总裁等职务.公司注册资本3000万. Mtime时光网 ...

  10. 一、服务端开发基础(搭建Web服务器、网络基础概念、请求响应流程、配置Apache、静态网站与动态网站)

    一.建立你的第一个网站(目标) 前端开发 最终还是属于 Web 开发 中的一个分支,想要成为一名合格的前端开发人员,就必须要 充分理解Web 的概念. 构建一个专业的网站是一项巨大的工作!对于新手我们 ...

最新文章

  1. Windows下配置Maven环境变量
  2. SAP 电商云 UI 持续集成里 workflow 触发条件一览
  3. 雨中的蚊子为啥不会被雨滴砸死?
  4. 使用Hanlp加载大字典
  5. A/D转换器(华中师范)
  6. java 对象protected,Java对象类protected void finalize throws Throwable方法示例
  7. Matlab for循环subplot画图加标题
  8. ThinkPHP 接入 SeasLog 日志组件
  9. 深度学习试题_深度学习理论类常见面试题(二)
  10. 【转】设计模式(三)建造者模式Builder(创建型)
  11. 国际产品经理资格认证NPDP 2017
  12. 80端口被封 php跳转,80端口打不开网站问题
  13. [乡土民间故事_徐苟三传奇]第卅八回_徐苟三改字赢官司
  14. 双非本科生进大厂,而我还在底层默默地爬树(上)
  15. vm虚拟机安装以及镜像和网路配置
  16. cmd里如何查看历史命令并执行
  17. Asterisk常用命令
  18. 邮件服务器(postfix与squirrelmail)
  19. 其它服务器(ThinkPHP5)与Discuz3.3自带的UCenter实现同步(一) - 通信成功
  20. 老毛桃安装Linux系统ISO镜像,老毛桃U盘安装Centos

热门文章

  1. K8S Pod配置进阶1 containers字段解释
  2. *TEST 11 for NOIP 再次爆炸 (100-300)-----(( ! ))
  3. 计算机桌面背景一直自动更换,电脑的桌面自动变换即自动更换桌面背景
  4. 2014年终总结,我决定要实现的三个目标
  5. 大聪明教你学Java | 没有绝对安全的系统
  6. Could not find artifact xxx.xxx:ww-www-ww:pom:1.0.1-SNAPSHOT in xxxx(http://xxx.xxx.xxx:xxxx私服地址)
  7. 利用多线程中线程休眠----sleep实现简单的计时器以及时钟功能
  8. epoch如何设置,在Keras中,steps_per_epoch和纪元的设置如何影响训练结果?
  9. 家庭的和睦,人生的平淡
  10. 斐讯音箱控制扫地机器人_斐讯大能X3扫地机器人首批测试,这回真没花一分钱!...