使用Python获取页面图片信息并下载图片

2017-07-22  本文已影响195人  夜之魔

近期个人需要在一些网页上获取图片,因一张张图片保存实在麻烦,研究了下使用Python自动化获取并下载图片,以下是研究历程:

获取HTML源代码

importurllibimporturllib2header={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36","Connection":"keep-alive","Referer":"http://yoururl","Accept":"application/json, text/plain, */*"}#  设置请求的header

首先获得HTML的结构

使用urllib:

defgetHtml(url):page=urllib.urlopen(url)html=page.read()returnhtml

但是这样无法设置headers,使用urllib2可解决:

defgetHtml(url):req=urllib2.Request(url,headers=header)html=urllib2.urlopen(req)htmlData=html.read()print'解析成功!'# with open('test.txt', 'w') as f:# f.write(htmlData)returnhtmlData

拿到HTML源码后即可根据正则获取图片的src,将图片的src用列表保存,如

urllist= ['123456.jpg','aa.jpg']

请求图片链接并下载到本地

对urllist循环进行请求,使用urllib.urlretrieve可直接下载,无需发动请求:

x=0forimgurlinimglist:urllib.urlretrieve(imgurl,'%s.jpg'%x)#打开imglist中保存的图片网址,并下载图片保存在本地x=x+1

经实际测试,使用urllib.urlretrieve仅可以下载同步渲染的图片,如百度贴吧的图片,对于需要长时间加载出来的图片则会出现下载的图片在本地无法预览的提示,而且urllib.urlretrieve使用的默认python的header,肯定拿到不图片。

改进:使用urllib2.urlopen发起请求,再使用f.write保存图片到本地:

forimgurlinimglist:x=x+1request=urllib2.Request(imgurl,None,header)#设置请求头部response=urllib2.urlopen(request)withopen("%s.jpg"%x,"wb")asf:f.write(response.read())

添加实时进度条

通过urllib2.urlopen解决请求图片+下载图片的功能,不过这个方法有个缺陷,如果需要添加下载进度条功能,使用如下代码添加进度条,会出现进度条状态和f.write不同步的情况,原因是urllib2.urlopen拿回来的数据是一次性写到f.write里面的:

defchunk_report(bytes_so_far,chunk_size,total_size):percent=float(bytes_so_far)/total_sizepercent=round(percent*100,2)sys.stdout.write("Downloaded%d of%d bytes (%0.2f%%)\r"%(bytes_so_far,total_size,percent))ifbytes_so_far>=total_size:sys.stdout.write('\n')defchunk_read(resp,chunk_size=1024,report_hook=None):total_size=resp.info().getheader('Content-Length').strip()# 获得response的数据长度total_size=int(total_size)bytes_so_far=0while1:chunk=resp.read(chunk_size)bytes_so_far+=len(chunk)ifnotchunk:breakifreport_hook:report_hook(bytes_so_far,chunk_size,total_size)defgetImg(html):forimgurlinimglist:x=x+1request=urllib2.Request(imgurl,None,header)#设置请求头部response=urllib2.urlopen(request)chunk_read(response,report_hook=chunk_report)#无效withopen("%s.jpg"%x,"wb")asf:f.write(response.read())

为了让response的数据用流的形式写入文件,就需要使用requests模块了,同时进度条可以使用现成的progressbar模块,具体如下:

# -*- coding: utf-8 -*-importreimportsysimportrequestsimportprogressbarimporturllib2header={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36","Connection":"keep-alive","Referer":"http://cl.xias.pw/htm_data/16/1707/2509191.html","Accept":"application/json, text/plain, */*"}defgetHtml(url):req=urllib2.Request(url,headers=header)html=urllib2.urlopen(req)htmlData=html.read()print'解析成功!'# with open('test.txt', 'w') as f:# f.write(htmlData)returnhtmlDatadefgetImg(html):reg=r"

小结

这个小项目从简单的urllib应用到最后requests数据流的改进,有以下知识点:

urllib.urlretrieve发起的请求是使用Python默认的headers,如果需要改动headers,则需要使用urllib2.urlopen发起请求

urllib2.urlopen拿到的数据无法已数据流的形式给开发者使用

response返回的Content-Length,urllib2和requests的结构展示方式不同,urllib2使用response.info().getheader('Content-Length').strip()获得,requests使用response.headers.get("Content-Length")

requests是实现了urllib和urllib2功能的http模块,简单的应用场景可以直接使用urllib,复杂的场景使用requests为佳.

上一篇 下一篇

猜你喜欢

热点阅读