正则表达式使用 Python 从 HTML 中的 href 属性中提取 URL [重复]

Posted

技术标签:

【中文标题】正则表达式使用 Python 从 HTML 中的 href 属性中提取 URL [重复]【英文标题】:Regex to extract URLs from href attribute in HTML with Python [duplicate] 【发布时间】:2011-10-16 12:25:58 【问题描述】:

可能重复:What is the best regular expression to check if a string is a valid URL?

考虑如下字符串:

string = "<p>Hello World</p><a href="http://example.com">More Examples</a><a href="http://example2.com">Even More Examples</a>"

如何使用 Python 在锚标记的 href 中提取 url?比如:

>>> url = getURLs(string)
>>> url
['http://example.com', 'http://example2.com']

谢谢!

【问题讨论】:

不要尝试使用正则表达式解析 html。寻找可以为您提取 href 值的 HTML 解析器。 @Judge John Deed:better be lazy. 见:***.com/questions/9760588/… 【参考方案1】:
import re

url = '<p>Hello World</p><a href="http://example.com">More Examples</a><a href="http://example2.com">Even More Examples</a>'

urls = re.findall('https?://(?:[-\w.]|(?:%[\da-fA-F]2))+', url)

>>> print urls
['http://example.com', 'http://example2.com']

【讨论】:

在任何类型的正常抓取中,href 的文本部分也是链接而不是描述性文本,这只会给出重复。 对于那些修改此正则表达式的人,请注意 [$-_@.&+] 中的“-”充当范围运算符而不是字符。这意味着某些椅子(例如,',')被多次表示。 此正则表达式不考虑 URL 片段(# 后缀)。 如何在没有 http 的情况下使用它来捕获 URL?喜欢www.google.comgoogle.com 它不适用于以下文本:"http://lubimyczytac.pl/ksiazka/57710/nowy-umysl-cesarza-o-komputerach-umysle-i-prawach-fizyki':"【参考方案2】:

最好的答案是……

不要使用正则表达式

accepted answer 中的表达式漏掉了很多情况。其中,URL 中可以包含 unicode 字符。你想要的正则表达式是here,看了之后,你可能会得出结论,你毕竟不是真的想要它。最正确的版本是一万个字符

诚然,如果您从包含一堆 URL 的纯非结构化文本开始,那么您可能需要这个 10000 个字符长的正则表达式。但是如果您的输入是结构化的,请使用该结构。您声明的目标是“在锚标记的 href 中提取 url”。当您可以做一些更简单的事情时,为什么还要使用一万个字符长的正则表达式?

改为解析 HTML

对于许多任务,使用Beautiful Soup 会更快更容易使用:

>>> from bs4 import BeautifulSoup as Soup
>>> html = Soup(s, 'html.parser')           # Soup(s, 'lxml') if lxml is installed
>>> [a['href'] for a in html.find_all('a')]
['http://example.com', 'http://example2.com']

如果不想使用外部工具,也可以直接使用Python自带的HTML解析库。这是 HTMLParser 的一个非常简单的子类,它完全符合您的要求:

from html.parser import HTMLParser

class MyParser(HTMLParser):
    def __init__(self, output_list=None):
        HTMLParser.__init__(self)
        if output_list is None:
            self.output_list = []
        else:
            self.output_list = output_list
    def handle_starttag(self, tag, attrs):
        if tag == 'a':
            self.output_list.append(dict(attrs).get('href'))

测试:

>>> p = MyParser()
>>> p.feed(s)
>>> p.output_list
['http://example.com', 'http://example2.com']

您甚至可以创建一个接受字符串、调用feed 并返回output_list 的新方法。这是从 html 中提取信息的一种比正则表达式更强大且可扩展的方式。

【讨论】:

__init__self 都是什么东西? 美丽很棒是您需要按照最初问题中的要求解析 href 或 src 并且应该是公认的答案,但要注意在字符串中查找 URL 无济于事。 不过,这并不能回答问题。问题是关于 URL 的格式,而不是如何解析 HTML。 @AlSweigart,我认为问题的主体询问解析 HTML 是合理的。 @AlSweigart,感谢您编辑标题。我正在考虑这个问题,并意识到按照我自己的逻辑,我实际上应该编辑标题。然后我看到你已经这样做了!

以上是关于正则表达式使用 Python 从 HTML 中的 href 属性中提取 URL [重复]的主要内容,如果未能解决你的问题,请参考以下文章

从python中的html获取价值的最佳方法? [复制]

python中的正则表达式

Python 正则表达式 利用括号分组

在python中使用正则表达式从文本中删除html标签

Python中的正则表达式

python re正则表达式