gpt4 book ai didi

python - BeautifulSoup4 find_all() 在 extract() 或 decompose() 之后表现奇怪

转载 作者:行者123 更新时间:2023-11-28 16:30:19 25 4
gpt4 key购买 nike

我在使用 BeautifulSoup4 时发现了一个奇怪的行为。我有以下 XML(文件名:fake_product.xml):

<product acronym="ACRO1">
<formats>
<format id="format1">
</format>
<format id="format2">
</format>
<format id="format3">
</format>
<format id="format4">
</format>
<format id="format5">
</format>
<format id="format6">
</format>
</formats>
</product>

这个测试用例失败了:

import unittest
from bs4 import BeautifulSoup


class Test(unittest.TestCase):

def setUp(self):
with open('fake_product.xml') as f:
self.soup = BeautifulSoup(f, 'xml')

def test_product_removal(self):
output = len(self.soup.find_all('format'))
expected = 6
self.assertEqual(output, expected)

format_to_delete = self.soup.find(id='format2')
format_to_delete.extract()
#self.soup = BeautifulSoup(self.soup.prettify(), 'xml')
output = len(self.soup.find_all('format'))
expected -= 1
self.assertEqual(output, expected)

原因是 find_all() 无法再找到所有格式。如果我这样做print self.soup.prettify() 我觉得一切都很好。
如果我取消注释 TestCase 中的注释行并在 extract() 之后创建一个新的 BeautifulSoup 对象,则 find_all() 似乎再次正常工作并且 TestCase 成功。

有人可以向我解释一下这种行为吗?

最佳答案

这是 4.4.0 中引入的错误,请参阅 BeautifulSoup 4 project bug tracker :

In some situations, it seems calling extract() does not correctly adjust the next_sibling attribute of the previous element. This leaves the extracted element in the descendant generator. When later calling find(...) or find_all(...), the search then terminates at the extracted element, causing results to be missed.

This bug也是相关的并且包含一个潜在的修复:

Lines 265, 267, 274, 277 need != changing to is not

Line 290 needs == changing to is

我可以确认它修复了您的特定测试。

如果您不习惯编辑 BeautifulSoup 源代码,那么解决方法是像您一样重建树,或者降级到 4.3.2 直到出现修复程序。

关于python - BeautifulSoup4 find_all() 在 extract() 或 decompose() 之后表现奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32605694/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com