使用pyparsing查找标签

4 投票
4 回答
1922 浏览
提问于 2025-04-15 16:11

我正在用pyparsing来解析HTML。我想提取所有的embed标签,但有时候在这些标签后面会紧跟着一个a标签,如果有的话,我也想把它抓取出来。

举个例子:

import pyparsing
target = pyparsing.makeHTMLTags("embed")[0]
target.setParseAction(pyparsing.withAttribute(src=pyparsing.withAttribute.ANY_VALUE))
target.ignore(pyparsing.htmlComment)

result = target.searchString(""".....
   <object....><embed>.....</embed></object><br /><a href="blah">blah</a>
   """)

我在结果对象中找不到任何字符偏移量,否则我可以直接从原始输入字符串中截取一部分来处理。

补充说明:

有人问我为什么不使用BeautifulSoup。这是个好问题,让我通过一个代码示例来说明我为什么选择不使用它:

import BeautifulSoup
import urllib
import re
import socket

socket.setdefaulttimeout(3)

# get some random blogs
xml = urllib.urlopen('http://rpc.weblogs.com/shortChanges.xml').read()

success, failure = 0.0, 0.0

for url in re.compile(r'\burl="([^"]+)"').findall(xml)[:30]:
    print url
    try:
        BeautifulSoup.BeautifulSoup(urllib.urlopen(url).read())
    except IOError:
        pass
    except Exception, e:
        print e
        failure += 1
    else:
        success += 1


print failure / (failure + success)

当我尝试这样做时,BeautifulSoup在解析时会出现错误,大约有20-30%的时间会出错。这些并不是罕见的边缘案例。虽然pyparsing比较慢且使用起来麻烦,但无论我怎么用它都不会出错。如果有人能告诉我更好地使用BeautifulSoup的方法,我会非常感兴趣。

4 个回答

1

我成功运行了你的BeautifulSoup代码,没有遇到任何错误。我使用的是BeautifulSoup 3.0.7a版本。

请使用BeautifulSoup 3.0.7a版本;3.1.0.1版本有一些问题,导致在某些情况下根本无法正常工作(就像你遇到的情况)。

1

为什么要自己写一个HTML解析器呢?标准库里已经有了一个叫做HTMLParser的工具,而BeautifulSoup也能处理HTMLParser做不了的事情。

5

如果有一个可选的 <a> 标签,且它出现在 <embed> 标签后面会很有意思,那么就把它加到你的搜索模式里:

embedTag = pyparsing.makeHTMLTags("embed")[0]
aTag = pyparsing.makeHTMLTags("a")[0]
target = embedTag + pyparsing.Optional(aTag)
result = target.searchString(""".....   
    <object....><embed>.....</embed></object><br /><a href="blah">blah</a>
    """)

print result.dump()

如果你想在你的解析器中捕捉到某个表达式的位置,可以插入其中一个,并给它一个结果名称:

loc = pyparsing.Empty().setParseAction(lambda s,locn,toks: locn)
target = loc("beforeEmbed") + embedTag + loc("afterEmbed") + 
                                                 pyparsing.Optional(aTag)

撰写回答