爬取豆瓣TOP250电影排行榜
学习指南
本系列课程没有必然的前后关系(除非特别强调)
因此,你可以选择任意一个喜欢的案例开始学习!
项目需求
很多朋友在看一部电影前都喜欢先找一下网友们对该片的评价。
说到电影评分的网站,除了国外的 IMDB 和烂番茄,国内要数豆瓣最为出名。
主要原因是豆瓣有一套完整的评分和防水军机制
在这套机制下,豆瓣评分高的电影不一定是所有人都喜欢的,但是豆瓣评分低的电影,一定是实打实的烂片!
虽然每个人的喜好偏爱不同,但通常豆瓣评分 8 分以上的电影,都是值得一看的。
豆瓣还专门提供了一个 TOP250 的电影链接 -> https://movie.douban.com/top250
温馨提示:别看这些片儿都“挺老”的,很多都是现在很难再超越的经典,建议豆瓣的 TOP250 都看一遍,相信你将会受益匪浅!
要求:编写一个小爬虫,将豆瓣 TOP250 的电影名、评分以及相关的资料保存到一个文件中。
开发思路
思路一:
在《零基础入门学习Python》系列课程中,给大家讲过使用 Python 开发爬虫,那时候是利用 urllib 模块实现网络抓取功能。但现在请忘掉它,因为在 Python 中,有一个更好地替代者 —— Requests。
Requests 简化了 urllib 的诸多冗杂且无意义的操作,并提供了更强大的功能。不是我吹,Requests 是 Python 所有模块中最受欢迎的一个,全世界最优秀的程序员都在使用它!
有关 Requests 模块的安装及使用,请参考 -> Requests 模块中文文档
使用 Requests 模块的 get() 方法从服务器上下载一个页面之后,就需要解析它。
思路二:
解析网页内容小甲鱼推荐使用 BeautifulSoup 模块,它可以化腐朽为神奇,将一个复杂的网页结构转化为书籍目录的形式供你浏览。
>>> import requests
>>> import bs4
>>> res = requests.get("https://movie.douban.com/top250")
>>> soup = bs4.BeautifulSoup(res.text, "html.parser")
>>> targets = soup.find_all("div", class_="hd")
>>> for each in targets:
print(each.a.span.text)
肖申克的救赎
霸王别姬
这个杀手不太冷
阿甘正传
美丽人生
千与千寻
辛德勒的名单
泰坦尼克号
盗梦空间
机器人总动员
海上钢琴师
三傻大闹宝莱坞
忠犬八公的故事
放牛班的春天
大话西游之大圣娶亲
教父
龙猫
楚门的世界
乱世佳人
天堂电影院
触不可及
当幸福来敲门
熔炉
无间道
搏击俱乐部
这些哗啦啦的数据是怎么得来的呢?
我们先来看下 HTML 源代码:
发现每个电影的标题都是位于 <div class="hd">...</div> 标签中的,它的从属关系是:div -> a -> span。
所以我们先调用 find_all() 方法,找到所有 class="hd" 的 div 标签,然后按照从属关系即可直接取出电影名。
怎么样?是不是和翻书查字典一样简单!
有关 BeautifulSoup 模块的安装及使用,请参考 -> BeautifulSoup4 模块中文文档
模块档案
- Requests 模块中文文档(一)
- Requests 模块中文文档(二)
- Requests 模块中文文档(三)
- Requests 模块中文文档(四)
- Requests 模块中文文档(五)
- Requests 模块中文文档(六)
- BeautifulSoup4 模块中文文档
代码清单
import requests
import bs4
import re
def open_url(url):
# 使用代理
# proxies = {"http": "127.0.0.1:1080", "https": "127.0.0.1:1080"}
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36'}
# res = requests.get(url, headers=headers, proxies=proxies)
res = requests.get(url, headers=headers)
return res
def find_movies(res):
soup = bs4.BeautifulSoup(res.text, 'html.parser')
# 电影名
movies = []
targets = soup.find_all("div", class_="hd")
for each in targets:
movies.append(each.a.span.text)
# 评分
ranks = []
targets = soup.find_all("span", class_="rating_num")
for each in targets:
ranks.append(' 评分:%s ' % each.text)
# 资料
messages = []
targets = soup.find_all("div", class_="bd")
for each in targets:
try:
messages.append(each.p.text.split('\n')[1].strip() + each.p.text.split('\n')[2].strip())
except:
continue
result = []
length = len(movies)
for i in range(length):
result.append(movies[i] + ranks[i] + messages[i] + '\n')
return result
# 找出一共有多少个页面
def find_depth(res):
soup = bs4.BeautifulSoup(res.text, 'html.parser')
depth = soup.find('span', class_='next').previous_sibling.previous_sibling.text
return int(depth)
def main():
host = "https://movie.douban.com/top250"
res = open_url(host)
depth = find_depth(res)
result = []
for i in range(depth):
url = host + '/?start=' + str(25 * i)
res = open_url(url)
result.extend(find_movies(res))
with open("豆瓣TOP250电影.txt", "w", encoding="utf-8") as f:
for each in result:
f.write(each)
if __name__ == "__main__":
main()
补充
尽管豆瓣设计了一套防止水军刷分的机制,但仍然是有漏网之鱼的。
于是有网友给出了一套非常直观有效地判断电影好坏的方法
通常只应天上有的神作,评分是呈现“F”形状的,也就是 5 分和 4 分居多,1、2、3 分几乎没有。
比如触及灵魂深处的越狱神作《肖申克的救赎》
又如励志神作《阿甘正传》
一般的好片(值得到电影院去支持的)评分是呈现“P”形状的,也就是 3、4、5 分占主导,1 和 2 分较少。
比如《杀破狼2》,讲真,张晋在里面主演的反派确实帅到掉渣
还有前期红遍全国的《战狼2》
普通烂片通常是呈现“b”的形状,也就是 4、5 分比较少,1、2、3 分占据多数。
比如《小时代》(个人观点,不喜勿喷)
有些虽然是烂片,但是刚上映时水军(刷分)特别多的
或者是只有粉丝喜欢,一般人根本看不下去的
这类片的评分是呈现一个“C”的形状……(个人观点,不喜勿喷)
但随着看的人越来越多,其终将呈现出烂片的特征(个人观点,不喜勿喷)
最后还有一种终极烂片,就是本身就是烂片,然后没有粉丝也没钱请水军的那种……
评分是呈现出“L”形的,比如前阵子为了评分的事儿还声称要豆瓣道歉赔偿的《纯洁心灵·逐梦演艺圈》(个人观点,不喜勿喷)
光听名字就是一阵酥麻