4

我正在使用 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

4 回答 4

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)
于 2009-11-20T04:02:28.767 回答
1

为什么要编写自己的 HTML 解析器?标准库包括HTMLParser,BeautifulSoup 可以处理 HTMLParser 不能处理的任何工作。

于 2009-11-20T01:02:12.067 回答
1

你不喜欢使用普通的正则表达式?还是因为解析html的坏习惯?:D

re.findall("<object.*?</object>(?:<br /><a.*?</a>)?",a)
于 2009-11-20T15:21:13.810 回答
1

我能够运行您的 BeautifulSoup 代码并且没有收到任何错误。我正在运行 BeautifulSoup 3.0.7a

请使用 BeautifulSoup 3.0.7a;3.1.0.1 在某些情况下(例如您的情况)存在阻止它工作的错误。

于 2009-11-20T19:48:25.453 回答