使用pyparsing查找标签
我正在用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)