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


Posted in Python onMarch 25, 2020

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

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头像的脸上,并附文:‘拿去,速滚'

到此这篇关于python自动下载图片的方法示例的文章就介绍到这了,更多相关python 自动下载图片内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
深入Python解释器理解Python中的字节码
Apr 01 Python
ubuntu系统下 python链接mysql数据库的方法
Jan 09 Python
Python中元组,列表,字典的区别
May 21 Python
分享一下如何编写高效且优雅的 Python 代码
Sep 07 Python
Python代码缩进和测试模块示例详解
May 07 Python
kafka-python批量发送数据的实例
Dec 27 Python
python logging模块书写日志以及日志分割详解
Jul 22 Python
详解python列表(list)的使用技巧及高级操作
Aug 15 Python
Window10下python3.7 安装与卸载教程图解
Sep 30 Python
原生python实现knn分类算法
Oct 24 Python
python中的 zip函数详解及用法举例
Feb 16 Python
Python datetime 格式化 明天,昨天实例
Mar 02 Python
Python短信轰炸的代码
Mar 25 #Python
PyQt5事件处理之定时在控件上显示信息的代码
Mar 25 #Python
基于Python计算圆周率pi代码实例
Mar 25 #Python
Python异常原理及异常捕捉实现过程解析
Mar 25 #Python
Python导入模块包原理及相关注意事项
Mar 25 #Python
Python脚本导出为exe程序的方法
Mar 25 #Python
Python实现猜年龄游戏代码实例
Mar 25 #Python
You might like
CI框架学习笔记(二) -入口文件index.php
2014/10/27 PHP
PHP使用内置dir类实现目录遍历删除
2015/03/31 PHP
PHP多维数组遍历方法(2种实现方法)
2015/12/10 PHP
PHP队列场景以及实现代码实例详解
2021/02/26 PHP
jQuery 在光标定位的地方插入文字的插件
2012/05/10 Javascript
js onkeypress与onkeydown 事件区别详细说明
2012/12/13 Javascript
浅析ajax请求json数据并用js解析(示例分析)
2013/07/13 Javascript
JavaScript程序员应该知道的45个实用技巧
2014/03/04 Javascript
JavaScript更改字符串的大小写
2015/05/07 Javascript
使用jQuery处理AJAX请求的基础学习教程
2016/05/10 Javascript
以WordPress为例讲解jQuery美化页面Title的方法
2016/05/23 Javascript
jQuery仿写百度百科的目录树
2017/01/03 Javascript
一文让你彻底搞清楚javascript中的require、import与export
2017/09/24 Javascript
薪资那么高的Web前端必看书单
2017/10/13 Javascript
微信小程序button标签open-type属性原理解析
2020/01/21 Javascript
vue 动态给每个页面添加title、关键词和描述的方法
2020/08/28 Javascript
[01:43]倾听DOTA2英雄之声 魅惑魔女国服配音鉴赏
2013/06/06 DOTA
使用python实现rsa算法代码
2016/02/17 Python
Python的SimpleHTTPServer模块用处及使用方法简介
2018/01/22 Python
Python模块文件结构代码详解
2018/02/03 Python
python 将字符串完成特定的向右移动方法
2019/06/11 Python
Python matplotlib画曲线例题解析
2020/02/07 Python
Python抓包并解析json爬虫的完整实例代码
2020/11/03 Python
CSS3 filter(滤镜)实现网页灰色或者黑色模式的示例代码
2021/02/24 HTML / CSS
Keds官方网站:购买帆布运动鞋和经典皮鞋
2016/11/12 全球购物
马来西亚在线购物市场:PGMall.my
2019/10/13 全球购物
如何提高SQL Server的安全性
2016/07/25 面试题
外贸业务员的岗位职责
2013/11/23 职场文书
会计出纳岗位职责
2013/12/25 职场文书
2014年元旦活动方案
2014/02/15 职场文书
国际贸易系求职信
2014/08/09 职场文书
交通事故一次性赔偿协议书范本
2014/11/02 职场文书
酒店收银员岗位职责
2015/04/07 职场文书
2017年寒假少先队活动总结
2016/04/06 职场文书
关于销售人员的年终工作总结要点
2019/08/15 职场文书
mysql数据库如何转移到oracle
2022/12/24 MySQL