【爬虫军火库】下载保存图片(文件)
今天开始开一个新坑,暂且叫做【爬虫军火库】吧。以前一直想系统地写些东西,最终大都未能成文,想来我不适合发宏愿立长志,还是一步一个脚印地写点零碎的东西。有关爬虫,以后会写很多东西,写完以后再进行梳理好了。
之所以要写军火库,是因为在写爬虫的过程中,遇到过很多重复性的工作。即便是Python的社区环境已经提供了很多很方便的第三方库,在实际操作中也难免需要根据不同情况做很多具体的分析。所以接下来要写的这个系列,会很像一个utils,记录一些小而实用、可复用的代码段,有些时候不会去关注前因后果,只是简简单单地聚焦在一个很小的功能上。仅此而已。
是为短序。
军火库这个系列没有严格顺序,想到什么、遇到什么,就会及时地写下来。
昨天在后台收到一个提问:
于是今天我们先来写一下下载、保存图片(文件)的方法。
假设现在已有一个图片(文件)的网址,如何保存到本地。
1、最简便的办法,使用urllib.request.urlretrieve
用法:urlretrieve(url, filename=None, reporthook=None, data=None)
示例1:http://placekitten.com/500/600 这是一个提供猫片的网站,你只需要修改之后的两个数字就可以获取相应宽高比的小猫图片。
现在要将这张图片下载到本地:
import urllib.request
url = 'http://placekitten.com/500/600'
urllib.request.urlretrieve(url, 'cat_img.jpg')
示例2:下载新浪财经年报PDF 如http://vip.stock.finance.sina.com.cn/corp/view/vCB_AllBulletinDetail.php?stockid=000048&id=712408
import urllib.request
url = 'http://file.finance.sina.com.cn/211.154.219.97:9494/MRGG/CNSESZ_STOCK/2011/2011-4/2011-04-26/712408.PDF'
urllib.request.urlretrieve(url, '712408.pdf')
2、请求获取bytes后自己建文件存
还是前面的示例1,可以写成:
import requests
url = 'http://placekitten.com/500/600'
r = requests.get(url).content #这里也可以用urllib.request.urlopen()方法
f = open('cat_img.jpg', 'wb')
f.write(r)
f.close()
这样写自然是不如之前的一行代码解决问题来的方便,但是这样有一个好处,就是方便解决网络请求的问题。尤其是使用requests库时,无论是添加headers还是添加proxies,都十分方便。
举个栗子。各家爬虫文章最喜欢写的入门网站,妹子图(排第二的可能是煎蛋?),现在新加了反盗链的措施,说白了就是要验证请求头中的Referer字段。这是如果直接用urlretrieve就会获取到这样的结果:
于是我们需要这么来做:
import requests
headers = {'Referer': 'http://www.mzitu.com/'}
url = 'http://i.meizitu.net/2015/12/05m01.jpg'
r = requests.get(url, headers=headers).content
f = open('mzitu.jpg', 'wb')
f.write(r)
f.close()
3、解决urlretrieve添加headers的问题
前面的方法2中说到,urlretrieve不方便添加headers,但是并不是不能添加。如果一定要用的话,就需要构建opener。
import urllib.request
url = 'http://i.meizitu.net/2015/12/05m01.jpg'
opener=urllib.request.build_opener()
opener.addheaders = [('Referer', 'http://www.mzitu.com/')]
urllib.request.install_opener(opener)
urllib.request.urlretrieve(url, 'mzitu.jpg')
一般来说大概就是这些问题了。常用到的可以写成函数,以便以后调用。还有一个问题就是,在具体拼接储存路径时经常需要用到字符串的split方法,结合os.getcwd(),os.mkdir(),os.chdir()等。
最后回到最初的问题,为什么加了Referer都没有获取到图片呢?其实是个乌龙,我看了这位朋友的代码,其中有这么一行:
rsp = requests.get(url_real, headers).content
需要注意的是,这么写其实没有把headers添加进去。
我们可以用inspect来查看requests.get()方法所需的参数。
所以在添加headers时一定要写成:
rsp = requests.get(url_real, headers=headers).content
最后插句题外话,后台的自动回复又打开了,图片识别的接口有问题还在调,所以识图功能暂时用不了,会尽快想办法的。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法