【问题标题】:Python .csv writer putting data on wrong row (Python 3.7) strange formattingPython .csv 编写器将数据放在错误的行(Python 3.7)奇怪的格式
【发布时间】:2019-03-14 16:36:31
【问题描述】:

我正在尝试使用 BeautifulSoup 从网页中提取数据并将该数据格式化为 .csv 文件。我已经非常成功地获取了页面中的数据,但我无法弄清楚如何正确格式化文件。

我的问题是,如果我在第一列中有 10 个项目(带有标题的 11 行),则下一列中的数据从我的第 12 行开始。 .csv 最终看起来是交错的(像楼梯),例如:

Field1,Field2,Field3
data1,,
data1,,
data1,,
,data2,
,data2,
,data2,
,,data3
,,data3
,,data3

显然,使用如下格式的 .csv 会更容易:

Field1,Field2,Field3
data1,data2,data3
data1,data2,data3
data1,data2,data3

我的代码如下所示:

import time
import requests
import csv
from bs4 import BeautifulSoup

# Time to wait between each item.
t = .010

# Create a csv file to write to.
f = open('filename.csv', 'w')
fieldnames = ('Field1','Field2')
writer = csv.DictWriter(f, fieldnames = fieldnames, lineterminator = '\n')
writer.writeheader()

# Define target page.
url = 'https://www.example.com'
page = requests.get(url)
soup = BeautifulSoup(page.text, 'html.parser')

# Filter useful information from the page.
data_list = soup.find(class_='class0')
data_raw = data_list.find_all(class_='class1')
otherData_raw = otherData_list.find_all(class_='class2')

# Extract [data1] from html.
for data_location in data_raw:
    data_refine = data_location.find_all('a')

    for data_item in data_refine:
        field1 = data_item.contents[0]
        writer.writerow({'Field1':field1})
    time.sleep(t)

# Extract [data2] from html.
for otherData_location in otherData_raw:
    otherData_refine = otherData_location.find_all('a')

    for otherData_item in otherData_refine:
        field2 = otherData_item.contents[0]
        writer.writerow({'Field2':field2})
    time.sleep(t)

f.close()

我尝试了一些解决方案,但都没有运气。我是 Python 的初学者,所以如果这是一个愚蠢的问题,我提前道歉。不过,我将非常感谢您对这个问题的任何帮助。谢谢!

【问题讨论】:

    标签: python python-3.x csv beautifulsoup


    【解决方案1】:

    我的建议是在输出任何内容之前收集所有数据。如果您在一行中需要多条数据,请将它们全部添加到列表中,然后将它们写入 CSV,如下所示:

    with open('csv.csv', 'w', encoding='utf-8') as f:
        for line in csv_data:
            f.write(','.join(line) + '\n')
    

    您当然也可以使用 CSV 模块。

    如果你提供一个你想抓取的示例页面以及感兴趣的领域,这将有助于回答你的问题,因为它很模糊

    【讨论】:

      【解决方案2】:

      代码每行写一个单元格:

      writer.writerow({'Field1':field1})
      

      会写

      foo,,  # Only Field1 column is populated
      
      writer.writerow({'Field2':field2})
      

      会写

      ,foo,  # Only Field2 column is popuplated
      

      在写入文件之前收集一行中的所有列

      row = {'Field1: 'foo', 'Field2': 'bar'...}
      writer.writerow(row)
      

      【讨论】:

        猜你喜欢
        • 2017-01-18
        • 2018-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-11
        • 2019-07-21
        • 2020-08-28
        相关资源
        最近更新 更多