Python爬虫之多线程下载豆瓣Top250电影图片
爬虫项目介绍
本次爬虫项目将爬取豆瓣Top250电影的图片,其网址为:https://movie.douban.com/top250, 具体页面如下图所示:
本次爬虫项目将分别不使用多线程和使用多线程来完成,通过两者的对比,显示出多线程在爬虫项目中的巨大优势。本文所使用的多线程用到了concurrent.futures模块,该模块是Python中最广为使用的并发库,它可以非常方便地将任务并行化。在concurrent.futures模块中,共有两种并发模块,分别如下:
- 多线程模式:ThreadPoolExecutor,适合 IO密集型任务;
- 多进程模式:ProcessPoolExecutor,适合计算密集型任务。
具体的关于该模块的介绍可以参考其官方网址:https://docs.python.org/3/library/concurrent.futures.html 。
本次爬虫项目将会用到concurrent.futures模块中的ThreadPoolExecutor类,多线程下载豆瓣Top250电影图片。下面将会给出本次爬虫项目分别不使用多线程和使用多线程的对比,以此来展示多线程在爬虫中的巨大优势。
不使用多线程
首先,我们不使用多线程来下载豆瓣Top250电影图片,其完整的Python代码如下:
import time import requests import urllib.request from bs4 import BeautifulSoup # 该函数用于下载图片 # 传入函数: 网页的网址url def download_picture(url): # 获取网页的源代码 r = requests.get(url) # 利用BeautifulSoup将获取到的文本解析成HTML soup = BeautifulSoup(r.text, "lxml") # 获取网页中的电影图片 content = soup.find('div', class_='article') images = content.find_all('img') # 获取电影图片的名称和下载地址 picture_name_list = [image['alt'] for image in images] picture_link_list = [image['src'] for image in images] # 利用urllib.request..urlretrieve正式下载图片 for picture_name, picture_link in zip(picture_name_list, picture_link_list): urllib.request.urlretrieve(picture_link, 'E://douban/%s.jpg' % picture_name) def main(): # 全部10个网页 start_urls = ["https://movie.douban.com/top250"] for i in range(1, 10): start_urls.append("https://movie.douban.com/top250?start=%d&filter=" % (25 * i)) # 统计该爬虫的消耗时间 t1 = time.time() print('*' * 50) for url in start_urls: download_picture(url) t2 = time.time() print('不使用多线程,总共耗时:%s'%(t2-t1)) print('*' * 50) main()
其输出结果如下:
************************************************** 不使用多线程,总共耗时:79.93260931968689 **************************************************
去E盘中的douban文件夹查看,如下图:
我们可以看到,在不使用多线程的情况下,这个爬虫总共耗时约80s,完成了豆瓣Top250电影图片的下载。
使用多线程
接下来,我们使用多线程来下载豆瓣Top250电影图片,其完整的Python代码如下:
import time import requests import urllib.request from bs4 import BeautifulSoup from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED # 该函数用于下载图片 # 传入函数: 网页的网址url def download_picture(url): # 获取网页的源代码 r = requests.get(url) # 利用BeautifulSoup将获取到的文本解析成HTML soup = BeautifulSoup(r.text, "lxml") # 获取网页中的电影图片 content = soup.find('div', class_='article') images = content.find_all('img') # 获取电影图片的名称和下载地址 picture_name_list = [image['alt'] for image in images] picture_link_list = [image['src'] for image in images] # 利用urllib.request..urlretrieve正式下载图片 for picture_name, picture_link in zip(picture_name_list, picture_link_list): urllib.request.urlretrieve(picture_link, 'E://douban/%s.jpg' % picture_name) def main(): # 全部10个网页 start_urls = ["https://movie.douban.com/top250"] for i in range(1, 10): start_urls.append("https://movie.douban.com/top250?start=%d&filter=" % (25 * i)) # 统计该爬虫的消耗时间 print('*' * 50) t3 = time.time() # 利用并发下载电影图片 executor = ThreadPoolExecutor(max_workers=10) # 可以自己调整max_workers,即线程的个数 # submit()的参数: 第一个为函数, 之后为该函数的传入参数,允许有多个 future_tasks = [executor.submit(download_picture, url) for url in start_urls] # 等待所有的线程完成,才进入后续的执行 wait(future_tasks, return_when=ALL_COMPLETED) t4 = time.time() print('使用多线程,总共耗时:%s' % (t4 - t3)) print('*' * 50) main()
其输出结果如下:
************************************************** 使用多线程,总共耗时:9.361606121063232 **************************************************
再去E盘中的douban文件夹查看,发现同样也下载了250张电影图片。
总结
通过上述两个爬虫程序的对比,我们不难发现,同样是下载豆瓣Top250电影,10个网页中的图片,在没有使用多线程的情况下,总共耗时约80s,而在使用多线程(10个线程)的情况下,总共耗时约9.5秒,效率整整提高了约8倍。这样的效率提升在爬虫中无疑是令人兴奋的。
希望读者在看了本篇博客后,也能尝试着在自己的爬虫中使用多线程,说不定会有意外的惊喜哦~~因为,大名鼎鼎的Python爬虫框架Scrapy,也是使用多线程来提升爬虫速度的哦!
注意:本人现已开通两个微信公众号: 因为Python(微信号为:python_math)以及轻松学会Python爬虫(微信号为:easy_web_scrape), 欢迎大家关注哦~~

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
JavaScript 基础 --- (数据类型/循环/条件)
一、js 输出1.window.alert() 警告框 2.document.write() 写到 HTML 文档中 3.innerHTML 写到 HTML 元素 4.console.log() 写到浏览器的控制台 二、js 语句与注释 1. ; (var a = 1;) ;表示语句的结尾 2. 语句标识符:var / if / for 等 3.注释:单行 // 多行 /* */三、数据类型 1.未定义 (undefined) var x; //x 为 undefined(表示变量不含有值) 2.数字 (Number) var y = 5; //y 为数字 3.字符串 (String) var z = "John" // z为字符串 4.布尔 (Boolean) var a = true; //a 为 布尔类型 5.对象 (Object) var person ={firstname:"John",lastname:"Doe",id:5566}; 取值:console.log(person.firstname) console.log(pe...
- 下一篇
Python集训营
第8哥博客 http://blog.51cto.com/de8ug/2087144 知识在于点滴积累
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Windows10,CentOS7,CentOS8安装Nodejs环境
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Linux系统CentOS6、CentOS7手动修改IP地址
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16