爲了使正則表達式適應lxml的自動鏈接,有兩件事要做。首先將整個url模式匹配包裝在一個組中(?P<body> ..)
- 這可讓lxml知道href=""
屬性中的內容。
接下來,將主機部件包裝到(?<host> ..)
組中,並在調用自動鏈接功能時傳遞參數avoid_hosts=[]
。原因是你正在使用的正則表達式模式並不總是找到一個主機(有時host
部分將是None
),因爲它匹配部分網址和模糊的類似網址的模式。
我已經修改了正則表達式以包括上述變化和給定的一個片段的測試用例:
import re
import lxml.html
import lxml.html.clean
url_regexp = re.compile(r"""(?i)\b(?P<body>(?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|(?P<host>[a-z0-9.\-]+[.][a-z]{2,4}/))(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»「」‘’]))""")
DOC = """<html><body>
http://foo.com/blah_blah
http://foo.com/blah_blah/.
http://www.extinguishedscholar.com/wpglob/?p=364.
http://✪df.ws/1234
rdar://1234
rdar:/1234
message://%[email protected]%3e
What about <mailto:[email protected]?subject=TEST> (including brokets).
bit.ly/foo
</body></html>"""
tree = lxml.html.fromstring(DOC)
body = tree.find('body')
lxml.html.clean.autolink(body, [url_regexp], avoid_hosts=[])
print lxml.html.tostring(tree)
輸出:
<html><body>
<a href="http://foo.com/blah_blah">http://foo.com/blah_blah</a>
<a href="http://foo.com/blah_blah/">http://foo.com/blah_blah/</a>.
<a href="http://www.extinguishedscholar.com/wpglob/?p=364">http://www.extinguishedscholar.com/wpglob/?p=364</a>.
<a href="http://%C3%A2%C2%9C%C2%AAdf.ws/1234">http://✪df.ws/1234</a>
<a href="rdar://1234">rdar://1234</a>
<a href="rdar:/1234">rdar:/1234</a>
<a href="message://%[email protected]%3e">message://%[email protected]%3e</a>
What about <<a href="mailto:[email protected]?subject=TEST">mailto:[email protected]?subject=TEST</a>>
(including brackets).
<a href="bit.ly/foo">bit.ly/foo</a>
</body></html>
這是一個正則表達式的地獄......但它的作品像魅力。還有一個問題:** bit.ly/foo **將鏈接到一個子文件夾,而不是域名......你將如何解決這個問題? – Titusz 2011-04-12 00:44:45
您提供的正則表達式會匹配url-link文本,但clean.autolink函數是一個黑盒子:它不會讓您傳遞迴調來修改鏈接,然後對它們進行編碼。我建議複製clean.autolink和clean._link_text函數,去掉你不使用的東西,並且自定義行爲。特別是當你遍歷匹配的url時,找到沒有'Host'部分的東西,並且在url上添加'http://'方案(以及任何其他您希望應用的規則)。 – samplebias 2011-04-12 01:04:37
謝謝...我現在正在工作...通過簡單的後處理來解決它。 (用於body.xpath('// a')中的鏈接:....) – Titusz 2011-04-12 11:14:14