我正在尝试找到一种在Python中解析(可能是格式错误的)HTML的方法,如果满足一组条件,则输出该文档的位置(行,列).位置信息正在绊倒我.要清楚,我没有必要构建一个对象树.我只想找到某些数据及其在原始文档中的位置(想想一个拼写检查器,例如:’word’foo“在第x行,第y列,拼写错误)’

作为一个例子,我想要这样的东西(使用ElementTree的Target API):

import xml.etree.ElementTree as ET
class EchoTarget:
def start(self, tag, attrib):
if somecondition():
print "start", tag, attrib, self.getpos()
def end(self, tag):
if somecondition():
print "end", tag, self.getpos()
def data(self, data):
if somecondition():
print "data", repr(data), self.getpos()
target = EchoTarget()
parser = ET.XMLParser(target=target)
parser.feed("
some text
") 
 
parser.close()

但是,据我所知,getpos()方法(或类似的东西)不存在.当然,那是使用XML解析器.我想解析可能格式错误的HTML.

有趣的是,Python Standard Lib中的HTMLParser类确实提供了获取位置信息的支持(使用getpos()方法),但它在处理格式错误的HTML时非常糟糕,并且已作为可能的解决方案被淘汰.我需要在不破坏解析器的情况下解析真实单词中存在的HTML.

我知道两个HTML解析器可以很好地解析格式错误的HTML,即lxml和html5lib.事实上,我更喜欢使用其中任何一个而不是Python中可用的任何其他选项.

但是,据我所知,html5lib不提供事件API,并且需要将文档解析为树对象.然后我将不得不遍历树.当然,到那时,与源文档没有关联,并且所有位置信息都丢失了.所以,html5lib已经出局,这是一种耻辱,因为它似乎是处理格式错误的HTML的最佳解析器.

lxml库提供了一个主要镜像ElementTree的Target API,但同样,我不知道有什么方法可以访问每个事件的位置信息.浏览源代码也没有提示.

lxml还为SAX事件提供API.有趣的是,Python的标准库提到SAX支持Locator Objects,但很少提供有关如何使用它们的文档.这个SO Question提供了一些信息(当使用SAX Parser时),但是我没有看到它与lxml提供的对SAX事件的有限支持有何关系.

最后,在有人建议Beautiful Soup之前,我会指出,正如主页上所说,“Beautiful Soup位于流行的Python解析器之上,如lxml和html5lib”.它给我的全部内容是从没有连接到原始源文档的数据中提取数据.与html5lib一样,当我访问数据时,所有位置信息都会丢失.我希望/需要直接对解析器进行原始访问.

为了扩展我在开头提到的拼写检查器示例,我想检查文档文本中的单词的拼写(但不是标签名称或属性),并且可能想要跳过检查特定标签的内容(如脚本)或代码标签).因此,我需要一个真正的HTML解析器.但是,在报告拼写错误的单词时,我只对原始源文档中拼写错误的单词的位置感兴趣,而不需要构建树对象.需要说明的是,这只是一个潜在用途的例子.我可以将它用于完全不同的东西,但需求基本相同.事实上,我曾经使用HTMLParser构建了一些非常相似的东西,但从未使用它,因为错误处理不适用于该用例.那是几年前的事了,而且我似乎已经把这个档案遗失了.我想这次使用lxml或html5lib.

那么,有什么我想念的吗?我很难相信这些解析器(除了大多数无用的HTMLParser之外)都没有任何方法可以访问位置信息.但是,如果他们这样做,它必须是无证的,这对我来说似乎很奇怪.