如何用Python/JS提取带<CAPTION>的文本表格数据?代码报错求解
Python 实现方案
核心思路
先用BeautifulSoup定位带<CAPTION>标记的表格,手动提取表格结构再转成DataFrame,规避pandas直接解析不规范HTML触发的ParserError;也可通过调整read_html参数适配非标准表格。
代码示例
from bs4 import BeautifulSoup import pandas as pd # 读取文件内容 with open('table.txt', 'r', encoding='utf-8') as f: content = f.read() soup = BeautifulSoup(content, 'html.parser') # 定位所有带<CAPTION>的表格 tables_with_caption = soup.find_all('table', caption=True) result_dict = {} for table in tables_with_caption: # 获取标题文本 caption_text = table.caption.get_text(strip=True) # 提取表格行 rows = table.find_all('tr') table_data = [] for row in rows: # 提取每个单元格的文本,清理空白 cells = [cell.get_text(strip=True) for cell in row.find_all(['td', 'th'])] if any(cells): # 跳过空行 table_data.append(cells) # 转成DataFrame,自动识别表头 if table_data: df = pd.DataFrame(table_data[1:], columns=table_data[0]) result_dict[caption_text] = df # 示例:提取1994年Inventories数值 for caption, df in result_dict.items(): # 假设表头包含年份,行包含Inventories if 'Inventories' in df.iloc[:,0].values: inv_row = df[df.iloc[:,0] == 'Inventories'] if '1994' in df.columns: print(f"{caption} 1994年Inventories: {inv_row['1994'].values[0]}")
适配ParserError的替代方案
如果坚持用read_html,可通过参数跳过无效行或指定表头:
# 针对单个带caption的表格 table_html = str(tables_with_caption[0]) # 跳过前n行,指定表头行号 df = pd.read_html(table_html, skiprows=1, header=0)[0]
JavaScript (Node.js) 实现方案
用cheerio库解析HTML结构,提取目标表格数据,适合Node.js环境处理本地文件。
代码示例
首先安装依赖:
npm install cheerio fs
然后编写脚本:
const fs = require('fs'); const cheerio = require('cheerio'); // 读取文件 fs.readFile('table.txt', 'utf8', (err, content) => { if (err) throw err; const $ = cheerio.load(content); // 遍历所有带<CAPTION>的表格 $('table:has(caption)').each((idx, table) => { const caption = $(table).find('caption').text().trim(); const rows = $(table).find('tr'); const tableData = []; rows.each((i, row) => { const cells = $(row).find('td, th').map((j, cell) => $(cell).text().trim()).get(); if (cells.some(text => text)) { // 跳过空行 tableData.push(cells); } }); // 转换为结构化数据 const headers = tableData[0]; const dataRows = tableData.slice(1); const structuredData = dataRows.map(row => { const obj = {}; headers.forEach((header, idx) => { obj[header] = row[idx] || ''; }); return obj; }); console.log(`表格标题: ${caption}`); // 示例:提取1994年Inventories数值 const invRow = structuredData.find(item => item[headers[0]] === 'Inventories'); if (invRow && invRow['1994']) { console.log(`1994年Inventories: ${invRow['1994']}`); } }); });
内容的提问来源于stack exchange,提问作者Jerom Ganoć
相关产品推荐
相关产品推荐

