Python .csv writer, помещающий данные в неправильную строку (Python 3.7) странное форматирование

#python #python-3.x #csv #beautifulsoup

#python #python-3.x #csv #beautifulsoup

Вопрос:

Я пытаюсь использовать 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, поэтому заранее приношу извинения, если это глупый вопрос. Однако я был бы очень признателен за любую помощь в решении этой проблемы. Спасибо!

Ответ №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)