难道这个re.compile()表达式找不到页面中的所有链接吗?

时间:2014-07-08 00:27:59

标签: python parsing hyperlink

我在python中理解re.compile()方法有很多困难。我找到了这个例子,从我读到的它应该找到网页中的所有链接。它是否正确?有人可以解释表达式的"(。*?)部分吗?它对我来说没有多大意义,它似乎没有在页面中找到链接。

link_finder = re.compile('href="(.*?)"')
links = link_finder.findall(html)

2 个答案:

答案 0 :(得分:1)

"(.*?)"

这是一个非贪婪的表达式,用于匹配一对双引号之间的所有字符。非贪婪意味着尽快,因为它会找到下一个双引号,它会停止搜索。

相比之下,贪婪的表达

"(.*)"

不会停在它找到的下一个双引号上 - 它会继续直到它击中当前行的最后一个 - 因此这个词是"贪婪的",而不是你需要的这种情况。

它可能无法为您找到任何内容,因为您使用single-quotes代替double-quotes引用了所有链接。在这种情况下,请尝试

link_finder = re.compile("href='(.*?)'")
而是(注意单引号和双引号的位置是交换的)

示例输出:

>>> link_finder = re.compile("href='(.*?)'")
>>> links = link_finder.findall("<a href='testlink'>")
>>> links
['testlink']

修改

作为免责声明,我应该注意到还有更好的方法可以做到这一点。一个如下:

re.compile("href\s*=\s*['\"](.*?)['\"]")

哪个匹配空格以及匹配两种类型的引号。但肯·汉普森建议使用专用工具lxmlBeautiful Soup更好。

答案 1 :(得分:1)

要真正找到文档中的所有 HTML 链接,它比正则表达式支持的更加细微。

例如,这些标记中的任何一个都是有效的HTML:

<a href='foo.html'>foo</a>

<a href = 'foo2.html'>foo2</a>

但是你的正则表达式只能找到第一个。

可以改变正则表达式来解释,是的,即:

link_finder = re.compile("href\s*=\s*'(.*?)'")

但除此之外还有其他细微差别(单引号和双引号对只是另一个例子),这又回到了关于使用正则表达式解析 HTML (也不是 XML 等)。最好使用实际的 HTML 解析器来实现这一点,因为所有这些细微差别都被考虑在内,因为解析器必须考虑整个语法语言。

如果您在网络环境中操作, jQuery 实际上可能是最好的选择,因为它会通过单行搜索 DOM 。< / p>

对于纯Python, lxml 是一种可能性(http://lxml.de/)。