Python 正则表达式爬取网站图片

3 篇文章 0 订阅
3 篇文章 0 订阅

使用正则表达式和 requests 模块

前要知识

所需模块学习路径
rere模块知识总结
requestsrequest模块学习路径

通过 re 和 requests 模块便可完成简单的图片爬取功能。

行动开始
我们以素材8网站为例,对素材8首页存在的图片进行爬取。

# 首先导入我们所需要用到的包
import re
import requests
# get 是request里的一个方法 它的意思是:从指定的资源请求数据。
ret = requests.get("https://www.sucai8.com/")
# 这里的ret.text是将请求到的数据转化为文本格式读取,其实也就是页面的html代码内容
# 具体的输出内容就不进行展示了,感兴趣可以动手尝试
print(ret.text)

这里加一点点的前端知识:一个网页里面的所有元素都有它们自己的标签,图片对应的标签格式是 < img 内置元素 /> ,这里我通过将文本导入 Linux,并用 grep 方法过滤出所有的图片标签:
在这里插入图片描述
通过 Linux 对文本内容进行选中处理后,我仔细看了所有的图片内容格式标签,对内容进行判断: src 是图片存放的路径,后面有 alt,width,class 等对图片进行设置的内置元素,因此我产生了初步的正则表达式的想法:

# 使用正则表达式断言(这个是正则表达式中挺有意思的部分,后续会专门出一期讲解)
rets_1 = re.findall(r'(?<=<img src=")(.+)(?=" (?:alt=.+>|width.+>|class.+/>))', ret.text)
# 通过使用断言设置图片存放路径的左边内容格式和右边格式内容对其的路径进行匹配  我们来尝试看一下得到的结果
print(rets_1)

在这里插入图片描述
这里得到的结果并不是我们想要的那种仅有图片的格式,后面的13张图片都能正常的得到存储路径,但是前面的出现了过长的问题。在我仔细读了 Linux 过滤的文本后,我估计是贪婪匹配出了问题,在上面的内容中使用贪婪匹配就会导致输出的内容超出我们的预期(做爬虫的时候千万记得不要用贪婪匹配!不要用贪婪匹配! 因为HTML不同元素的格式内容都很接近,所以使用贪婪匹配容易出现问题。),于是我将代码改成:

rets_2 = re.findall(r'(?<=<img src=")(.+?)(?=" (?:alt=.+>|width.+>|class.+/>))', ret.text)
print(rets_2)

在这里插入图片描述
ok 所有图片都以预期的格式正常输出。

然后我们开始考虑,想要把这些图片下载下来应该怎么办呢?
是不是可以使用 requests.get(‘图片储存路径’) 然后用它的 content 方法(返回的是bytes型也就是二进制的数据),将内容写入文件,应该就是我们想要下载的图片了!
开始敲!

import os 
# 因为我想把文件储存到当前路径下所以使用 os 模块找到当前路径
head = "https://www.sucai8.com"
# 因为文件的存储路径是 网址 + 我们得到的存储路径 (这里涉及一点前端的知识 有兴趣可以去了解一下) 所以我们下一步是需要对前面得到的路径都加一段头内容
list_result = [head+temp for temp in rets_2]
# 这样我们就得到了所有图片的存储路径 可以直接通过requests.get()对路径进行访问
print(list_result)

在这里插入图片描述
ok,我们看到每张想要下载的图片都是可以点进去的链接的时候就完成了下载的前期准备工作。
然后下载内容的代码如下:

for i in range(len(list_result)):
	print(f"正在下载第{i+1}张图片,下载地址:{list_result[i]}")
	# os.path.dirname 这个就是得到当前存在的路径
	d_path = os.path.dirname(__file__)
	# de_path 就是在路径的后面加上一个图片的格式,png/jpg/gif 通过split(".")进行字符串分隔,然后访问它的格式名
    de_path = d_path + f'/{i+1}' + f'.{list_result[i].split(".")[3]}'
    # 打开文件(如果不存在就新建)将content得到的内容进行写入
    with open(de_path, 'wb') as fp:
        fp.write(d_pic.content)
        fp.close()

代码直接运行试试!
在这里插入图片描述
Alt
所有的图片都下载成功了!
但是还是觉得代码并不完整(别问,问就是处女座!)
考虑如果网速不佳的情况下,下载请求过长就要输出访问超时,改图片无法下载,如果在规定时间内访问就可以下载,是不是代码会更加完整一些?于是将代码改良后,如下:

for i in range(len(list_result)):
    print(f"正在下载第{i+1}张图片,下载地址:{list_result[i]}")
    # try except else 是异常处理语句
    # 如果 try 的要求不被满足就会触发 except 的异常请求
    # 如果 try 正常执行 在 try 的内容执行完毕之后就继续执行else语句 
    try:
        d_pic = requests.get(list_result[i], timeout=5)

    except TimeoutError:
        print("访问超时,该图片无法下载")

    else:
        d_path = os.path.dirname(__file__)
        de_path = d_path + f'/{i+1}' + f'.{list_result[i].split(".")[3]}'
        with open(de_path, 'wb') as fp:
            fp.write(d_pic.content)
            fp.close()

至此 整个代码过程已经写完了,并且图片都正常下载可以直接打开观看图片的内容。将该次爬虫实验的所有代码贴在下面:

import requests
import re
import os

ret = requests.get("https://www.sucai8.com/")
# print(ret.text)

head = "https://www.sucai8.com"
# rets_1 = re.findall(r'(?<=<img src=")(.+)(?=" class.+/>)', ret.text)
rets_2 = re.findall(r'(?<=<img src=")(.+?)(?=" (?:alt=.+>|width.+>|class.+/>))', ret.text)
# print(rets_1)
# print(rets_2)
list_result = [head+temp for temp in rets_2]
# print(list_result)
for i in range(len(list_result)):
    print(f"正在下载第{i+1}张图片,下载地址:{list_result[i]}")
    try:
        d_pic = requests.get(list_result[i], timeout=5)

    except TimeoutError:
        print("访问超时,该图片无法下载")

    else:
        d_path = os.path.dirname(__file__)
        de_path = d_path + f'/{i+1}' + f'.{list_result[i].split(".")[3]}'
        with open(de_path, 'wb') as fp:
            fp.write(d_pic.content)
            fp.close()

ok 此次爬虫结束!
如果感兴趣想要深入了解学习 欢迎来 三创 一起交流学习!

  • 23
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wx-zhou

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

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

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

打赏作者

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

抵扣说明:

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

余额充值