赞
踩
.
打开
https://movie.douban.com/top250?start=0&filter=
来到豆瓣主页
此处可以观察到电影是在第1个序号开始的,暂时记住url,观察后续变化
切换第二页,发现url变化:
https://movie.douban.com/top250?start=25&filter=
第二页如下:
**url第一页:https://movie.douban.com/top250?start=0&filter=
**url第二页:https://movie.douban.com/top250?start=25&filter=
可以明确观察到切换一页start=后的参数增加25
通过页面数据发现一页是25个电影
通常情况下数组的下标是在0开始的
即0是第一个元素,所以第二页是从第26个电影开始,按照数组排序是编号25的元素开始,由此可以得知url的参数从0开始到24为第一页的25个电影,第二页起始则为25,以此类推后续页数起始值是50,75…
.
代码如下:
import requests
url = 'https://movie.douban.com/top250?start=0&filter='
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"}
response = requests.get(url, headers=headers) #headers是模拟浏览器的头部标识,这是反爬机制的一种
text = response.text
print(text)
可以在打印的结果中看到该页的网页源码(以下展示部分源码):
<li> <div class="item"> <div class="pic"> <em class="">1</em> <a href="https://movie.douban.com/subject/1292052/"> <img width="100" alt="肖申克的救赎" src="https://img3.doubanio.com/view/photo/s_ratio_poster/public/p480747492.webp" class=""> </a> </div> <div class="info"> <div class="hd"> <a href="https://movie.douban.com/subject/1292052/" class=""> <span class="title">肖申克的救赎</span> <span class="title"> / The Shawshank Redemption</span> <span class="other"> / 月黑高飞(港) / 刺激1995(台)</span> </a> <span class="playable">[可播放]</span> </div> <div class="bd"> <p class=""> 导演: 弗兰克·德拉邦特 Frank Darabont 主演: 蒂姆·罗宾斯 Tim Robbins /...<br> 1994 / 美国 / 犯罪 剧情 </p> <div class="star"> <span class="rating5-t"></span> <span class="rating_num" property="v:average">9.7</span> <span property="v:best" content="10.0"></span> <span>2035033人评价</span> </div> <p class="quote"> <span class="inq">希望让人自由。</span> </p> </div> </div> </div> </li>
根据该段源代码,编写正则表达式来获取详细信息:
以下使用正则表达式的懒惰(非贪婪)模式,(.*?)
为需要获取信息的字段
regix = '<div class="item">.*?<div class="pic">.*?<em class="">(.*?)</em>.*?<img.*?src="(.*?)" class="">.*?div class="info.*?class="hd".*?class="title">(.*?)</span>.*?class="other">(.*?)</span>.*?<div class="bd">.*?<p class="">(.*?)<br>(.*?)</p>.*?class="star.*?<span class="(.*?)"></span>.*?span class="rating_num".*?average">(.*?)</span>'
接下来开始将正则接入主页请求代码中使用:
以下不单单是正则匹配,同时遍历每个电影的有效信息,去除冗杂信息,将每个电影数据合并为字典型数据
import requests import re url = 'https://movie.douban.com/top250?start=0&filter=' headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"} response = requests.get(url, headers=headers) #headers是模拟浏览器的头部标识,这是反爬机制的一种 text = response.text regix = '<div class="item">.*?<div class="pic">.*?<em class="">(.*?)</em>.*?<img.*?src="(.*?)" class="">.*?div class="info.*?class="hd".*?class="title">(.*?)</span>.*?class="other">(.*?)</span>.*?<div class="bd">.*?<p class="">(.*?)<br>(.*?)</p>.*?class="star.*?<span class="(.*?)"></span>.*?span class="rating_num".*?average">(.*?)</span>' results = re.findall(regix, text, re.S) #使用正则的非贪婪模式匹配所有有效信息字段 for item in results: #循环遍历所有字段并清洗干扰字符和多余字段,并将清洗后的结果重构成字典保存 dic = { '电影名称': item[2] + ' ' + re.sub(' ', '', item[3]), '电影图片': re.findall('/public/(.*?).jpg', item[1])[0] + '.jpg', '导演和演员': re.sub(' ', '', item[4].strip()), '评分': item[7] + '分', '排名': item[0] } print(dic)
运行结果如下:
{'电影名称': '肖申克的救赎 /月黑高飞(港) / 刺激1995(台)', '电影图片': 'p480747492.jpg', '导演和演员': '导演: 弗兰克·德拉邦特 Frank Darabont主演: 蒂姆·罗宾斯 Tim Robbins /...', '评分': '9.7分', '排名': '1'} {'电影名称': '霸王别姬 /再见,我的妾 / Farewell My Concubine', '电影图片': 'p2561716440.jpg', '导演和演员': '导演: 陈凯歌 Kaige Chen主演: 张国荣 Leslie Cheung / 张丰毅 Fengyi Zha...', '评分': '9.6分', '排名': '2'} {'电影名称': '阿甘正传 /福雷斯特·冈普', '电影图片': 'p1484728154.jpg', '导演和演员': '导演: 罗伯特·泽米吉斯 Robert Zemeckis主演: 汤姆·汉克斯 Tom Hanks / ...', '评分': '9.5分', '排名': '3'} {'电影名称': '这个杀手不太冷 /杀手莱昂 / 终极追杀令(台)', '电影图片': 'p511118051.jpg', '导演和演员': '导演: 吕克·贝松 Luc Besson主演: 让·雷诺 Jean Reno / 娜塔莉·波特曼 ...', '评分': '9.4分', '排名': '4'} {'电影名称': '美丽人生 /一个快乐的传说(港) / Life Is Beautiful', '电影图片': 'p2578474613.jpg', '导演和演员': '导演: 罗伯托·贝尼尼 Roberto Benigni主演: 罗伯托·贝尼尼 Roberto Beni...', '评分': '9.5分', '排名': '5'} {'电影名称': '泰坦尼克号 /铁达尼号(港 / 台)', '电影图片': 'p457760035.jpg', '导演和演员': '导演: 詹姆斯·卡梅隆 James Cameron主演: 莱昂纳多·迪卡普里奥 Leonardo...', '评分': '9.4分', '排名': '6'} {'电影名称': '千与千寻 /神隐少女(台) / 千与千寻的神隐', '电影图片': 'p2557573348.jpg', '导演和演员': '导演: 宫崎骏 Hayao Miyazaki主演: 柊瑠美 Rumi Hîragi / 入野自由 Miy...', '评分': '9.4分', '排名': '7'} {'电影名称': '辛德勒的名单 /舒特拉的名单(港) / 辛德勒名单', '电影图片': 'p492406163.jpg', '导演和演员': '导演: 史蒂文·斯皮尔伯格 Steven Spielberg主演: 连姆·尼森 Liam Neeson...', '评分': '9.5分', '排名': '8'} {'电影名称': '盗梦空间 /潜行凶间(港) / 全面启动(台)', '电影图片': 'p513344864.jpg', '导演和演员': '导演: 克里斯托弗·诺兰 Christopher Nolan主演: 莱昂纳多·迪卡普里奥 Le...', '评分': '9.3分', '排名': '9'} {'电影名称': '忠犬八公的故事 /秋田犬八千(港) / 忠犬小八(台)', '电影图片': 'p524964039.jpg', '导演和演员': '导演: 莱塞·霍尔斯道姆 Lasse Hallström主演: 理查·基尔 Richard Ger...', '评分': '9.4分', '排名': '10'} {'电影名称': '海上钢琴师 /声光伴我飞(港) / 一九零零的传奇', '电影图片': 'p2574551676.jpg', '导演和演员': '导演: 朱塞佩·托纳多雷 Giuseppe Tornatore主演: 蒂姆·罗斯 Tim Roth / ...', '评分': '9.3分', '排名': '11'} {'电影名称': '楚门的世界 /真人Show(港) / 真人戏', '电影图片': 'p479682972.jpg', '导演和演员': '导演: 彼得·威尔 Peter Weir主演: 金·凯瑞 Jim Carrey / 劳拉·琳妮 Lau...', '评分': '9.3分', '排名': '12'} {'电影名称': '三傻大闹宝莱坞 /三个傻瓜(台) / 作死不离3兄弟(港)', '电影图片': 'p579729551.jpg', '导演和演员': '导演: 拉库马·希拉尼 Rajkumar Hirani主演: 阿米尔·汗 Aamir Khan / 卡...', '评分': '9.2分', '排名': '13'} {'电影名称': '机器人总动员 /太空奇兵·威E(港) / 瓦力(台)', '电影图片': 'p1461851991.jpg', '导演和演员': '导演: 安德鲁·斯坦顿 Andrew Stanton主演: 本·贝尔特 Ben Burtt / 艾丽...', '评分': '9.3分', '排名': '14'} {'电影名称': '放牛班的春天 /歌声伴我心(港) / 唱诗班男孩', '电影图片': 'p1910824951.jpg', '导演和演员': '导演: 克里斯托夫·巴拉蒂 Christophe Barratier主演: 热拉尔·朱尼奥 Gé...', '评分': '9.3分', '排名': '15'} {'电影名称': '星际穿越 /星际启示录(港) / 星际效应(台)', '电影图片': 'p2206088801.jpg', '导演和演员': '导演: 克里斯托弗·诺兰 Christopher Nolan主演: 马修·麦康纳 Matthew Mc...', '评分': '9.3分', '排名': '16'} {'电影名称': '大话西游之大圣娶亲 /西游记完结篇仙履奇缘 / 齐天大圣西游记', '电影图片': 'p2455050536.jpg', '导演和演员': '导演: 刘镇伟 Jeffrey Lau主演: 周星驰 Stephen Chow / 吴孟达 Man Tat Ng...', '评分': '9.2分', '排名': '17'} {'电影名称': '熔炉 /无声呐喊(港) / 漩涡', '电影图片': 'p1363250216.jpg', '导演和演员': '导演: 黄东赫 Dong-hyuk Hwang主演: 孔侑 Yoo Gong / 郑有美 Yu-mi Jung /...', '评分': '9.3分', '排名': '18'} {'电影名称': '疯狂动物城 /优兽大都会(港) / 动物方城市(台)', '电影图片': 'p2315672647.jpg', '导演和演员': '导演: 拜伦·霍华德 Byron Howard / 瑞奇·摩尔 Rich Moore主演: 金妮弗·...', '评分': '9.2分', '排名': '19'} {'电影名称': '无间道 /Infernal Affairs / Mou gaan dou', '电影图片': 'p2564556863.jpg', '导演和演员': '导演: 刘伟强 / 麦兆辉主演: 刘德华 / 梁朝伟 / 黄秋生', '评分': '9.2分', '排名': '20'} {'电影名称': '龙猫 /邻居托托罗 / 邻家的豆豆龙', '电影图片': 'p2540924496.jpg', '导演和演员': '导演: 宫崎骏 Hayao Miyazaki主演: 日高法子 Noriko Hidaka / 坂本千夏 Ch...', '评分': '9.2分', '排名': '21'} {'电影名称': '教父 /Mario Puzo's The Godfather', '电影图片': 'p616779645.jpg', '导演和演员': '导演: 弗朗西斯·福特·科波拉 Francis Ford Coppola主演: 马龙·白兰度 M...', '评分': '9.3分', '排名': '22'} {'电影名称': '当幸福来敲门 /寻找快乐的故事(港) / 追求快乐', '电影图片': 'p1312700628.jpg', '导演和演员': '导演: 加布里尔·穆奇诺 Gabriele Muccino主演: 威尔·史密斯 Will Smith ...', '评分': '9.1分', '排名': '23'} {'电影名称': '怦然心动 /萌动青春 / 青春萌动', '电影图片': 'p501177648.jpg', '导演和演员': '导演: 罗伯·莱纳 Rob Reiner主演: 玛德琳·卡罗尔 Madeline Carroll / 卡...', '评分': '9.1分', '排名': '24'} {'电影名称': '触不可及 /闪亮人生(港) / 逆转人生(台)', '电影图片': 'p1454261925.jpg', '导演和演员': '导演: 奥利维·那卡什 Olivier Nakache / 艾力克·托兰达 Eric Toledano主...', '评分': '9.2分', '排名': '25'}
这样我们就完成了信息的请求与获取阶段操作
.
图片保存操作,代码如下(该步骤重新构写一个函数方法,便于传参操作):
def file_image(file, filename):
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"}
r = requests.get(file, headers=headers) #file为图片对应的url
with open(filename + '.jpg', 'wb') as f: #filename 是图片名称
f.write(r.content) #content 字节方式的响应体,会自动为你解码 gzip 和 deflate 压缩 通过写入方法写入图片
文本保存操作,代码如下:
def file_data(dic): #dic为电影的详细信息 字典型数据
with open('douban_film.txt', 'a', encoding='utf-8') as f:
f.write(json.dumps(dic, ensure_ascii=False) + '\n') #使用json的dumps方法写入字段到txt文本中,为防止ascii编码转译,使用ensure_ascii=False方法关闭这项功能
.
.
代码如下:
import requests import re import json def start(): for i in range(0, 250, 25): url = 'https://movie.douban.com/top250?start='+str(i)+'&filter=' headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"} response = requests.get(url, headers=headers) text = response.text regix = '<div class="item">.*?<div class="pic">.*?<em class="">(.*?)</em>.*?<img.*?src="(.*?)" class="">.*?div class="info.*?class="hd".*?class="title">(.*?)</span>.*?class="other">(.*?)</span>.*?<div class="bd">.*?<p class="">(.*?)<br>(.*?)</p>.*?class="star.*?<span class="(.*?)"></span>.*?span class="rating_num".*?average">(.*?)</span>' results = re.findall(regix, text, re.S) for item in results: dic = { '电影名称': item[2] + ' ' + re.sub(' ', '', item[3]), '电影图片': re.findall('/public/(.*?).jpg', item[1])[0] + '.jpg', '导演和演员': re.sub(' ', '', item[4].strip()), '评分': item[7] + '分', '排名': item[0] } print(dic) file = item[1] filename = re.findall('/public/(.*?).jpg', str(item[1]))[0] file_image(file, filename) file_data(dic) def file_image(file, filename): headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"} r = requests.get(file, headers=headers) with open(filename + '.jpg', 'wb') as f: f.write(r.content) def file_data(dic): with open('douban_film.txt', 'a', encoding='utf-8') as f: f.write(json.dumps(dic, ensure_ascii=False) + '\n') if __name__ == '__main__': start()
运行后结果如下:
总共抓取250个图片和1个文本文档(文档包含250条电影数据)
以上就是关于使用python采集豆瓣TOP250电影图片及数据的操作,转载请注明出处!https://blog.csdn.net/dbldwang/article/details/106563152
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。