我希望这个问题不是RTFM问题。
我正在尝试编写一个Python脚本,从标准HTML网页(<link href...
标签)中提取链接。
我在网上搜索匹配的regexen,发现了许多不同的模式。是否有任何商定的标准正则表达式匹配链接?
亚当
更新 我实际上在寻找两个不同的答案:
Igal Serban
和cletus
!)答案 0 :(得分:17)
使用HTML的正则表达起来很混乱。只需使用像Beautiful Soup这样的DOM解析器。
答案 1 :(得分:8)
正如其他人所说,如果不需要实时性能,BeautifulSoup是一个很好的解决方案:
import urllib2
from BeautifulSoup import BeautifulSoup
html = urllib2.urlopen("http://www.google.com").read()
soup = BeautifulSoup(html)
all_links = soup.findAll("a")
关于第二个问题,是的,HTML链接应该是明确定义的,但实际遇到的HTML不太可能是标准的。 BeautifulSoup的美妙之处在于它使用类似浏览器的启发式方法来尝试解析您可能实际遇到的非标准,格式错误的HTML。
如果您确定要使用标准XHTML,则可以使用(更多)更快的XML解析器,例如expat。
正则表达式,由于上述原因(解析器必须维护状态,正则表达式不能这样做)永远不会是一般解决方案。
答案 2 :(得分:5)
没有。
您可以考虑使用Beautiful Soup。您可以将其称为解析html文件的标准。
答案 3 :(得分:4)
Shoudl链接不是一个定义明确的正则表达式吗?
不,[X] HTML不适用于使用正则表达式解析的一般情况。考虑以下示例:
<link title='hello">world' href="x">link</link>
<!-- <link href="x">not a link</link> -->
<![CDATA[ ><link href="x">not a link</link> ]]>
<script>document.write('<link href="x">not a link</link>')</script>
这只是一些随机有效的例子;如果你必须应对真实的标签汤HTML,那就有一百万个不正确的可能性。
如果您知道并且可以依赖目标页面的确切输出格式,那么您可以使用正则表达式。否则,抓取网页是完全错误的选择。
答案 4 :(得分:3)
Shoudl链接不是一个定义明确的正则表达式吗?这是一个相当理论化的问题,
我是第二个PEZ的回答:
我不认为HTML适用于“定义明确”的正则表达式,因为它不是常规语言。
据我所知,任何HTML标记都可能包含任意数量的嵌套标记。例如:
<a href="http://stackoverflow.com">stackoverflow</a>
<a href="http://stackoverflow.com"><i>stackoverflow</i></a>
<a href="http://stackoverflow.com"><b><i>stackoverflow</i></b></a>
...
因此,原则上,要正确匹配标记,您必须至少能够匹配表单的字符串:
BE
BBEE
BBBEEE
...
BBBBBBBBBBEEEEEEEEEE
...
其中B表示标签的开头,E表示结束。也就是说,您必须能够匹配由任意数量的B组成的字符串,然后匹配相同的数量的E。要做到这一点,你的匹配器必须能够“计数”,正则表达式(即有限状态自动机)根本不能这样做(为了计算,自动机至少需要一个堆栈)。参考PEZ的答案,HTML是一种无上下文的语法,而不是常规语言。
答案 5 :(得分:1)
这取决于HTML的生成方式。如果它受到某种程度的控制,你就可以逃脱:
re.findall(r'''<link\s+.*?href=['"](.*?)['"].*?(?:</link|/)>''', html, re.I)
答案 6 :(得分:1)
在那里回答你的两个问题。
答案 7 :(得分:0)
在回答问题#2时(不应该将链接定义为明确的正则表达式),答案是......不。
HTML链接结构是一种递归,很像编程语言中的parens和braces。必须有相同数量的开始和结束构造,并且“链接”表达式可以嵌套在其自身中。
要正确匹配“链接”表达式,需要使用正则表达式来计算开始和结束标记。正则表达式是一类有限自动机。根据定义,有限自动机不能“计算”模式中的构造。需要语法来描述诸如此类的递归数据结构。正则表达式无法“计数”是您看到使用语法描述的编程语言而不是正则表达式的原因。
所以不可能创建一个正面匹配100%所有“链接”表达式的正则表达式。肯定有正则表达式可以匹配大量精确的“链接”,但它们永远不会是完美的。
我最近写了一篇关于这个问题的博客文章。 Regular Expression Limitations