赞
踩
目录
本文是按照该文章思路实现的,多亏博主终于令我找到了合适的网站能够实操了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')
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。