BeautifulSoup - 轻松获取无HTML标签内容的方法

7

我正在使用这段代码来查找页面中所有有趣的链接:

soup.findAll('a', href=re.compile('^notizia.php\?idn=\d+'))

它的功能很好。不幸的是,在那个a标签里有很多嵌套标签,比如fontb和其他不同的东西...我想要的只是纯文本内容,没有其他任何html标签。

链接示例:

<A HREF="notizia.php?idn=1134" OnMouseOver="verde();" OnMouseOut="blu();"><FONT CLASS="v12"><B>03-11-2009:&nbsp;&nbsp;<font color=green>CCS Ingegneria Elettronica-Sportello studenti ed orientamento</B></FONT></A>

当然它很丑(而且标记语言并不总是相同的!),我想要得到:
03-11-2009:  CCS Ingegneria Elettronica-Sportello studenti ed orientamento

在文档中,建议在findAll方法中使用text=True,但这会忽略我的正则表达式。为什么?我该如何解决?

PyQuery 听起来是一个非常酷的替代品:http://pypi.python.org/pypi/pyquery - Josh Pearce
2个回答

13

我用过这个:

def textOf(soup):
    return u''.join(soup.findAll(text=True))

所以...

texts = [textOf(n) for n in soup.findAll('a', href=re.compile('^notizia.php\?idn=\d+'))]

我认为你需要一个循环 - 你不能在结果集上调用 findAll,只能在单个结果上调用。 - RichieHindle

2

您对使用pyparsing解决问题感兴趣吗?

from pyparsing import makeHTMLTags, SkipTo, anyOpenTag, anyCloseTag, ParseException

htmlsrc = """<A HREF="notizia.php?idn=1134" OnMouseOver="verde();" OnMouseOut="blu();"><FONT CLASS="v12"><B>03-11-2009:&nbsp;&nbsp;<font color=green>CCS Ingegneria Elettronica-Sportello studenti ed orientamento</B></FONT></A>"""

# create pattern to find interesting <A> tags
aStart,aEnd = makeHTMLTags("A")
def matchInterestingHrefsOnly(t):
    if not t.href.startswith("notizia.php?"):
        raise ParseException("not interested...")
aStart.setParseAction(matchInterestingHrefsOnly)
patt = aStart + SkipTo(aEnd)("body") + aEnd

# create pattern to strip HTML tags, and convert HTML entities
stripper = anyOpenTag.suppress() | anyCloseTag.suppress()
def stripTags(s):
    s = stripper.transformString(s)
    s = s.replace("&nbsp;"," ")
    return s


for match in patt.searchString(htmlsrc):
    print stripTags(match.body)

输出:

03-11-2009:  CCS Ingegneria Elettronica-Sportello studenti ed orientamento

这实际上对HTML的变幻无动于衷,因为它考虑了属性的存在/不存在、大小写等因素。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接