当前位置:   article > 正文

数据采集——爬虫篇(一):豆瓣电影TOP250详细信息采集

数据采集——爬虫篇(一):豆瓣电影TOP250详细信息采集

数据采集——爬虫篇(一):豆瓣电影TOP250详细信息采集

.

1.分析豆瓣url换页变化

打开
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…

.

2.python模拟发送requests请求主页信息:

代码如下:

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

可以在打印的结果中看到该页的网页源码(以下展示部分源码):

<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">&nbsp;/&nbsp;The Shawshank Redemption</span>
                                <span class="other">&nbsp;/&nbsp;月黑高飞()  /  刺激1995()</span>
                        </a>


                            <span class="playable">[可播放]</span>
                    </div>
                    <div class="bd">
                        <p class="">
                            导演: 弗兰克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·罗宾斯 Tim Robbins /...<br>
                            1994&nbsp;/&nbsp;美国&nbsp;/&nbsp;犯罪 剧情
                        </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>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

根据该段源代码,编写正则表达式来获取详细信息:
以下使用正则表达式的懒惰(非贪婪)模式,(.*?)为需要获取信息的字段

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>'
  • 1

接下来开始将正则接入主页请求代码中使用:
以下不单单是正则匹配,同时遍历每个电影的有效信息,去除冗杂信息,将每个电影数据合并为字典型数据

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('&nbsp;', '', item[3]),
        '电影图片': re.findall('/public/(.*?).jpg', item[1])[0] + '.jpg',
        '导演和演员': re.sub('&nbsp;', '', item[4].strip()),
        '评分': item[7] + '分',
        '排名': item[0]
    }
    print(dic)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

运行结果如下:

{'电影名称': '肖申克的救赎 /月黑高飞(港)  /  刺激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&#39;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'}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

这样我们就完成了信息的请求与获取阶段操作

.

3.图片下载以及文本保存

图片保存操作,代码如下(该步骤重新构写一个函数方法,便于传参操作):

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 压缩  通过写入方法写入图片
  • 1
  • 2
  • 3
  • 4
  • 5

文本保存操作,代码如下:

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方法关闭这项功能
  • 1
  • 2
  • 3

.
.

4.抓取250个电影的详细信息并将图片和信息保存到本地(代码汇总)

代码如下:

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('&nbsp;', '', item[3]),
                '电影图片': re.findall('/public/(.*?).jpg', item[1])[0] + '.jpg',
                '导演和演员': re.sub('&nbsp;', '', 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()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

运行后结果如下:
总共抓取250个图片和1个文本文档(文档包含250条电影数据)
在这里插入图片描述
以上就是关于使用python采集豆瓣TOP250电影图片及数据的操作,转载请注明出处!https://blog.csdn.net/dbldwang/article/details/106563152

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/191190
推荐阅读
相关标签
  

闽ICP备14008679号