我想知道是否有任何方法可以从python中的电子邮件正文中提取域名。我正在考虑使用正则表达式,但我写的不太好,并且想知道是否有人可以帮助我。这是一个示例电子邮件正文:
<tr><td colspan="5"><font face="verdana" size="4" color="#999999"><b>Resource Links - </b></font><span class="snv"><a href="http://clk.about.com/?zi=4/RZ">Get Listed Here</a></span></td><td class="snv" valign="bottom" align="right"><a href="http://sprinks.about.com/faq/index.htm">What Is This?</a></td></tr><tr><td colspan="6" bgcolor="#999999"><img height="1" width="1"></td></tr><tr><td colspan="6"><map name="sgmap"><area href="http://x.about.com/sg/r/3412.htm?p=0&ref=fooddrinksl_sg" shape="rect" coords="0, 0, 600, 20"><area href="http://x.about.com/sg/r/3412.htm?p=1&ref=fooddrinksl_sg" shape="rect" coords="0, 55, 600, 75"><area href="http://x.about.com/sg/r/3412.htm?p=2&ref=fooddrinksl_sg" shape="rect" coords="0, 110, 600, 130"></map><img border="0" src="http://z.about.com/sg/sg.gif?cuni=3412" usemap="#sgmap" width="600" height="160"></td></tr><tr><td colspan="6"> </td></tr>
<tr><td colspan="6"><a name="d"><font face="verdana" size="4" color="#cc0000"><b>Top Picks - </b></font></a><a href="http://slclk.about.com/?zi=1/BAO" class="srvb">Fun Gift Ideas</a><span class="snv">
from your <a href="http://chinesefood.about.com">Chinese Cuisine</a> Guide</span></td></tr><tr><td colspan="6" bgcolor="cc0000"><img height="1" width="1"></td></tr><tr><td colspan="6" class="snv">
所以我需要“clk.about.com”等。
谢谢!
答案 0 :(得分:2)
最干净的方法是使用cssselect
和lxml.html
中的urlparse
。方法如下:
from lxml import html
from urlparse import urlparse
doc = html.fromstring(html_data)
links = doc.cssselect("a")
domains = set([])
for link in links:
try: href=link.attrib['href']
except KeyError: continue
parsed=urlparse(href)
domains.add(parsed.netloc)
print domains
首先,使用fromstring
将html数据加载到文档对象中。您使用标准css选择器cssselect
在文档中查询链接。您遍历链接,使用.attrib['href']
获取其网址 - 如果没有任何链接(except - continue
),请跳过它们。使用urlparse
将url解析为命名元组,并将域(netloc
)放入集合中。瞧!
当您在线拥有良好的库时,请尝试避免使用正则表达式。它们很难维护。对于HTML解析也是一个禁忌。
<强>更新强>:
评论中的href
过滤器建议非常有用,代码如下所示:
from lxml import html
from urlparse import urlparse
doc = html.fromstring(html_data)
links = doc.cssselect("a[href]")
domains = set([])
for link in links:
href=link.attrib['href']
parsed=urlparse(href)
domains.add(parsed.netloc)
print domains
您不需要try-catch
阻止,因为href
过滤器确保您只捕获其中包含href
属性的锚点。
答案 1 :(得分:1)
您可以使用Python标准库中的HTMLParser
来访问文档的某些部分。
答案 2 :(得分:1)
from lxml import etree
from StringIO import StringIO
from urlparse import urlparse
html = """<tr><td colspan="5"><font face="verdana" size="4" color="#999999"><b>Resource Links - </b></font><span class="snv"><a href="http://clk.about.com/?zi=4/RZ">Get Listed Here</a></span></td><td class="snv" valign="bottom" align="right"><a href="http://sprinks.about.com/faq/index.htm">What Is This?</a></td></tr><tr><td colspan="6" bgcolor="#999999"><img height="1" width="1"></td></tr><tr><td colspan="6"><map name="sgmap"><area href="http://x.about.com/sg/r/3412.htm?p=0&ref=fooddrinksl_sg" shape="rect" coords="0, 0, 600, 20"><area href="http://x.about.com/sg/r/3412.htm?p=1&ref=fooddrinksl_sg" shape="rect" coords="0, 55, 600, 75"><area href="http://x.about.com/sg/r/3412.htm?p=2&ref=fooddrinksl_sg" shape="rect" coords="0, 110, 600, 130"></map><img border="0" src="http://z.about.com/sg/sg.gif?cuni=3412" usemap="#sgmap" width="600" height="160"></td></tr><tr><td colspan="6"> </td></tr><tr><td colspan="6"><a name="d"><font face="verdana" size="4" color="#cc0000"><b>Top Picks - </b></font></a><a href="http://slclk.about.com/?zi=1/BAO" class="srvb">Fun Gift Ideas</a><span class="snv"> from your <a href="http://chinesefood.about.com">Chinese Cuisine</a> Guide</span></td></tr><tr><td colspan="6" bgcolor="cc0000"><img height="1" width="1"></td></tr><tr><td colspan="6" class="snv">"""
parser = etree.HTMLParser()
tree = etree.parse(StringIO(html), parser)
r = tree.xpath("//a")
links = []
for i in r:
try:
links.append(i.attrib['href'])
except KeyError:
pass
for link in links:
print urlparse(link)
从这里可以将域名区分为netloc。 xPath在这里可能不是最好的,有人请建议改进,但应该适合您的需求。
答案 3 :(得分:1)
HTMLParser是一种干净的方式。如果你想要一些快速和肮脏的东西,或者只是想看看中等复杂的正则表达式是什么样的,这里有一个示例正则表达式来找到href&#39; s(在我的头顶,未经测试):
r'<a\s+href="\w+://[^/"]+[^"]*">'
答案 4 :(得分:1)
鉴于你在域前总是有一个http协议说明符,这应该有用(txt就是你的例子)。
import re
[groups[0] for groups in re.findall(r'http://(\w+(\.\w+){1,})(/\w+)*', txt)]
但域名模式并不完美。