【问题标题】:Python 3.3.2 - Finding Image Sources in HTMLPython 3.3.2 - 在 HTML 中查找图像源
【发布时间】:2013-08-17 02:14:50
【问题描述】:

我需要从 html 文件中定位和提取图像源。例如,它可能包含:

<image class="logo" src="http://example.site/logo.jpg">

<img src="http://another.example/picture.png">

使用 Python。我不想使用任何第三方程序。不过,我可以使用 RE 模块。程序应该:

  • 筛选所有内容
  • 找出imgimage 标签
  • 找到src并获取属性值(不带双引号)

这可能吗?如果可以,我该怎么做?我们可以假设我不需要访问互联网来执行此操作(我有一个名为 website.html 的文件,其中包含所有 html 代码)。

编辑:我当前的正则表达式是

r'&lt;img[^&gt;]*\ssrc="(.*?)"'

r'&lt;image[^&gt;]*\ssrc="(.*?)"'

主要问题是表达式会选择以 img 或 image 开头的任何内容。例如,如果有 &lt;imagesomethingrandom src="website"&gt; 的内容,它仍会将其视为图像(因为单词 image 位于开头)并添加源。

提前致谢。

罗伯。

【问题讨论】:

  • 看看RegularExpressions.info,尝试学习正则表达式。当您对它们有相当了解并尝试自己编写表达式时,请返回并编辑问题。
  • @FakeRainBrigand 我已经学习了正则表达式的不同语法。我可以找到标签(),但我不知道如何将标签的内部放入列表中。这就是我问这个问题的原因。
  • 好的,那就分享一下你的表情吧。
  • @FakeRainBrigand 完成并完成。
  • 你的结果是什么?

标签: html regex python-3.x


【解决方案1】:

说明

这个表达式将:

  • 查找所有具有src 属性的imageimg 标记
  • 忽略不是image或img的标签,如imagesomethingrandom
  • 捕获src属性的值
  • 正确处理单引号、双引号或不带引号的属性值
  • 避免大多数棘手的边缘情况,这些情况在匹配 html 时似乎会绊倒正则表达式

&lt;ima?ge?(?=\s|&gt;)(?=(?:[^&gt;=]|='[^']*'|="[^"]*"|=[^'"][^\s&gt;]*)*?\ssrc=(['"]?)(.*?)\1(?:\s|&gt;))(?:[^&gt;=]|='[^']*'|="[^"]*"|=[^'"][^\s&gt;]*)*&gt;

示例

Live Regex Demo
Live Python Demo

示例文本

注意第一行中相当困难的边缘情况

<img onmouseover=' src="NotTheDroidsYouAreLookingFor.png" ; if (x > 3) { funRotate(src); } ' src="http://another.example/picture.png">
<imagesomethingrandom class="logo" src="http://example.site/imagesomethingrandom.jpg">
<image class="logo" src="http://example.site/logo.jpg">
<img src="http://another.example/DoubleQuoted.png">
<image src='http://another.example/SingleQuoted.png'>
<img src=http://another.example/NotQuoted.png>

Python 代码

#!/usr/bin/python
import re

string = """<img onmouseover=' src="NotTheDroidsYouAreLookingFor.png" ; if (x > 3) { funRotate(src); } ' src="http://another.example/picture.png">
<imagesomethingrandom class="logo" src="http://example.site/imagesomethingrandom.jpg">
<image class="logo" src="http://example.site/logo.jpg">
<img src="http://another.example/DoubleQuoted.png">
<image src='http://another.example/SingleQuoted.png'>
<img src=http://another.example/NotQuoted.png>
""";

regex = r"""<ima?ge?(?=\s|>)(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\ssrc=(['"]?)(.*?)\1(?:\s|>))(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*>""";

intCount = 0

for matchObj in re.finditer( regex, string, re.M|re.I|re.S):
    print " "
    print "[", intCount, "][ 0 ] : ", matchObj.group(0)
    print "[", intCount, "][ 1 ] : ", matchObj.group(1)
    print "[", intCount, "][ 2 ] : ", matchObj.group(2)
    intCount+=1

捕获组

Group 0 获取整个图像或 img 标签
第 1 组获取包围 src 属性的引号(如果存在)
第2组获取src属性值

[ 0 ][ 0 ] :  <img onmouseover=' src="NotTheDroidsYouAreLookingFor.png" ; if (x > 3) { funRotate(src); } ' src="http://another.example/picture.png">
[ 0 ][ 1 ] :  "
[ 0 ][ 2 ] :  http://another.example/picture.png

[ 1 ][ 0 ] :  <image class="logo" src="http://example.site/logo.jpg">
[ 1 ][ 1 ] :  "
[ 1 ][ 2 ] :  http://example.site/logo.jpg

[ 2 ][ 0 ] :  <img src="http://another.example/DoubleQuoted.png">
[ 2 ][ 1 ] :  "
[ 2 ][ 2 ] :  http://another.example/DoubleQuoted.png

[ 3 ][ 0 ] :  <image src='http://another.example/SingleQuoted.png'>
[ 3 ][ 1 ] :  '
[ 3 ][ 2 ] :  http://another.example/SingleQuoted.png

[ 4 ][ 0 ] :  <img src=http://another.example/NotQuoted.png>
[ 4 ][ 1 ] :  
[ 4 ][ 2 ] :  http://another.example/NotQuoted.png

【讨论】:

  • 你是如何生成正则表达式图的?令人印象深刻
  • 正则表达式不允许在等号前后有额外的空格。示例 myhost.com/img/good.png">
  • 非常真实,这种极端情况和许多其他情况可能存在。可以通过在等号前后添加\ * [这是一个反斜杠空格星号] 来适应这种极端情况。但 HTML 最佳实践建议不要在等号周围包含空格以提高可读性,更重要的是,OP 的示例文本没有涵盖这种边缘情况。
【解决方案2】:

试试BeautifulSoup,直接写

from bs4 import BeautifulSoup    
soup = BeautifulSoup(theHTMLtext)
imagesElements = soup.find_all('img')

【讨论】:

    【解决方案3】:

    还有一个修改版

    <ima?ge? # using conditional letters, we match both tags in one expression
    \s+      # require at least one space, also includes newlines which are valid
             # prevents <imgbutnotreally> tags
    [^>]*?   # similar to the above, but tell it not to be greedy (performance)
    \bsrc="([^"]+) # match a space and find all characters in the src tag
    

    rubular

    <ima?ge?\s+[^>]*?\src="([^"]+)
    

    【讨论】:

    • 稍微好一点的方法是:]*?src=["|']([^["|']]+) 因为它也适合名称周围的单引号。
    • 您在最后一个正则表达式中错误地使用了字符类。
    • 谢谢。我没有注意到这一点。我猜&lt;img src=|thing.png|&gt; 不应该被接受。
    • 这部分表达式 ([^["']]+) 并没有完全按照你的想法做,你可以考虑重写这部分。
    • 谢谢。我只是将它回滚到第二个修订版,并做了一个小的、经过测试的更改。我也更新了rubular。
    【解决方案4】:

    使用汤在 html 中查找一些图像

    from bs4 import BeautifulSoup
    
    url = <img src="http://another.example/picture.png">
    
    a = BeautifulSoup(html, 'html.parser')
    b = a.findAll('img')
    url_picture = list()
    for i in range(0, len(b)):
        image = b[i].attrs['src']
        url_picture.append(image)
    

    【讨论】:

      猜你喜欢
      • 2013-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-02
      • 2014-11-22
      • 2013-12-02
      • 2023-03-22
      • 2010-10-18
      相关资源
      最近更新 更多