题目👇
利用urllib模块+正则表达式爬取http://tieba.baidu.com/p/2460150866页面中的所有图片,保存到本地
思路分析👇
本题的核心就是python3中urllib.request模块提供的urlretrieve()函数。
👉urlretrieve()方法可以实现直接将远程数据下载到本地
函数urlretrieve(url, filename=None, reporthook=None, data=None) | |
---|---|
参数名称 | 参数意义 |
url | 下载链接地址 |
filename | 指定了保存本地路径(如果参数未指定,urllib会生成一个临时文件保存数据。) |
reporthook | 是一个回调函数,当连接上服务器、以及相应的数据块传输完毕时会触发该回调,我们可以利用这个回调函数来显示当前的下载进度。 |
data | post导服务器的数据,该方法返回一个包含两个元素的(filename, headers) 元组,filename 表示保存到本地的路径,header表示服务器的响应头 |
因此我们需要为最终的urlretrieve这步操作准备这些参数。
图片的url也就是下载地址,它来自html代码的img标签内的src参数。
所以我们首先要获得目标网址的全部源代码,在此基础之上我们再用正则表达式对html代码适当进行过滤得到url下载地址。
最后filenamere和reporthook回调函数我们都可以自由发挥。
代码示例👇
#coding:utf-8
#author:Mitchell
#task:利用urllib模块+正则表达式爬取http://tieba.baidu.com/p/2460150866 页面中的所有图片,保存到本地
import urllib.request
import re
#回调函数,打印下载进度
def callback(a1,a2,a3):
#必须有三个参数
#参数@a1:目前为此传递的数据块数量
#参数@a2:每个数据块的大小,单位是字节byte
#参数@a3:远程文件的大小
download_pg = 100.0*a1*a2/a3
if download_pg > 100:
download_pg = 100
print("%.2f%%" %download_pg,)
#获得目标网页全部源代码
def getHtml(url):
#目标头部信息
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36'
}
#url作为Request()方法的参数,构造并返回一个符合headers要求的Request对象
req = urllib.request.Request(url, headers=headers)
#Request对象作为urlopen()方法的参数,发送给服务器并接收响应
fp = urllib.request.urlopen(req)
#读取指定网页全部源代码并解码
htmlCode = fp.read().decode()
#返回文本
return htmlCode
#获得下载地址并进行下载
def getImg(htmlCode):
'''
. 除换行符外的任意字符
+ -- 匹配位于+之前的字符或子模式的1次或多次出现,
?-- 匹配位于?之前的0个或1个字符,用于表示非贪心模式
举例:'src=".+?"'匹配 src=" 开始,以 " 结束的尽可能短的字符串。且开始和结束中间必须有字符,因为+表示1到多个。
所以匹配<img src="test.jpg" width="60px" height="80px"/>时,会匹配出src="test.jpg"
<img src="test.jpg" pic_ext width="60px" height="80px"/><img src="test1.jpg" pic_ext width="60px" height="80px"/>
'src="(.+?\.jpg)"' 匹配 src=" 开始,以 .jpg" 结束的尽可能短的字符串。可以把所有src="...."中的地址匹配出来
'''
#构建正则表达式对象
reg = r'src="(.+?\.jpg)" pic_ext'
imgre = re.compile(reg)
imglist = imgre.findall(htmlCode) #如果正则表达式带子模式,findall返回括号中匹配的
#计数变量,用于命名
x=0
#图片存放的目录,默认空串为当前目录
paths = ""
for imgurl in imglist:
#urlretrieve()函数解析
#urllib.request.urlretrieve(url,filename=None,reporthook=None,data=None)
#参数@url:远程服务器地址(即需要获取数据的地址)
#参数@filename:将远程获取的数据存放入的文件名
#参数@reporthook:是一个回调函数,当连接上服务器、以及相应的数据块传输完毕的时候会触发该回调。我们可以利用这个回调函数来显示当前的下载进度。
#参数@data:指post到服务器的数据。
urllib.request.urlretrieve(imgurl,'{}{}.jpg'.format(paths,x), callback)
x = x + 1
htmlCode = getHtml("http://tieba.baidu.com/p/2460150866")
getImg(htmlCode)
print("————————END————————")