python--正则表达式应用

正则对一个简单爬虫程序的改进

一个爬虫程序

这是一个提取网页源代码中以.jpg结尾的图片引用,并将其下载的python小程序

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    ## 一个小爬虫
    ## 下载网页中的所有图片
    ## getJpg.py
    import re
    import urllib

    # Get the source code of a website
    def getHtml(url):
    print 'Getting html source code...'
    page = urllib.urlopen(url)
    html = page.read()
    return html

    # Open the website and check up the address of images,
    # and find the common features to decide the re_rule
    def getImageAddrList(html):
        print 'Getting all address of images...'
        rule = r"src=\"(.+\.jpg)\" pic_ext"
        imReg = re.compile(rule)
        imList = re.findall(imReg, html)
        return imList

    def getImage(imList):
        print 'Downloading...'
        name = 1;
        for imgurl in imList:
            urllib.urlretrieve(imgurl, '%s.jpg' % name)
            name += 1
        print 'Got ', len(imList), ' images!'

    ## main
    htmlAddr = "http://tieba.baidu.com/p/2510089409"
    html = getHtml(htmlAddr)
    imList = getImageAddrList(html)
    getImage(imList)

问题:

其中用的规则是"src=\"(.+\.jpg)\" pic_ext",可是这样会出现问题:
如:网页源代码中会有这样的串:
情况一:引用非jpg图片的标签后连着一个引用jpg图片的标签

src="http://static.tieba.baidu.com/tb/editor/images/face/i_f07.png" pic_ext="png"  width="30" height="30"><br><br><br><img pic_type="0" class="BDE_Image" src="http://imgsrc.baidu.com/forum/w%3D580/sign=5db4e4ccbf096b6381195e583c318733/ef59ccbf6c81800a4e2aaaedb03533fa838b4702.jpg" pic_ext="jpeg"  

匹配出来的url:
http://static.tieba.baidu.com/tb/editor/images/face/i_f07.png" pic_ext="png" width="30" height="30"><br><br><br><img pic_type="0" class="BDE_Image" src="http://imgsrc.baidu.com/forum/w%3D580/sign=5db4e4ccbf096b6381195e583c318733/ef59ccbf6c81800a4e2aaaedb03533fa838b4702.jpg
情况二:两个引用jpg图片的标签连一起

src="http://imgsrc.baidu.com/forum/w%3D580/sign=2d3c6fb835a85edffa8cfe2b795509d8/bc27cffc1e178a82280c7948f703738da977e823.jpg" pic_ext="jpeg"  height="350" width="560"><br><img pic_type="0" class="BDE_Image" src="http://imgsrc.baidu.com/forum/w%3D580/sign=a18181c99213b07ebdbd50003cd69113/8713c8fcc3cec3fda670a19dd788d43f86942788.jpg" pic_ext="bmp"

提取的url:
http://imgsrc.baidu.com/forum/w%3D580/sign=0955e2d1b2de9c82a665f9875c8080d2/8d1ab051f8198618ad77e96c4bed2e738bd4e623.jpg" pic_ext="jpeg" height="315" width="560"><br><img pic_type="0" class="BDE_Image" src="http://imgsrc.baidu.com/forum/w%3D580/sign=2d3c6fb835a85edffa8cfe2b795509d8/bc27cffc1e178a82280c7948f703738da977e823.jpg" pic_ext="jpeg" height="350" width="560"><br><img pic_type="0" class="BDE_Image" src="http://imgsrc.baidu.com/forum/w%3D580/sign=a18181c99213b07ebdbd50003cd69113/8713c8fcc3cec3fda670a19dd788d43f86942788.jpg
这两种情况都是两个图片img标签连在了一起导致我们匹配到了两段的合体, 这样提取的url显然不是我们想要的。

改进:

通过查阅,发现正则表达式有两种匹配模式:贪婪模式与非贪婪模式(懒惰模式)

贪婪匹配:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到:abcaxc(ab*c)。

非贪婪匹配:就是匹配到结果就好,就少的匹配字符。如上面使用模式p匹配字符串str,结果就是匹配到:abc(ab*c)。

于是,对上面的正则改进:"src=\"(.+?\.jpg)\" pic_ext"在+后加上?就可以以非贪婪模式进行匹配。这样两个引用jpg图片的情况就可以分别提取出url了,

那怎么处理第一种情况呢?
通过观察我们发现,我们想要的其实是src=后面双引号之间的内容,并且是两个相互匹配的双引号。也就是说,""之间是不应有其他的"的。所以,问题就很容易了,只要把 . 换成[^\"]匹配的是出来"之外的字符就行了。
改后,正则变成这样:rule = r"src=\"([^\"]+?\.jpg)\" pic_ext"

现在就能轻松地抓取网页上图片啦!

参考:

http://blog.csdn.net/zouxy09/article/details/16920661
正则表达式贪婪与非贪婪模式:http://www.cnblogs.com/xudong-bupt/p/3586889.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值