【问题标题】:How to convert HTML table to CSV? [Python]如何将 HTML 表格转换为 CSV? [Python]
【发布时间】:2021-12-28 23:06:25
【问题描述】:

我有一个表格中的固定数据数组结构 我用表格保存了html 现在我试图获取 html 文件中的表格并将其放入 csv 文件中以组织数据(使用我在这里看到的代码)并且我不断收到错误

这是代码(取自本站)

# Importing the required modules 
import os
import sys
import pandas as pd
from bs4 import BeautifulSoup

path = 'file location' + 'file.html'

# empty list
data = []

# for getting the header from
# the HTML file
list_header = []
soup = BeautifulSoup(open(path),'html.parser')
header = soup.find_all("table")[0].find("tr")

for items in header:
    try:
        list_header.append(items.get_text())
    except:
        continue

# for getting the data 
HTML_data = soup.find_all("table")[0].find_all("tr")[1:]

for element in HTML_data:
    sub_data = []
    for sub_element in element:
        try:
            sub_data.append(sub_element.get_text())
        except:
            continue
    data.append(sub_data)

# Storing the data into Pandas
# DataFrame 
dataFrame = pd.DataFrame(data = data, columns = list_header)

# Converting Pandas DataFrame
# into CSV file
dataFrame.to_csv('Geeks.csv')

但得到这个错误

File, line 38, in <module>
dataFrame = pd.DataFrame(data = data, columns = list_header)
File, line 509, in __init__
arrays, columns = to_arrays(data, columns, dtype=dtype)
File, line 524, in to_arrays
return _list_to_arrays(data, columns, coerce_float=coerce_float, dtype=dtype)
File, line 567, in _list_to_arrays
raise ValueError(e) from e
ValueError: 1 columns passed, passed data had 7 columns

我做错了什么?

【问题讨论】:

  • 刚刚读取错误,ValueError: 1 columns passed, passed data had 7 columns,看起来您的标题有 1 个元素,但您的数据每行有 7 个元素;或者也许是相反的方式。打印标题和第一行,看看列是否匹配。

标签: pandas dataframe csv beautifulsoup


【解决方案1】:

我看到您的示例代码中缺少的重要一点是您没有在每个行元素中迭代 td 元素,也许 for sub_element in element 行进行单元格迭代,但不清楚。对于您自己和其他需要阅读您的代码的人(例如,我们?),我建议非常明确地查找和迭代元素。

我没有安装 BeautifulSoup (BS) 或 Pandas,但我想提供以下作为模板,用于显式遍历表的层次结构。我正在使用 Python 的标准 xmlcsv 模块。 (我认为 BS API 与 ElementTree 足够相似,可以指导您)

这是一个非常简单的带有表格的 HTML,input.html

<html>
<body>
<table>
    <tr><td>Col1</td><td>Col2</td><td>Col3</td></tr>
    <tr><td>Row1Col1</td><td>Row1Col2</td><td>Row1Col3</td></tr>
    <tr><td>Row2Col1</td><td>Row2Col2</td><td>Row2Col3</td></tr>
    <tr><td>Row3Col1</td><td>Row3Col2</td><td>Row3Col3</td></tr>
    <tr><td>Row4Col1</td><td>Row4Col2</td><td>Row4Col3</td></tr>
</table>
</body>
</html>
import csv
from xml.etree import ElementTree as ET

# Accumulate rows from the table
all_rows = []

root = ET.parse('input.html')

# Get the table once
my_table = root.find('.//table')

# Iterate rows (tr) for that table
for elem_tr in my_table.findall('tr'):
    new_row = []

    # Iterate cells (td) per row
    for elem_td in elem_tr.findall('td'):
        # Build your row cell-by-cell
        new_row.append(elem_td.text)

    # Save finished row
    all_rows.append(new_row)

# Finally write all rows
with open('out.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerows(all_rows)

当我运行它时,这是我的 out.csv

Col1,Col2,Col3
Row1Col1,Row1Col2,Row1Col3
Row2Col1,Row2Col2,Row2Col3
Row3Col1,Row3Col2,Row3Col3
Row4Col1,Row4Col2,Row4Col3

【讨论】:

    猜你喜欢
    • 2010-11-27
    • 2017-11-03
    • 2011-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    相关资源
    最近更新 更多