前面我们可以爬取网页了,爬取网页之后我们就可以获取网页上的各种资源,比如图片。至于下载,主要用到urllib模块的urlretrieve方法,这个方法可以直接将远程数据下载到本地。
urllib.urlretrieve(url[, filename[, reporthook[, data]]])
参数说明:
url:外部或者本地url
filename:指定了保存到本地的路径(如果未指定该参数,urllib会生成一个临时文件来保存数据);
reporthook:是一个回调函数,当连接上服务器、以及相应的数据块传输完毕的时候会触发该回调。我们可以利用这个回调函数来显示当前的下载进度。
data:指post到服务器的数据。该方法返回一个包含两个元素的元组(filename, headers),filename表示保存到本地的路径,header表示服务器的响应头。
一、下面以Python3.6.1爬取百度贴吧(http://tieba.baidu.com/p/2460150866)的图片并下载到指定目录为例
首先,查看网页源代码,观察到,图片的特征基本是这样的(这里只截取部分):<img src=".......jpg" pic_etx=.....>,每张图片都有一个链接
所以我们在代码中只要获取到这些链接并下载到指定目录就可以了。
'''
Created on 2017-4-17
@author: Administrator
'''
import urllib.request
import re
def gethtml(url):
html=urllib.request.urlopen(url)
data=html.read()
return data.decode("utf-8")
def getimg(html):
dir="D:\\images\\" #图片保存路径
reg='src="(.+?\.jpg)" pic_ext'
imgreg=re.compile(reg)
imglist=imgreg.findall(html)
x=0
for i in imglist:
print(i)
urllib.request.urlretrieve(i,'{}{}.jpg'.format(dir, x))
x=x+1
html=gethtml("http://tieba.baidu.com/p/2460150866")
getimg(html)
进入D盘的images目录,可以看到图片已经全部下载下来了:
控制台同时打印出图片的路径:
二、再以Python3.6.1爬取淘宝网首页(http://taobao.com/)的图片并下载到指定目录为例:
还是先查看源代码,可以看到图片格式有jpg,gif,png,并且图片的路径都是//.......(此处省略路径名,见下截图).jpg(png,gif)这种形式:
这种形式用正则表达式匹配应该是//(.*?\.(jpg|png|gif)),但是由于是从前往后匹配,如匹配"//abcd "img:" //12.jpg"得到的就不是12.jpg,而是abcd "img:" //12.jpg,为了避免这种情况,我用了递归的方法,直到最后的字符串不含有//为止(如有更好的方法,烦请各位大神给出,我已经用了?避免贪婪匹配,但得到的还不是最短的)。代码如下:
<span style="color:#330099">'''
Created on 2017-4-18
@author: Administrator
'''
import urllib.request
import re
import os
def getHtml(url):
webpage=urllib.request.urlopen(url)
html=webpage.read()
html=html.decode("utf-8")
return html
def getImg(html):
#reg='"img":"(.+\.(jpg|png))","tce_rule_count":"1"}'
path="D:\\images\\"
reg='//(.*?\.(jpg|png|gif))'
imgreg=re.compile(reg)
imglist=imgreg.findall(html)
x=0
for i in imglist:
u=fun1(i[0])
if u=="g.alicdn.com/s.gif" or u=="i4/T1KxCMXeNjXXXXXXXX-14-14.gif":#这两个路径发现找不到图片,程序会终止,所以去掉了
x=x+1
continue
url="http://"+u
urllib.request.urlretrieve(url, "{}{}.{}".format(path,x,i[1]))
print(u)
x=x+1
def fun1(m):
s=''.join(m)
y=s.find("//")
if y==-1:
return s
else:
reg='//(.*?\.(jpg|png|gif))'
imgreg=re.compile(reg)
imglist=imgreg.findall(s)
#print(imglist[0])
return fun1(imglist[0][0])
html=getHtml("https://www.taobao.com/")
getImg(html)
</span>
进入之前清空过的D:\\images\\目录:
同时控制台打印出图片路径:
三、下面综合上述来获取淘宝网首页的子链接里面的图片。思路是先获取所有链接,再获取链接里面的图片。代码如下:
<span style="color:#330099">'''
Created on 2017-4-19
@author: Administrator
'''
import urllib.request
import re
def getHtml(url):
html=urllib.request.urlopen(url)
data=html.read()
return data.decode("utf-8")
def getHtml1(url):#可以发现子链接里面的编码是gbk
html=urllib.request.urlopen(url)
data=html.read()
return data.decode("gbk")
def getLink(html):
reg='<a href="(.*?\.htm)" target='
linkreg=re.compile(reg)
linklist=linkreg.findall(html)
for i in linklist:
url="http:"+i
#getImg(getHtml1(url))
print(url)
def getImg(html):
path="D:\\images\\"
reg='//(.*?\.(jpg|png|gif))'
imgreg=re.compile(reg)
imglist=imgreg.findall(html)
x=0
for i in imglist:
u=fun1(i[0])
#这两个路径发现找不到图片,程序会终止,所以去掉了
if u=="g.alicdn.com/s.gif" or u=="i4/T1KxCMXeNjXXXXXXXX-14-14.gif":
x=x+1
continue
url="http://"+u
urllib.request.urlretrieve(url, "{}{}.{}".format(path,x,i[1]))
print(u)
x=x+1
def fun1(m):
s=''.join(m)
y=s.find("//")
if y==-1:
return s
else:
reg='//(.*?\.(jpg|png|gif))'
imgreg=re.compile(reg)
imglist=imgreg.findall(s)
#print(imglist[0])
return fun1(imglist[0][0])
html=getHtml("http://www.taobao.com/")
getLink(html)
</span>