栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

一起学爬虫——通过爬取豆瓣电影top250学习requests库的使用

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

一起学爬虫——通过爬取豆瓣电影top250学习requests库的使用

学习一门技术最快的方式是做项目,在做项目的过程中对相关的技术查漏补缺。

本文通过爬取豆瓣top250电影学习python requests的使用。

1、准备工作
在pycharm中安装request库

请看上图,在pycharm中依次点击:File->Settings。然后会弹出下图的界面:

点击2中左上角的“+”按钮,弹出下图的界面:

在右上角的查询框输入requests,然后点击“Install Package”按钮安装requests插件。

2、目标
抓取每部电影的名字、主演、评分、图片等信息, 并保存在txt文本文件中。

3、分析豆瓣top250电影首页
1、分析豆瓣电影top250的网页https://movie.douban.com/top250,在浏览器中打开该网页:

可以看到一页显示25部电影。250部电影分10显示:

要抓取250部电影需要抓取10次。下面是每一页的网页链接:

https://movie.douban.com/top250?start=0&filter=   首页,等效于https://movie.douban.com/top250https://movie.douban.com/top250?start=25&filter=  #第2页https://movie.douban.com/top250?start=50&filter=  #第3页...
...
...https://movie.douban.com/top250?start=225&filter=  #第10页

通过分析上面的链接可以得出一个规律:start=0显示1到25部电影,start=25显示26到50部电影,以此类推,在抓取每一页的电影时,是需要改变start的值即可。

4、抓取豆瓣电影top250首页
代码如下:

import requestsimport reimport json

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"}
url = 'https://movie.douban.com/top250?start=0&filter='proxies = {    "http": "http://123.207.96.189:80"}
response = requests.get(url, proxies = proxies,headers=headers)
text = response.text
print(text)

通过上述的代码我们可以学习到requests类库中如何使用headers信息和设置代理。
headers头信息和proxies代理信息都是定义为dict词典变量,然后在调用requests.get()方法时传输这个两个参数:

response = requests.get(url, proxies = proxies,headers=headers)

很多网站都有反爬虫的措施,对于没有headers头信息的请求一律认为是爬虫,禁止该请求的访问。因此在每次爬取网页时都需要加上headers头信息。

对于访问过于频繁的请求,客户端的IP会被禁止访问,因此设置代理可以将请求伪装成来自不同的IP,前提是要保证代理的IP地址是有效的。

5、抓取每一部电影的信息

查看网页源代码有两种方式:
通过鼠标右键点击查看“查看源文件”选项,或者通过浏览器的开发者工具选项,然后点击Network查看源码:

下图是一部电影在HTML网页中的显示,我们要做的就是从HTML中提取出电影名称、主演、图片等信息。

提取电影的信息需要用到正则表达式。
通过上图可以看到一部电影的信息对应的源代码是节点,红色框所示。我们先用正则表达式提取到每部电影的所有信息:
regix = ''
class为pic的div节点包含电影的排名和电影图片信息,提取电影排名和电影图片信息的正则表:

regix = '.*?.*?(.*?).*?'

class为info的div标签中包含了电影的名字、导演和演员等信息,电影名字是在class为hd的div的节点内,节点内包含的是电影的名字,节点内包含的是电影的别名,上图中的褐色框部分,因此提取电影名字的正则表达式为:

regix = '.*?.*?(.*?).*?.*?divclass="info.*?class="hd".*?class="title">(.*?).*?class="other">(.*?)'

class为bd的节点内包含的是电影的导演和主演信息,其中class为“”的p节点内包含的是电影的导演和演员信息,其中还包含了
标签,上图中的紫色框部分,为了提取电影导演和演员的信息,正则表达式改写为:

regix = '.*?.*?(.*?).*?.*?divclass="info.*?class="hd".*?class="title">(.*?).*?class="other">(.*?).*?.*?(.*?)
(.*?)

'

class为start的div标签中包含的是电影的星级和评分,上图黑色框部分。提取星级和评分的规则和提取电影排名、图片等信息类似,最后提取整个电影信息的正则表达式为:

regix = '.*?.*?(.*?).*?.*?div class="info.*?class="hd".*?class="title">(.*?).*?class="other">(.*?).*?.*?(.*?)
(.*?)

.*?class="star.*?.*?span class="rating_num".*?average">(.*?)'

提取一页中所有电影信息的代码如下:

import requestsimport reimport json

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"}
url = 'https://movie.douban.com/top250?start=0&filter='proxies = {    "http": "http://123.207.96.189:80"}
response = requests.get(url, proxies = proxies,headers=headers)
text = response.text
regix = '.*?.*?(.*?).*?.*?div class="info.*?class="hd".*?class="title">(.*?).*?class="other">(.*?).*?.*?(.*?)
(.*?)

.*?class="star.*?.*?span class="rating_num".*?average">(.*?)'results = re.findall(regix,text,re.S)for item in results:     print(item)

结果为:

('1', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p480747492.jpg', '肖申克的救赎', ' / 月黑高飞(港)  /  刺激1995(台)', 'n                            导演: 弗兰克·德拉邦特 Frank Darabont   主演: 蒂姆·罗宾斯 Tim Robbins /...', 'n                            1994 / 美国 / 犯罪 剧情n                        ', 'rating5-t', '9.6')
('2', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p1910813120.jpg', '霸王别姬', ' / 再见,我的妾  /  Farewell My Concubine', 'n                            导演: 陈凯歌 Kaige Chen   主演: 张国荣 Leslie Cheung / 张丰毅 Fengyi Zha...', 'n                            1993 / 中国大陆 香港 / 剧情 爱情 同性n                        ', 'rating5-t', '9.6')
('3', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p511118051.jpg', '这个杀手不太冷', ' / 杀手莱昂  /  终极追杀令(台)', 'n                            导演: 吕克·贝松 Luc Besson   主演: 让·雷诺 Jean Reno / 娜塔莉·波特曼 ...', 'n                            1994 / 法国 / 剧情 动作 犯罪n                        ', 'rating45-t', '9.4')
('4', 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p510876377.jpg', '阿甘正传', ' / 福雷斯特·冈普', 'n                            导演: Robert Zemeckis   主演: Tom Hanks / Robin Wright Penn / Gary Sinise', 'n                            1994 / 美国 / 剧情 爱情n                        ', 'rating45-t', '9.4')
('5', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p510861873.jpg', '美丽人生', ' / 一个快乐的传说(港)  /  Life Is Beautiful', 'n                            导演: 罗伯托·贝尼尼 Roberto Benigni   主演: 罗伯托·贝尼尼 Roberto Beni...', 'n                            1997 / 意大利 / 剧情 喜剧 爱情 战争n                        ', 'rating5-t', '9.5')
('6', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p457760035.jpg', '泰坦尼克号', ' / 铁达尼号(港 / 台)', 'n                            导演: 詹姆斯·卡梅隆 James Cameron   主演: 莱昂纳多·迪卡普里奥 Leonardo...', 'n                            1997 / 美国 / 剧情 爱情 灾难n                        ', 'rating45-t', '9.3')
('7', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p1606727862.jpg', '千与千寻', ' / 神隐少女(台)  /  Spirited Away', 'n                            导演: 宫崎骏 Hayao Miyazaki   主演: 柊瑠美 Rumi Hîragi / 入野自由 Miy...', 'n                            2001 / 日本 / 剧情 动画 奇幻n                        ', 'rating45-t', '9.3')
('8', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p492406163.jpg', '辛德勒的名单', ' / 舒特拉的名单(港)  /  辛德勒名单', 'n                            导演: 史蒂文·斯皮尔伯格 Steven Spielberg   主演: 连姆·尼森 Liam Neeson...', 'n                            1993 / 美国 / 剧情 历史 战争n                        ', 'rating5-t', '9.5')
('9', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p513344864.jpg', '盗梦空间', ' / 潜行凶间(港)  /  全面启动(台)', 'n                            导演: 克里斯托弗·诺兰 Christopher Nolan   主演: 莱昂纳多·迪卡普里奥 Le...', 'n                            2010 / 美国 英国 / 剧情 科幻 悬疑 冒险n                        ', 'rating45-t', '9.3')
('10', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p1461851991.jpg', '机器人总动员', ' / 瓦力(台)  /  太空奇兵·威E(港)', 'n                            导演: 安德鲁·斯坦顿 Andrew Stanton   主演: 本·贝尔特 Ben Burtt / 艾丽...', 'n                            2008 / 美国 / 爱情 科幻 动画 冒险n                        ', 'rating45-t', '9.3')
('11', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p524964016.jpg', '忠犬八公的故事', ' / 忠犬小八(台)  /  秋田犬八千(港)', 'n                            导演: 莱塞·霍尔斯道姆 Lasse Hallström   主演: 理查·基尔 Richard Ger...', 'n                            2009 / 美国 英国 / 剧情n                        ', 'rating45-t', '9.3')
('12', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p579729551.jpg', '三傻大闹宝莱坞', ' / 三个傻瓜(台)  /  作死不离3兄弟(港)', 'n                            导演: 拉库马·希拉尼 Rajkumar Hirani   主演: 阿米尔·汗 Aamir Khan / 卡...', 'n                            2009 / 印度 / 剧情 喜剧 爱情 歌舞n                        ', 'rating45-t', '9.2')
('13', 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p511146807.jpg', '海上钢琴师', ' / 声光伴我飞(港)  /  一九零零的传奇', 'n                            导演: 朱塞佩·托纳多雷 Giuseppe Tornatore   主演: 蒂姆·罗斯 Tim Roth / ...', 'n                            1998 / 意大利 / 剧情 音乐n                        ', 'rating45-t', '9.2')
('14', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p1910824951.jpg', '放牛班的春天', ' / 歌声伴我心(港)  /  唱诗班男孩', 'n                            导演: 克里斯托夫·巴拉蒂 Christophe Barratier   主演: 杰拉尔·朱诺 Géra...', 'n                            2004 / 法国 瑞士 德国 / 剧情 音乐n                        ', 'rating45-t', '9.2')
('15', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2455050536.jpg', '大话西游之大圣娶亲', ' / 西游记完结篇仙履奇缘  /  齐天大圣西游记', 'n                            导演: 刘镇伟 Jeffrey Lau   主演: 周星驰 Stephen Chow / 吴孟达 Man Tat Ng...', 'n                            1995 / 香港 中国大陆 / 喜剧 爱情 奇幻 冒险n                        ', 'rating45-t', '9.2')
('16', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p479682972.jpg', '楚门的世界', ' / 真人Show(港)  /  真人戏', 'n                            导演: 彼得·威尔 Peter Weir   主演: 金·凯瑞 Jim Carrey / 劳拉·琳妮 Lau...', 'n                            1998 / 美国 / 剧情 科幻n                        ', 'rating45-t', '9.2')
('17', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2190556185.jpg', '教父', ' / Mario Puzo's The Godfather', 'n                            导演: 弗朗西斯·福特·科波拉 Francis Ford Coppola   主演: 马龙·白兰度 M...', 'n                            1972 / 美国 / 剧情 犯罪n                        ', 'rating45-t', '9.2')
('18', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2539252713.jpg', '龙猫', ' / 邻居托托罗  /  邻家的豆豆龙', 'n                            导演: 宫崎骏 Hayao Miyazaki   主演: 日高法子 Noriko Hidaka / 坂本千夏 Ch...', 'n                            1988 / 日本 / 动画 奇幻 冒险n                        ', 'rating45-t', '9.1')
('19', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2206088801.jpg', '星际穿越', ' / 星际启示录(港)  /  星际效应(台)', 'n                            导演: 克里斯托弗·诺兰 Christopher Nolan   主演: 马修·麦康纳 Matthew Mc...', 'n                            2014 / 美国 英国 加拿大 冰岛 / 剧情 科幻 冒险n                        ', 'rating45-t', '9.2')
('20', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p1363250216.jpg', '熔炉', ' / 无声呐喊(港)  /  漩涡', 'n                            导演: 黄东赫 Dong-hyuk Hwang   主演: 孔侑 Yoo Gong / 郑有美 Yu-mi Jeong ...', 'n                            2011 / 韩国 / 剧情n                        ', 'rating45-t', '9.2')
('21', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2233971046.jpg', '无间道', ' / Infernal Affairs  /  Mou gaan dou', 'n                            导演: 刘伟强 / 麦兆辉   主演: 刘德华 / 梁朝伟 / 黄秋生', 'n                            2002 / 香港 / 剧情 犯罪 悬疑n                        ', 'rating45-t', '9.1')
('22', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p1312700744.jpg', '当幸福来敲门', ' / 寻找快乐的故事(港)  /  追求快乐', 'n                            导演: 加布里尔·穆奇诺 Gabriele Muccino   主演: 威尔·史密斯 Will Smith ...', 'n                            2006 / 美国 / 剧情 传记 家庭n                        ', 'rating45-t', '9.0')
('23', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p1454261925.jpg', '触不可及', ' / 闪亮人生(港)  /  逆转人生(台)', 'n                            导演: 奥利维·那卡什 Olivier Nakache / 艾力克·托兰达 Eric Toledano   主...', 'n                            2011 / 法国 / 剧情 喜剧n                        ', 'rating45-t', '9.2')
('24', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p663036666.jpg', '怦然心动', ' / 萌动青春  /  青春萌动', 'n                            导演: 罗伯·莱纳 Rob Reiner   主演: 玛德琳·卡罗尔 Madeline Carroll / 卡...', 'n                            2010 / 美国 / 剧情 喜剧 爱情n                        ', 'rating45-t', '9.0')
('25', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p1963126880.jpg', '乱世佳人', ' / 飘', 'n                            导演: 维克多·弗莱明 Victor Fleming / 乔治·库克 George Cukor   主演: 费...', 'n                            1939 / 美国 / 剧情 历史 爱情 战争n                        ', 'rating45-t', '9.2')

从上面的结果看到电影的星级是rating5-t、rating45-t、rating4-t这样的字符代表五星、四星半、四星等。转换代码为:

def star_transfor(str):
    if str == 'rating5-t':        return '五星'
    elif str == 'rating45-t' :        return '四星半'
    elif str == 'rating4-t':        return '四星'
    elif str == 'rating35-t' :        return '三星半'
    elif str == 'rating3-t':        return '三星'
    elif str == 'rating25-t':        return '两星半'
    elif str == 'rating2-t':        return '两星'
    elif str == 'rating15-t':        return '一星半'
    elif str == 'rating1-t':        return '一星'
    else:        return '无星'

在爬取网页时,会将图片也爬取下来,下面的代码是将每部电影的图片保存到本地:

def down_image(url,headers):
    r = requests.get(url,headers = headers)
    filename = re.search('/public/(.*?)$',url,re.S).group(1)    with open(filename,'wb') as f:
        f.write(r.content)

爬取到网页的信息后,一般会将爬取的信息保存到数据库或文本文件中,下面的代码是将爬取到的电影信息保存到文本文件中:

def write_movies_file(str):
    with open('douban_film.txt','a',encoding='utf-8') as f:
        f.write(json.dumps(str,ensure_ascii=False) + 'n')

写入文本文件用到了json库的dumps方法,该方法实现了字典的序列化,并且要指定ensure_ascii参数为False,保证中文不乱码。

write_movies_file方法传入的是一个字典的参数,因此在爬取到一部电影的信息时,需要将电影信息格式化为一个字典,代码为:

results = re.findall(regix, text, re.S)for item in results:    yield {        '电影名称' : item[2] + ' ' + re.sub(' ','',item[3]),        '导演和演员' : re.sub(' ','',item[4].strip()),        '评分': star_transfor(item[6].strip()) + '/' + item[7] + '分',        '排名' : item[0]
    }

到目前为止,我们已经实现了爬取一页电影的信息,一页包含有25部电影,250部电影有10页,之前已经提到过,改变start的值即可抓取不同页的电影,下面的代码是构造10页电影url的代码:

for offset in range(0, 250, 25):
    url = 'https://movie.douban.com/top250?start=' + str(offset) +'&filter='

爬取豆瓣电影top250的完整代码如下:

import requestsimport reimport jsondef parse_html(url):
    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="info.*?class="hd".*?class="title">(.*?).*?class="other">'             '(.*?).*?.*?(.*?)
(.*?)

.*?class="star.*?.*?'             'span class="rating_num".*?average">(.*?)'     results = re.findall(regix, text, re.S)    for item in results:         down_image(item[1],headers = headers)        yield {            '电影名称' : item[2] + ' ' + re.sub(' ','',item[3]),            '导演和演员' : re.sub(' ','',item[4].strip()),            '评分': star_transfor(item[6].strip()) + '/' + item[7] + '分',            '排名' : item[0]         }def main():     for offset in range(0, 250, 25):         url = 'https://movie.douban.com/top250?start=' + str(offset) +'&filter='         for item in parse_html(url):             print(item)             write_movies_file(item)def write_movies_file(str):     with open('douban_film.txt','a',encoding='utf-8') as f:         f.write(json.dumps(str,ensure_ascii=False) + 'n')def down_image(url,headers):     r = requests.get(url,headers = headers)     filename = re.search('/public/(.*?)$',url,re.S).group(1)    with open(filename,'wb') as f:         f.write(r.content)def star_transfor(str):     if str == 'rating5-t':        return '五星'     elif str == 'rating45-t' :        return '四星半'     elif str == 'rating4-t':        return '四星'     elif str == 'rating35-t' :        return '三星半'     elif str == 'rating3-t':        return '三星'     elif str == 'rating25-t':        return '两星半'     elif str == 'rating2-t':        return '两星'     elif str == 'rating15-t':        return '一星半'     elif str == 'rating1-t':        return '一星'     else:        return '无星'if __name__ == '__main__':     main()

总结
使用requests爬取一个网页的基本步骤:

  • 设置头信息。

  • 设置代理

  • 使用get方法爬取网页

  • 使用正则表达式提取相应的信息

  • 下载图片

  • 将爬取到的数据保存到文本文件或数据库中。

通过本文可以学习到如何使用requests库爬取网页,使用正则表达式提取网页的信息,下载图片,保存信息到文本文件中。



作者:Summer哥 
https://www.cnblogs.com/airnew/p/9981599.html


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/221413.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号