【Python】利用urllib模块+正则表达式爬取贴吧图片

本篇博客介绍了如何利用Python的urllib.request模块结合正则表达式,从指定的百度贴吧帖子中抓取所有图片URL,并将其下载保存到本地。通过设置User-Agent避免反爬,使用回调函数显示下载进度,正则表达式匹配img标签的src属性,最后调用urlretrieve()函数下载图片。
摘要由CSDN通过智能技术生成

题目👇

利用urllib模块+正则表达式爬取http://tieba.baidu.com/p/2460150866页面中的所有图片,保存到本地

思路分析👇

本题的核心就是python3中urllib.request模块提供的urlretrieve()函数

👉urlretrieve()方法可以实现直接将远程数据下载到本地

函数urlretrieve(url, filename=None, reporthook=None, data=None)
参数名称参数意义
url下载链接地址
filename指定了保存本地路径(如果参数未指定,urllib会生成一个临时文件保存数据。)
reporthook是一个回调函数,当连接上服务器、以及相应的数据块传输完毕时会触发该回调,我们可以利用这个回调函数来显示当前的下载进度。
datapost导服务器的数据,该方法返回一个包含两个元素的(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————————")

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mitch311

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值