【问题标题】:Regex doesn't return all img tags - Python正则表达式不返回所有 img 标签 - Python
【发布时间】:2016-02-02 13:59:40
【问题描述】:

我有一个 python 脚本,可以下载 html 和 html 中显示的图像,因此我可以在本地打开文件。

它工作正常,唯一的问题是,有一个特定的 div,其中的图像不会被正则表达式下载/找到。我不知道为什么。这不是一个大问题,但我想知道原因。

这是脚本的重要部分:

url = "http://www.somedomain.com"
urlContent = urllib2.urlopen(url).read()
#Write originalHtml to file
f = open("originalHtml",'w')
f.write(urlContent)
f.close()
# HTML image tag: some_text
imgUrls = re.findall('img .*?src="(.*?)"', urlContent)

之后,我逐个遍历链接,下载图像并替换 html 中的链接,以便“src”指向我下载它的本地路径。该脚本负责相对链接和直接链接。

但是,部分图像永远不会被下载。 这是没有被拾取的 html:

<img src="/images/news/den-mcx80001.jpg" style="width:60px;height:36px;margin-top:12px; margin-bottom:12px; margin-left:17px; margin-right:17px;float:left; ">

不过,这确实得到了采纳:

<img class="productimg" style="width:72px;height:74px;margin-top:15px; margin-bottom:15px; margin-left:3px; margin-right:28px " src="/images/01_prdarticledocs/ImagesSmall/jpr/jpr-prx718xlf.jpg" alt="jpr-prx718xlf">

我不是正则表达式方面的专家,远非如此,但它似乎应该同时掌握两者,不是吗?

【问题讨论】:

  • 使用beautifulsoup库
  • 这是不使用正则表达式解析 HTML 的众多原因之一。
  • 对,就是那个。可悲的是,我知道那个帖子.. 那么,重新开始。
  • Mini sn-p 显示您的代码应该可以工作 repl.it/BixJ/0

标签: python regex html-parsing


【解决方案1】:

按照 cmets 的建议,使用 BeautifulSoup 修复。 代码 sn-p 供任何人寻找脚本来下载带有图像的 HTML、保存它们并将 html 中的图像重新链接到本地​​相对链接。

import urllib2
import re
from BeautifulSoup import BeautifulSoup
from os.path import basename
from urlparse import urlsplit

#get content of a url and save (not necessary) the originalhtml
url = "http://www.someDomain.com"
urlContent = urllib2.urlopen(url).read()
page = BeautifulSoup(urlContent)
f = open("originalHtml",'w')
f.write(urlContent)
f.close()
#Find all images in the file, put them in imgUrls 
imgUrls = page.findAll('img')
imagesDict = {}

# download all images
for image in imgUrls:
    try:
        #get src tag and download file, save link and local link in dict
        imgUrl = image['src']
        imgData = urllib2.urlopen(imgUrl).read()
        fileName = basename(urlsplit(imgUrl)[2])
        location = "images/" + fileName;
        imagesDict[location] = imgUrl
        print "loc=" + location
        output = open(location,'wb')
        output.write(imgData)
        output.close()
    except:
        #not so clean solution to catch hard-linked images ('http://somedomain.com/img/image.jpg
        try:
            imgData = urllib2.urlopen(url + imgUrl).read()
            fileName =  basename(urlsplit(imgUrl)[2])
            location = "images/" + fileName
            imagesDict[location] = imgUrl
            print "loc=" + location
            output = open(location,'wb')
            output.write(imgData)
            output.close()
        except:
            print "Double ERROR"
        print "Error" + imgUrl
        pass

#Replace the old links to new local links
for dictKey in imagesDict:
    urlContent = re.sub(imagesDict[dictKey], dictKey, urlContent)


#save HTML
f = open("imagesReplaced.html", 'w')
f.write(urlContent)
f.close()

【讨论】:

    【解决方案2】:

    您不应该使用正则表达式来解析 html。

    调试这些故障真的很难。我看不出您发布的图像标签不应与正则表达式匹配的任何原因。但这里有几个例子,这个正则表达式模式会失败。

    urlContent = """
    single quotes     <img src='/image/one.jpg' /> 
    unexpected space  <img src ="/image/two.jpg" /> 
    not an img tag    <script src="/some/javascript.js"> 
    """
    >>> re.findall('img .*?src="(.*?)"', urlContent)
    
    ['/some/javascript.js']
    

    按照其他答案的建议使用 html/xml 解析器是解决问题的唯一明智方法。

    PS:这已经在 cmets 中链接了,但我想每次讨论这个话题时都必须包含这个答案:RegEx match open tags except XHTML self-contained tags

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-20
      • 1970-01-01
      相关资源
      最近更新 更多