Python爬虫:正则的应用——批量获取网站图片

目录

一、写在前面

观察网页:

二、爬取流程

(一)获得数据

(二)数据解析

(三)结果

(四)其他

三、错误

四、代码


一、写在前面

        本文是按照该文章思路实现的,多亏博主终于令我找到了合适的网站能够实操了TT 

python正则表达式实战——获取图片_正则方式提取图片是什么_爱吃饼干的小白鼠的博客-CSDN博客

正则

        正则语法:使用元字符进行排列组合用来匹配字符串,在线测试网站:在线正则表达式测试

 

 

 图片来源视频教程:2 2 Re解析 正则表达式 02(上)_哔哩哔哩_bilibili

观察网页

        点击某个标签下,按F12点击element,鼠标挪动定位图片所在,在此可以看到在图片中是以 img 标签储存,里面的 src 属性就是图片对应地址,对该URL单独发起请求,即可获得图片

        要获得的数据:最受欢迎的壁纸(Here are the most popular walls uploaded within the last month)

二、爬取流程

(一)获得数据

UA伪装、发起请求、获取响应数据一气呵成:

import requests
import re

# 该网页对应的URL
url = 'https://wallhaven.cc/toplist'

# UA伪装
head = {'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36'}

# 获取响应数据,该页面返回的是text类型
text=requests.get(url=url, headers=head).text

(二)数据解析

        将图片对应的那组标签复制到Python里进行正则处理,只需要用正则方法获得 src 属性里的 url 就好了

        例如,该网页某图片对应字串:<img alt="loading" class="lazyload loaded" data-src="https://th.wallhaven.cc/small/p9/p9yl39.jpg"

1.应用正则表达式:

我们要获取红色的字串

regx_0= '<img alt="loading".*?src="(.*?)"'

# 或者
regx_0= '<img alt="loading".*?src="(.*?)".*?</i></a></div></figure>'

关于正则表达式中的.*,.*?,.+?的理解_小人物大青春的博客-CSDN博客

         .*? 里面的?让前面尽可能少地匹配(?的意思是0或者1次),出现多个满足的匹配结果时,会选择最短的

        PS:这里正则表达式还不熟练,比如加上前面的 class="xxx" 后者在后面加上><a 字符之后得到的是个空列表,以及与预期不同的返回值

2.使用 re.findall() 将表达式作用于获得的网页源码:

img_list=re.findall(regx_0,text,re.S)

['https://th.wallhaven.cc/small/jx/jxvw7q.jpg', 'https://th.wallhaven.cc/small/3l/3lrw69.jpg', 'https://th.wallhaven.cc/small/x6/x6p3y3.jpg', 'https://th.wallhaven.cc/small/9d/9dr8pd.jpg', 'https://th.wallhaven.cc/small/we/wem6mp.jpg', 'https://th.wallhaven.cc/small/d6/d6w2dj.jpg', 'https://th.wallhaven.cc/small/l8/l82kpr.jpg', 'https://th.wallhaven.cc/small/rr/rrjyq1.jpg', 'https://th.wallhaven.cc/small/x6/x6ppxl.jpg', 'https://th.wallhaven.cc/small/zy/zy552w.jpg', 'https://th.wallhaven.cc/small/l8/l8228q.jpg', 'https://th.wallhaven.cc/small/rr/rrjg67.jpg', 'https://th.wallhaven.cc/small/7p/7prmdv.jpg', 'https://th.wallhaven.cc/small/kx/kx2eoq.jpg', 'https://th.wallhaven.cc/small/kx/kx2k76.jpg', 'https://th.wallhaven.cc/small/d6/d6wkwl.jpg', 'https://th.wallhaven.cc/small/o5/o52y67.jpg', 'https://th.wallhaven.cc/small/l8/l82wjy.jpg', 'https://th.wallhaven.cc/small/m3/m32g5k.jpg', 'https://th.wallhaven.cc/small/rr/rrjgw7.jpg', 'https://th.wallhaven.cc/small/qz/qzll57.jpg', 'https://th.wallhaven.cc/small/gp/gp2qre.jpg', 'https://th.wallhaven.cc/small/2y/2y3dkx.jpg', 'https://th.wallhaven.cc/small/2y/2y3wr9.jpg']

关于 findall 用法:https://www.cnblogs.com/rmticocean/articles/15879476.html

        参数 re.S因为. 无法匹配换行符,有了re.S 后,正则表达式会将这个字符串作为一个整体单行匹配

3.创建储存文件的文件夹

        记得这个代码写在最开头

import os

if not os.path.exists('./wallheavenlib'):
    os.mkdir('./wallheavenlib')

        函数返回了一个列表,列表里面是每个图片的 URL,遍历该列表发起请求即可得到网页中的图片

4.完善程序

        接下来做的几件事:

(1) 用循环语句遍历每个图片的 url 发起请求,就可以得到每个图片的二进制数据

        昂,大概就是这种吧。。

(2) 指定文件路径和文件名称

(3) 使用 with open(): 打开文件并以二进制形式写入

# 循环对图片的地址发起请求

for img_url in img_list:
    # 用img_url遍历列表里的每个 url,发起get请求,返回二进制数据赋给img_data
    img_data=requests.get(url=img_url, headers=head).content
    # 文件名称,以原名称+jpg后缀命名,不会重复
    img_name=img_url.split('/',)[-1]
    # 文件路径为:./wallheavenlib/xx.jpg,这里少了 xx.jpg 不行,会报错!!!
    # 因为下面write写入的需要是个具体文件
    img_path='./wallheavenlib/'+img_name
    # 将img_path路径下的某文件以二进制的形式写入储存
    with open (img_path,'wb') as fp:
        fp.write(img_data)
        print(img_name+' completed')

(三)结果

        结果自然是成功地获得了图片

(四)其他

        下拉过程中发现网页会发起 Ajax 请求并且多了一个页面的参数,返回的仍然是 text 类型数据

         于是进行了改进

# 参数
p=input('Pages:')
parm={page:p}
text=requests.get(url=url, headers=head,params=parm).text

         也是成功获得了图片

三、错误

(一)一开始选择了不合适的网站,该网站图片的地址是动态的,也就是重复复制打开图片的链接是不一样的,动态的不可用正则爬取

(二)空列表

 正则表达式出错,以后要在实例中多练习

(三)其他

1.

这个错误大概应该也是正则出错了

2.

是因为粗心:

3.

        参数字典 key 是字符串类型

四、代码

import requests
import re
import os

# 创建文件的储存路径
if not os.path.exists('./wallheavenlib'):
    os.mkdir('./wallheavenlib')
# 访问的url
url = 'https://wallhaven.cc/toplist?'
# 参数
p=input('Pages:')
parm={'page':p}
# UA伪装
head = {'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'}
# 获得html源码
text=requests.get(url=url, headers=head,params=parm).text

# 正则匹配
# <img alt="loading" class="lazyload loaded" data-src="https://th.wallhaven.cc/small/x6/x6p3y3.jpg" src="https://th.wallhaven.cc/small/x6/x6p3y3.jpg"><a class="preview" href="https://wallhaven.cc/w/x6p3y3" target="_blank"></a><div class="thumb-info"><span class="wall-res">2400 x 1350</span><a class="jsAnchor overlay-anchor wall-favs" data-href="https://wallhaven.cc/wallpaper/fav/x6p3y3">259<i class="fa fa-fw fa-star"></i></a><a class="jsAnchor thumb-tags-toggle tagged" data-href="https://wallhaven.cc/wallpaper/tags/x6p3y3" original-title="Tags"><i class="fas fa-fw fa-tags"></i></a></div></figure>
regx_0= '<img alt="loading".*?src="(.*?)".*?</i></a></div></figure>'
img_list=re.findall(regx_0,text,re.S)
print(img_list)

# 循环对图片的地址发起请求
for img_url in img_list:
    # 用img_url遍历列表里的每个 url,发起get请求,返回二进制数据赋给img_data
    img_data=requests.get(url=img_url, headers=head).content
    # 文件名称,以原名称+jpg后缀命名,不会重复
    img_name=img_url.split('/',)[-1]
    # 文件路径为:./wallheavenlib/xx.jpg,这里少了 xx.jpg 不行!
    img_path='./wallheavenlib/'+img_name
    # 将img_path路径下的某文件以二进制的形式写入储存
    with open (img_path,'wb') as fp:
        fp.write(img_data)
        print(img_name+' completed')

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

带带琪宝

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

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

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

打赏作者

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

抵扣说明:

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

余额充值