首页 > 解决方案 > 如何使用 Python 在 CSV 文件中可变地确定每行的列数?

问题描述

我正在分析有关内幕交易的 xml 结构的文本文件。我编写了一些代码来解析 XML 结构并将输出写入 CSV 文件。文件的结果按行写入,分析的信息写入单独的列中。但是在某些文件中,信息多次出现,我的代码覆盖了单元格中的信息,最后只有一个日期在我的 CSV 文件的单元格中。

import csv
import glob
import re
import string
import time
import bs4 as bs


# User defined directory for files to be parsed
TARGET_FILES = r'D:\files\'
# User defined file pointer to LM dictionary

# User defined output file
OUTPUT_FILE =  r'D:\ouput\Parser.csv'
# Setup output
OUTPUT_FIELDS = [r'Datei', 'transactionDate', r'transactionsCode', r'Director', r'Officer', r'Titel', r'10-% Eigner', r'sonstiges', r'SignatureDate']


def main():

    f_out = open(OUTPUT_FILE, 'w')
    wr = csv.writer(f_out, lineterminator='\n', delimiter=';')
    wr.writerow(OUTPUT_FIELDS)

    file_list = glob.glob(TARGET_FILES)
    for file in file_list:
        print(file)
        with open(file, 'r', encoding='UTF-8', errors='ignore') as f_in:
            soup = bs.BeautifulSoup(f_in, 'xml')

        output_data = get_data(soup)
        output_data[0] = file                       
        wr.writerow(output_data)


def get_data(soup):

# overrides the transactionDate if more than one transactions disclosed on the current form
# the number determine the column for the output


    _odata = [0] * 9

    try:
        for item in soup.find_all('transactionDate'):
            _odata[1] = item.find('value').text               
    except AttributeError:
        _odata[1] = ('keine Angabe')
    try:
        for item in soup.find_all('transactionAcquiredDisposedCode'):
            _odata[2] = item.find('value').text
    except AttributeError:
        _odata[2] = 'ka'
    for item in soup.find_all('reportingOwnerRelationship'):
        try:
            _odata[3] = item.find('isDirector').text
        except AttributeError:
            _odata[3] = ('ka')
        try:
            _odata[4] = item.find('isOfficer').text
        except AttributeError:
            _odata[4] = ('ka')
        try:
            _odata[5] = item.find('officerTitle').text
        except AttributeError:
            _odata[5] = 'ka'
        try:
            _odata[6] = item.find('isTenPercentOwner').text
        except AttributeError:
            _odata[6] = ('ka')
        try:
            _odata[7] = item.find('isOther').text
        except AttributeError:
            _odata[7] = ('ka')
        try:
            for item in soup.find_all('ownerSignature'):
                _odata[8] = item.find('signatureDate').text
        except AttributeError:
            _odata[8] = ('ka')

    return _odata


if __name__ == '__main__':
    print('\n' + time.strftime('%c') + '\nGeneric_Parser.py\n')
    main()
    print('\n' + time.strftime('%c') + '\nNormal termination.')

实际上,代码可以工作,但如果文件中给出了多个事务日期,则会覆盖列。所以我需要一个代码来自动使用每个交易日期的下一列。这怎么能行?如果有人能解决我的问题,我会很高兴。非常感谢!

标签: python-3.xbeautifulsoupxml-parsingexport-to-csv

解决方案


您的问题是您每次都在迭代结果, soup.find_all() 并且每次写入相同的值。你需要 _odata在每次迭代中做一些事情,否则你只会得到最后一次写入的内容。

如果您可以向我们展示您尝试解析的数据实际上是什么样的,也许我们可以给出更具体的答案。


推荐阅读