设为首页收藏本站

Crossin的编程教室

 找回密码
 立即加入
查看: 9695|回复: 3
打印 上一主题 下一主题

爬虫+网站开发实例:电影票比价网

[复制链接]

169

主题

1

好友

733

积分

版主

Rank: 7Rank: 7Rank: 7

跳转到指定楼层
楼主
发表于 2019-3-7 11:46:21 |只看该作者 |正序浏览
注:一篇去年的旧文,发现没在知乎发过,过来补个档。有个小问题是项目中淘票票的网页反爬提升且变动较多,目前暂不可用了。
时常有同学会问我类似的问题:我已经学完了 Python 基础,也照着例子写过一点爬虫代码 / 了解过 django 的入门项目 / 看过数据分析的教程……然后就不知道要做什么了。接下来应该如何继续提升编程能力呢?

我的答案很简单:
做项目
不要把“项目”想象得太复杂,觉得一定是那种收钱开发的才能称作项目(如果有这种项目当然会更好)。对于刚刚跨入编程世界的你来说,任何一个小项目都是好的开始。你所需要的,就是一双发现问题的眼睛。生活中工作中的一些小事情小麻烦,多想一步,是不是可以写一小段代码来解决。

一开始,或许你的解决方案很笨拙,很复杂,本来5分钟就能搞定的事情,你写代码却花了一个小时。但对你来说,此时的目的并不只是解决问题,而是这个过程本身。在折腾的过程中,你的经验才会增长。这是你单纯看教程所无法达到的,再好的教程也替代不了动手。(有时候会有人评论说,这功能直接用xxx就可以了,干嘛还要自己写代码。对此我不做评价,因为我知道他不是来学编程的。)

我们编程教室也陆续提供了一些项目案例。你可以参考我们的示例代码,或者更好的是,自己去思考一个解决方案并实现。我们的案例不少都放在了网站 http://lab.crossincode.com 上演示,欢迎大家去浏览。内容会持续更新,可留意我们微信公众号和知乎专栏里的文章。


今天介绍的这个项目就源自生活中的一个场景:买电影票。

当你打算周末出门看场电影的时候,就必然面临三个终极问题:
看什么?什么时候看?去哪儿看?
通常你只需要打开常用的购票App,选一部最近口碑不错的片子,去熟悉的影院看看有哪些场次就可以了。但有时你也会发现,同样一部电影,不远的两家影院,价格就差很多,不同的购票App也会因为促销活动之类有不同的优惠力度,一张票可能会相差几十元。但如果每次都去几个App把最近的排片和价格都浏览一遍,那也太麻烦了。于是就有了我们这个小项目:

电影票比价网

在我们这个网页上,会展示出当前热映的电影。进入每部电影,选择城市、区域、影院和日期,就可以看到最近的排片时间和不同渠道的价格。目前,我们是从糯米、淘票票和时光网三个渠道获取价格来做演示。(注:项目中淘票票现已失效)
实现技术
本项目是对爬虫和Web网站的综合运用,适合已经有掌握python基础,并且对此有一些了解的同学作为练手项目。涉及到模块主要是:
Django(1.10)requestsbs4python-Levenshtein(用来匹配不同渠道的影院信息)代码结构
项目主要有三块:
douban_movie使用豆瓣 api 每日更新上映的影片列表。movie_tickets项目的核心部分,用来处理影院信息和排名信息的抓取。django项目本身是一个网站,整体是在 django 的框架之中。开发思路使用爬虫爬取各电影票网站所有的电影院链接,作为基本的数据保存下来使用豆瓣 API 获取当日上映的电影信息,并每天更新django 显示电影信息,提供给用户选择电影院的接口将影片和影院信息发送到 django 后台进行查询,爬取对应的排片信息显示给用户代码片段
  1. # 获取淘票票某地区某电影院某影片价格#
  2. 1. 根据查询条件获取影院 id#
  3. 2. 根据影院 id 获取该影院正在上映电影#
  4. 3. 获取 查询电影的排片时间表链接#
  5. 4. 拿到价格
  6. def get_movie_tickets(self, *args):
  7.     assert len(args) == 4, 'not enough parameters \n type in -h for help'
  8.     movie_name = args[3]
  9.     mt = TaoppDt()
  10.     cinema_url = mt.search(*args[:3])
  11.     assert cinema_url, '未查询到该电影院'
  12.     pattern = re.compile(r'cinemaId=(\d+)')
  13.     cinemaid = re.findall(pattern, cinema_url)[0]
  14.     film_url = 'https://dianying.taobao.com/cinemaDetailSchedule.htm?cinemaId=' + str(cinemaid)
  15.     content = self.rq.req_url(film_url)
  16.     assert content, '请求失败,请检查 /utils/req.py 中 req_url 函数是否工作正常'
  17.     soup = bs4.BeautifulSoup(content, 'lxml')
  18.     soup_film = soup.find('a', text=re.compile(movie_name))
  19.     assert soup_film, '未查询到该电影'
  20.     film_param = soup_film['data-param']
  21.     return self._get_ticket_info(film_param)
复制代码
其他说明项目为了有一个较好的交互效果,在页面上用到了不少 Ajax 请求。这需要有一定的前端 js 基础。对网页前端不熟悉的同学可暂且略过,重点关注后端实现。不同渠道对于同一家影院的名称很可能有出入,因此这里使用了 python-Levenshtein 来对文本进行匹配。代码里在抓取时有用到我们的另一个项目:IP代理池(参见 Crossin:听说你好不容易写了个爬虫,结果没抓几个就被封了?)。但因为服务器资源有限,有时拿不到可用的代理。各位自己电脑上运行代码时,可尝试把 requests 的 proxies 参数去除。作为一个演示项目,必然存在一些bug(当然商业项目也不可能没有bug),加上爬虫的程序极有可能因为对方网站更新而失效。所以如果遇到问题,欢迎大家给我们报错。代码下载
完整的代码和详细代码说明已上传 Github,获取下载地址请在公众号(Crossin的编程教室)里回复 电影票。


════

其他文章及回答:

学编程:如何自学Python | 新手引导 | 一图学Python

开发案例:智能防挡弹幕 | 红包提醒 | 流浪地球

欢迎搜索及关注:Crossin的编程教室



回复

使用道具 举报

2

主题

0

好友

114

积分

注册会员

Rank: 2

地板
发表于 2020-2-13 10:11:24 |只看该作者
(๑•̀ㅂ•́)و✧
璀璨只是一瞬,幻灭却是永恒。
回复

使用道具 举报

5

主题

0

好友

145

积分

注册会员

Rank: 2

板凳
发表于 2019-6-21 15:32:28 |只看该作者
厉害了
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

沙发
发表于 2019-6-6 13:38:30 |只看该作者
转一个读者发现的问题,报错:
StaticApp has no attribute “directory”
getimgdata.jpeg

解答:我在github webpy项目pull request 找到了答案,python 3.7 与webpy不兼容导致的一些bug, 修改源码或者用 py 3.6+ 解决
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即加入

QQ|手机版|Archiver|Crossin的编程教室 ( 苏ICP备15063769号  

GMT+8, 2024-11-22 01:10 , Processed in 0.017058 second(s), 24 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部