1

我有以下代码从 html 文件中删除重复的段落。

from bs4 import BeautifulSoup

fp = open("Input.html", "rb")
soup = BeautifulSoup(fp, "html5lib")

elms = []
for elem in soup.find_all('font'):
    if elem not in elms:
        elms.append(elem)
    else:
        target =elem.findParent().findParent()
        target.decompose()
print(soup.html)

几乎可以工作,但是对于某些元素,我收到此错误

attributeerror: 'nonetype' object has no attribute 'findparent'

有没有办法在发生错误的 HTML 文件中打印行号以检查格式是什么?

代码没有问题的元素结构是这样的

<!DOCTYPE html>
<html>
  <body>
      <p align="left">
        <b><font face="Times New Roman" size="5" color="red">Some text</font></b> 
      </p>
  </body>
</html>

但是由于文件有点大,我没有确定代码卡住的元素的结构。

4

1 回答 1

1

由于您使用的是html5lib解析器,因此如果您使用的是文档中所述的 BeautifulSoup 4.8.1 或更高版本,则可以访问行号:

和解析器可以跟踪在原始文档中找到每个标签的位置html.parserhtml5lib您可以通过Tag.sourceline(行号)和Tag.sourcepos(行内开始标签的位置)访问此信息 [...]

在您的示例中,您可以轻松访问这些信息:

from bs4 import BeautifulSoup

html = """<!DOCTYPE html>
<html>
  <body>
      <p align="left">
        <b><font face="Times New Roman" size="5" color="red">Some text</font></b> 
      </p>
  </body>
</html>
"""

soup = BeautifulSoup(html, "html5lib")

for elem in soup.find_all('font'):
    print(elem.sourceline, elem.sourcepos, elem.string)

这将输出5 60 Some text,其中第一个数字是您的行号。

如果有任何潜在的错误,例如得到 a NoneType,你应该在遇到错误之前处理它。所以不要这样做:

target = elem.findParent().findParent()

您可以先检查,如果您获得第一个方法的结果findParent(),然后执行第二个请求,例如:

target = elem.findParent()
err_line, err_source, err_str = target.sourceline, target.sourcepos, target.string
if target:
    target = target.findParent()
else:
    print(f"Error near line {err_line} ({err_source}). Last good text: {err_str}")
于 2020-03-04T20:43:23.963 回答