使用BeautifulSoup将批量HTML文件转换为单个CSV的写入问题求助
代码核心问题汇总
- CSV文件打开逻辑错误:你把
open('names.csv', 'w')放在了遍历文件的for循环内部,且使用了覆盖写入模式w,每次循环都会清空之前写入的内容,最终CSV只会保留最后一个htm文件的处理结果,程序如果提前异常终止甚至会出现空文件。 - DictWriter使用方法错误:
csv.DictWriter的writerow方法要求传入字典格式的数据,键对应你定义的fieldnames,你现在传入的是元组,完全不符合调用要求,会直接触发参数异常。 - 语法拼写错误:提取
EDX的时候你写的是.content,其余字段统一用的.contents,二者是不同属性,运行会直接抛出属性不存在的异常。 - 字段格式问题:BeautifulSoup的
contents属性返回的是标签子元素的列表,你需要把它转为纯字符串再写入CSV,否则写入的内容会带有列表格式的方括号、引号等多余字符。 - 缺失表头写入逻辑:你没有调用
writer.writeheader()写入表头,且如果放在循环内会重复写入表头。 - 缺失异常兼容逻辑:如果某个htm文件缺失你要提取的标签,
find方法会返回None,后续调用findNext会直接报错,导致程序中途终止。 - CSV写入格式兼容问题:Windows下写入CSV如果不加
newline=''参数,每一行数据后会多生成空行,使用utf-8-sig编码可以避免Excel打开CSV时出现中文乱码。
修正后可直接运行的代码
import re import csv import os from bs4 import BeautifulSoup path = r'C:/Users/Mx/Testing/Infod' ext = '.htm' # 提前打开CSV、定义字段、写表头,全局只执行一次 with open('names.csv', 'w', encoding='utf-8-sig', newline='') as csvfile: fieldnames = ['Ref', 'country', 'Start date of Validity', 'End date of validity', 'Nomenclature code', 'Classification justification', 'Language', 'Place of issue', 'Date of issue', 'Name and address', 'Description', 'keywords'] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() # 遍历所有htm文件 for filename in os.listdir(path): if not filename.endswith(ext): continue fullpath = os.path.join(path, filename) # 单个文件异常捕获,避免局部问题中断整体运行 try: with open(fullpath, encoding="utf-8") as f: soup = BeautifulSoup(f, 'html.parser') # 提取ref编号 pattern = re.compile(r'GBBTI\S{9}') ref_tag = soup.find('td', text=pattern) ref = ref_tag.get_text(strip=True) if ref_tag else '' # 封装公共字段提取方法,减少重复代码 def get_field(label): tag = soup.find("b", text=label) if not tag: return '' next_td = tag.findNext("td") return next_td.get_text(strip=True) if next_td else '' # 批量提取所有字段 cx = get_field("Issuing country") SDX = get_field("Start date of validity") EDX = get_field("End date of validity") NCX = get_field("Nomenclature code") CJX = get_field("Classification justification") LX = get_field("Language") POIX = get_field("Place of issue") DOIX = get_field("Date of issue") NAAX = get_field("Name and adress") DOGX = get_field("Description of goods") NKX = get_field("National keywords") # 按字典格式写入行 writer.writerow({ 'Ref': ref, 'country': cx, 'Start date of Validity': SDX, 'End date of validity': EDX, 'Nomenclature code': NCX, 'Classification justification': CJX, 'Language': LX, 'Place of issue': POIX, 'Date of issue': DOIX, 'Name and address': NAAX, 'Description': DOGX, 'keywords': NKX }) except Exception as e: print(f"处理文件{filename}出错,已跳过,错误信息:{str(e)}") continue
内容的提问来源于stack exchange,提问作者MxMorrigan
相关产品推荐
相关产品推荐

