python自动下载图片的方法示例

作者:^_^影 时间:2022-01-03 06:32:44 

近日闲来无事,总有一种无形的力量萦绕在朕身边,让朕精神涣散,昏昏欲睡。

python自动下载图片的方法示例

可是,像朕这么有职业操守的社畜怎么能在上班期间睡瞌睡呢,我不禁陷入了沉思。。。。

python自动下载图片的方法示例

突然旁边的IOS同事问:‘嘿,兄弟,我发现一个网站的图片很有意思啊,能不能帮我保存下来提升我的开发灵感?'
作为一个坚强的社畜怎么能说自己不行呢,当时朕就不假思索的答应:‘oh, It's simple. Wait for me a few minute.'

python自动下载图片的方法示例

点开同事给的图片网站,

网站大概长这样:

python自动下载图片的方法示例

在朕翻看了几十页之后,朕突然觉得有点上头。心中一想'不对啊,朕不是来学习的吗?可是看美女图片这个事情怎么才可以和学习关联起来呢‘

python自动下载图片的方法示例

冥思苦想一番之后,突然脑中灵光一闪,'要不用python写个爬虫吧,将此网站的图片一网打尽‘。

python自动下载图片的方法示例

说干就干,身体力行,要问爬虫哪家强,‘人生苦短,我用python'。

首先找到我的电脑里面半年前下载的python安装包,无情的点击了安装,环境装好之后,略一分析网页结构。先撸一个简易版爬虫


#抓取爱小姐姐网图片保存到本地
import requests
from lxml import etree as et
import os

#请求头
headers = {
 #用户代理
 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}

#待抓取网页基地址
base_url = ''
#保存图片基本路径
base_dir = 'D:/python/code/aixjj/'
#保存图片
def savePic(pic_url):
 #如果目录不存在,则新建
 if not os.path.exists(base_dir):
   os.makedirs(base_dir)

arr = pic_url.split('/')
 file_name = base_dir+arr[-2]+arr[-1]
 print(file_name)
 #获取图片内容
 response = requests.get(pic_url, headers = headers)
 #写入图片
 with open(file_name,'wb') as fp:
   for data in response.iter_content(128):
     fp.write(data)

#观察此网站总共只有62页,所以循环62次
for k in range(1,63):
 #请求页面地址
 url = base_url+str(k)
 response = requests.get(url = url, headers = headers)
 #请求状态码
 code = response.status_code
 if code == 200:
   html = et.HTML(response.text)
   #获取页面所有图片地址
   r = html.xpath('//li/a/img/@src')
   #获取下一页url
   #t = html.xpath('//div[@class="page"]/a[@class="ch"]/@href')[-1]
   for pic_url in r:
     a = 'http:'+pic_url
     savePic(a)
 print('第%d页图片下载完成' % (k))

print('The End!')

尝试运行爬虫,嘿,没想到行了:

python自动下载图片的方法示例

python自动下载图片的方法示例

过了一会儿,旁边的哥们儿又来:‘嘿 bro 你这个可以是可以,就是速度太慢了啊,我的灵感会被长时间的等待磨灭,你给改进改进?'

python自动下载图片的方法示例

怎么提升爬虫的效率呢?略一思索,公司的电脑可是伟大的四核CPU啊,要不撸个多进程版本试试。然后就产生了下面这个多进程版本


#多进程版——抓取爱小姐姐网图片保存到本地

import requests
from lxml import etree as et
import os
import time
from multiprocessing import Pool

#请求头
headers = {
 #用户代理
 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}

#待抓取网页基地址
base_url = ''
#保存图片基本路径
base_dir = 'D:/python/code/aixjj1/'

#保存图片
def savePic(pic_url):
 #如果目录不存在,则新建
 if not os.path.exists(base_dir):
   os.makedirs(base_dir)

arr = pic_url.split('/')
 file_name = base_dir+arr[-2]+arr[-1]
 print(file_name)
 #获取图片内容
 response = requests.get(pic_url, headers = headers)
 #写入图片
 with open(file_name,'wb') as fp:
   for data in response.iter_content(128):
     fp.write(data)

def geturl(url):
 #请求页面地址
 #url = base_url+str(k)
 response = requests.get(url = url, headers = headers)
 #请求状态码
 code = response.status_code
 if code == 200:
   html = et.HTML(response.text)
   #获取页面所有图片地址
   r = html.xpath('//li/a/img/@src')
   #获取下一页url
   #t = html.xpath('//div[@class="page"]/a[@class="ch"]/@href')[-1]
   for pic_url in r:
     a = 'http:'+pic_url
     savePic(a)

if __name__ == '__main__':
 #获取要爬取的链接列表
 url_list = [base_url+format(i) for i in range(1,100)]
 a1 = time.time()
 #利用进程池方式创建进程,默认创建进程数量=电脑核数
 #自己定义进程数量方式 pool = Pool(4)
 pool = Pool()
 pool.map(geturl,url_list)
 pool.close()
 pool.join()
 b1 = time.time()
 print('运行时间:',b1-a1)

抱着试一试的心态,运行了多进程版本爬虫,嘿没想到又行了,在朕伟大的四核CPU的加持下,爬虫速度提升了3~4倍。
又过了一会儿,那哥们儿又偏过头来:‘你这个快是快了不少,但是还不是最理想的状态,能不能一眨眼就能爬取百八十个图片,毕竟我的灵感来的快去的也快'

我:‘…'
悄悄打开Google,搜索如何提升爬虫效率,给出结论:

多进程:密集CPU任务,需要充分使用多核CPU资源(服务器,大量的并行计算)的时候,用多进程。
多线程:密集I/O任务(网络I/O,磁盘I/O,数据库I/O)使用多线程合适。

呵,我这可不就是I/O密集任务吗,赶紧写一个多线程版爬虫先。于是,又诞生了第三款:


import threading # 导入threading模块
from queue import Queue #导入queue模块
import time #导入time模块
import requests
import os
from lxml import etree as et

#请求头
headers = {
 #用户代理
 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}
#待抓取网页基地址
base_url = ''
#保存图片基本路径
base_dir = 'D:/python/code/aixjj/'

#保存图片
def savePic(pic_url):
 #如果目录不存在,则新建
 if not os.path.exists(base_dir):
   os.makedirs(base_dir)

arr = pic_url.split('/')
 file_name = base_dir+arr[-2]+arr[-1]
 print(file_name)
 #获取图片内容
 response = requests.get(pic_url, headers = headers)
 #写入图片
 with open(file_name,'wb') as fp:
   for data in response.iter_content(128):
     fp.write(data)

# 爬取文章详情页
def get_detail_html(detail_url_list, id):
 while True:
   url = detail_url_list.get() #Queue队列的get方法用于从队列中提取元素
   response = requests.get(url = url, headers = headers)
   #请求状态码
   code = response.status_code
   if code == 200:
     html = et.HTML(response.text)
     #获取页面所有图片地址
     r = html.xpath('//li/a/img/@src')
     #获取下一页url
     #t = html.xpath('//div[@class="page"]/a[@class="ch"]/@href')[-1]
     for pic_url in r:
       a = 'http:'+pic_url
       savePic(a)

# 爬取文章列表页
def get_detail_url(queue):
 for i in range(1,100):
   #time.sleep(1) # 延时1s,模拟比爬取文章详情要快
   #Queue队列的put方法用于向Queue队列中放置元素,由于Queue是先进先出队列,所以先被Put的URL也就会被先get出来。
   page_url = base_url+format(i)
   queue.put(page_url)
   print("put page url {id} end".format(id = page_url))#打印出得到了哪些文章的url

#主函数
if __name__ == "__main__":
 detail_url_queue = Queue(maxsize=1000) #用Queue构造一个大小为1000的线程安全的先进先出队列
 #A线程负责抓取列表url
 thread = threading.Thread(target=get_detail_url, args=(detail_url_queue,))
 html_thread= []
 #另外创建三个线程负责抓取图片
 for i in range(20):
   thread2 = threading.Thread(target=get_detail_html, args=(detail_url_queue,i))
   html_thread.append(thread2)#B C D 线程抓取文章详情
 start_time = time.time()
 # 启动四个线程
 thread.start()
 for i in range(20):
   html_thread[i].start()
 # 等待所有线程结束,thread.join()函数代表子线程完成之前,其父进程一直处于阻塞状态。
 thread.join()
 for i in range(20):
   html_thread[i].join()
 print("last time: {} s".format(time.time()-start_time))#等ABCD四个线程都结束后,在主进程中计算总爬取时间。

粗略测试一下,得出结论: ‘Oh my god,这也太快了吧'。
将多线程版本爬虫扔到同事QQ头像的脸上,并附文:‘拿去,速滚'

来源:https://blog.csdn.net/weixin_39815001/article/details/103779788

标签:python,自动下载,图片
0
投稿

猜你喜欢

  • 15个Pythonic的代码示例(值得收藏)

    2022-07-27 21:21:19
  • python定义类self用法实例解析

    2022-01-08 14:11:01
  • asp如何防止计数器刷新计数?

    2009-11-22 19:19:00
  • go语言beego框架web开发语法笔记示例

    2024-05-21 10:25:22
  • Python中使用第三方库xlrd来写入Excel文件示例

    2023-08-16 21:37:29
  • MySQL系列之九 mysql查询缓存及索引

    2024-01-22 12:46:10
  • Python进程间通信方式

    2021-12-03 03:08:39
  • win10 mysql导出csv的两种方式

    2024-01-22 08:27:11
  • Python semaphore evevt生产者消费者模型原理解析

    2021-11-14 12:52:39
  • MySQL中对于not in和minus使用的优化

    2024-01-17 04:17:20
  • Jupyter安装拓展nbextensions及解决官网下载慢的问题

    2023-11-24 20:50:54
  • django框架如何集成celery进行开发

    2022-09-13 11:18:24
  • SQL Server使用T-SQL进阶之公用表表达式(CTE)

    2024-01-17 22:42:32
  • 解决PHP 7编译安装错误:cannot stat ‘phar.phar’: No such file or directory

    2023-09-05 06:07:44
  • SQL子查询全接触

    2007-08-20 10:51:00
  • Python Tornado批量上传图片并显示功能

    2023-08-07 22:33:21
  • Go实现MD5加密的三种方法小结

    2024-02-08 03:47:37
  • MySQL查询优化:连接查询排序limit(join、order by、limit语句)介绍

    2024-01-21 19:06:16
  • python自制包并用pip免提交到pypi仅安装到本机【推荐】

    2023-12-14 19:33:23
  • Vue中列表渲染指令v-for的基本用法详解

    2024-05-28 15:52:06
  • asp之家 网络编程 m.aspxhome.com