爬虫:正则的应用——批量获取网站图片"/>
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 = ''# 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=".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)['.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg', '.jpg']
关于 findall 用法:.html
参数 re.S:因为. 无法匹配换行符,有了re.S 后,正则表达式会将这个字符串作为一个整体单行匹配
3.创建储存文件的文件夹
记得这个代码写在最开头
import osif 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_dataimg_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 = '?'
# 参数
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=".jpg" src=".jpg"><a class="preview" href="" target="_blank"></a><div class="thumb-info"><span class="wall-res">2400 x 1350</span><a class="jsAnchor overlay-anchor wall-favs" data-href="">259<i class="fa fa-fw fa-star"></i></a><a class="jsAnchor thumb-tags-toggle tagged" data-href="" 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_dataimg_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')
更多推荐
Python爬虫:正则的应用——批量获取网站图片
发布评论