基于字节大小拆分BeautifulSoup获取的列表为动态命名嵌套列表及问题修复
解决BeautifulSoup爬取段落拆分后子列表重复问题
问题背景
用BeautifulSoup4爬取网页中所有<p>标签内容生成列表后,希望按指定字节大小将原列表拆分为动态命名的嵌套子列表(如CONTENT_SECTION_1、CONTENT_SECTION_2...),用于后续生成JSON对象。但现有代码运行后,所有子列表内容完全重复,需修正实现按字节分配不同段落的效果。
当前错误代码
from bs4 import BeautifulSoup # 模拟爬取的p标签内容列表 p_contents = [ "这是第一段内容,字节数较小。", "这是第二段,内容稍长一点,测试字节拆分逻辑。", "第三段内容,长度中等,用于验证拆分是否正确。", "第四段是很长的内容,用来触发拆分阈值,比如超过指定字节数就新建子列表。" ] # 拆分阈值:每个子列表的最大字节数(按UTF-8计算) MAX_BYTE_SIZE = 100 nested_content = {} temp_list = [] current_bytes = 0 section_num = 1 for content in p_contents: content_bytes = len(content.encode('utf-8')) if current_bytes + content_bytes <= MAX_BYTE_SIZE: temp_list.append(content) current_bytes += content_bytes else: # 错误点:每次都添加同一个temp_list的引用 nested_content[f"CONTENT_SECTION_{section_num}"] = temp_list section_num += 1 # 仅清空列表但未新建对象,引用仍指向原内存 temp_list.clear() temp_list.append(content) current_bytes = content_bytes # 处理最后一段 nested_content[f"CONTENT_SECTION_{section_num}"] = temp_list print(nested_content)
实际错误结果
{ 'CONTENT_SECTION_1': ['第四段是很长的内容,用来触发拆分阈值,比如超过指定字节数就新建子列表。'], 'CONTENT_SECTION_2': ['第四段是很长的内容,用来触发拆分阈值,比如超过指定字节数就新建子列表。'], 'CONTENT_SECTION_3': ['第四段是很长的内容,用来触发拆分阈值,比如超过指定字节数就新建子列表。'] }
重复原因分析
核心问题是复用了同一个列表对象的引用:
- 代码中
temp_list始终是同一个列表对象,每次temp_list.clear()只是清空列表内容,但内存地址不变。 - 往
nested_content中添加的是temp_list的引用,而非列表的副本。后续对temp_list的修改(清空、添加新内容)会同步影响所有已存入的子列表,最终所有子列表都指向最后一次修改后的temp_list内容。
修复后的代码
from bs4 import BeautifulSoup p_contents = [ "这是第一段内容,字节数较小。", "这是第二段,内容稍长一点,测试字节拆分逻辑。", "第三段内容,长度中等,用于验证拆分是否正确。", "第四段是很长的内容,用来触发拆分阈值,比如超过指定字节数就新建子列表。" ] MAX_BYTE_SIZE = 100 nested_content = {} temp_list = [] current_bytes = 0 section_num = 1 for content in p_contents: content_bytes = len(content.encode('utf-8')) if current_bytes + content_bytes <= MAX_BYTE_SIZE: temp_list.append(content) current_bytes += content_bytes else: # 正确做法:添加列表的副本(新建列表对象) nested_content[f"CONTENT_SECTION_{section_num}"] = temp_list.copy() section_num += 1 # 新建空列表,而非清空原列表 temp_list = [content] current_bytes = content_bytes # 处理剩余内容,同样添加副本 if temp_list: nested_content[f"CONTENT_SECTION_{section_num}"] = temp_list.copy() # 转为JSON(可选) import json print(json.dumps(nested_content, ensure_ascii=False, indent=2))
期望正确结果
{ "CONTENT_SECTION_1": [ "这是第一段内容,字节数较小。", "这是第二段,内容稍长一点,测试字节拆分逻辑。" ], "CONTENT_SECTION_2": [ "第三段内容,长度中等,用于验证拆分是否正确。" ], "CONTENT_SECTION_3": [ "第四段是很长的内容,用来触发拆分阈值,比如超过指定字节数就新建子列表。" ] }
内容的提问来源于stack exchange,提问作者NIGHTSCROLLER
相关产品推荐
相关产品推荐

