最近想抓一个网站的图片,写了一段程序,结果在爬取的时候,在某些位置就报爬取失败的错误。仔细查看了那些报错的数据对正则表达式的匹配有了更深的理解。
最短匹配遵循以下原则:
最先开始的匹配拥有最高的优先权——The match that begins earliest wins。即最短匹配是右侧最短,左侧不可知,很可能最长。
首先看下例子:
__author__ = 'Administrator'
import re
if __name__ == '__main__':
reg = r'src="(.*?\.jpg)"pic_ext'
#表示在整个网页中过滤出所有图片的地址,放在imglist中
list='src="https://gsp0.baidu.com/5aAHeD3nKhI2p27j8IqW0jdnxx1xbK/tb/editor/images/client/image\
emoticon1.png" ><br><img class="BDE_Image" src="https://imgsa.baidu.com/forum/w%3D580/sign=6a5dbf\
90a84bd11304cdb73a6aada488/e92b6059252dd42a8afc5a48063b5bb5c8eab859.jpg"pic_ext'
imgre = re.compile(reg) #转换成一个正则对象
imglist = imgre.findall(list)
print(len(imglist))
print(imglist[0])
如路径中显示,在字符串中,有连续两个src=“,虽然我们使用了最短匹配,但是获取的仍然是:
https://gsp0.baidu.com/5aAHeD3nKhI2p27j8IqW0jdnxx1xbK/tb/editor/images/client/image\
emoticon1.png" ><br><img class="BDE_Image" src="https://imgsa.baidu.com/forum/w%3D580/sign=6a5dbf\
90a84bd11304cdb73a6aada488/e92b6059252dd42a8afc5a48063b5bb5c8eab859.jpg
显然这个不是我们想要的结果,需要再一次匹配
reg1 = r'src="(.*?\.jpg)'
imgre1 = re.compile(reg1)
imglist1 = imgre1.findall(imglist[0])
print(imglist1)
我们重新做了一次匹配,获取到了准确的地址
'https://imgsa.baidu.com/forum/w%3D580/sign=6a5dbf 90a84bd11304cdb73a6aada488/e92b6059252dd42a8afc5a48063b5bb5c8eab859.jpg'
其实对于这种多个嵌套重复的情况,需要通过循环获得最准确的匹配。
再次处理如下:
reg1 = r'src="(.*?\.jpg)'
imgre1 = re.compile(reg1)
imglist1 = imgre1.findall(imglist[0])
while imglist1:
temp_result=imglist1
imglist1 = imgre1.findall(imglist1[0])
print(temp_result)
循环找到最后面的那个http://.*.jpg.
该方法只是匹配原则的一种解决方案,实际情况中要根据情况,或许有更好的,更优的正则结果。