Beautiful Soup:获取子节点的内容
我有以下的Python代码:
def scrapeSite(urlToCheck):
html = urllib2.urlopen(urlToCheck).read()
from BeautifulSoup import BeautifulSoup
soup = BeautifulSoup(html)
tdtags = soup.findAll('td', { "class" : "c" })
for t in tdtags:
print t.encode('latin1')
这段代码会返回以下的HTML代码:
<td class="c">
<a href="more.asp">FOO</a>
</td>
<td class="c">
<a href="alotmore.asp">BAR</a>
</td>
我想获取a节点之间的文本(比如说FOO或BAR),这部分内容应该是t.contents.contents。不过,这并没有那么简单 :)
有没有人知道怎么解决这个问题呢?
非常感谢,任何帮助都很受欢迎!
祝好,
Joseph
2 个回答
1
针对你的具体例子,pyparsing的makeHTMLTags功能可以很有用,因为它能处理很多不同的HTML标签变化,同时还能给结果提供一个方便的结构:
html = """
<td class="c">
<a href="more.asp">FOO</a>
</td>
<td class="c">
<a href="alotmore.asp">BAR</a>
</td>
<td class="d">
<a href="alotmore.asp">BAZZ</a>
</td>
"""
from pyparsing import *
td,tdEnd = makeHTMLTags("td")
a,aEnd = makeHTMLTags("a")
td.setParseAction(withAttribute(**{"class":"c"}))
pattern = td + a("anchor") + SkipTo(aEnd)("aBody") + aEnd + tdEnd
for t,_,_ in pattern.scanString(html):
print t.aBody, '->', t.anchor.href
输出结果是:
FOO -> more.asp
BAR -> alotmore.asp
3
在这种情况下,你可以使用 t.contents[1].contents[0]
来获取 FOO 和 BAR。
这里要知道的是,contents 返回的是一个包含所有元素(标签和可导航字符串)的列表。如果你打印 contents,你会看到它的样子像这样:
[u'\n', <a href="more.asp">FOO</a>, u'\n']
所以,要获取实际的标签,你需要访问 contents[1]
(如果你的内容完全一样,这个索引可能会根据源 HTML 的不同而变化)。找到正确的索引后,你可以使用 contents[0]
来获取 a 标签里面的字符串。
不过,由于这取决于 HTML 源的具体内容,所以这种方法比较脆弱。一个更通用和稳健的解决方案是再次使用 find()
来找到 'a' 标签,通过 t.find('a')
,然后使用 contents 列表来获取里面的值 t.find('a').contents[0]
,或者直接用 t.find('a').contents
来获取整个列表。