web-dev-qa-db-ja.com

Pythonを使用してHTMLのhref属性からURLを抽出する正規表現

可能性のある複製:
文字列が有効な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']

ありがとう!

79
user825286
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']
172
JohnJohnGa

最良の答えは...

正規表現を使用しないでください

受け入れられた答え の式は多くの場合を見逃しています。特に、URLにはUnicode文字を含めることができます。必要な正規表現は here であり、これを確認した後、結局は本当に必要ないと判断する場合があります。最も正しいバージョンは、1万文字長です。

確かに、たくさんのURLが含まれるプレーンで構造化されていないテキストから始める場合、その1万文字の正規表現が必要になる場合があります。ただし、入力が構造化されている場合は、構造体を使用します。目的は、「アンカータグのhref内のURLを抽出する」ことです。もっと簡単なことができるのに、なぜ1万文字の正規表現を使用するのですか?

代わりに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から情報を抽出するための正規表現よりもはるかに強力で拡張可能な方法です。

53
senderle