【问题标题】:Download CSV directly into Python CSV parser将 CSV 直接下载到 Python CSV 解析器中
【发布时间】:2011-10-02 07:17:12
【问题描述】:

我正在尝试从 Morningstar 下载 CSV 内容,然后解析其内容。如果我将 HTTP 内容直接注入 Python 的 CSV 解析器,则结果格式不正确。然而,如果我将 HTTP 内容保存到文件 (/tmp/tmp.csv),然后将文件导入 python 的 csv 解析器,结果是正确的。换句话说,为什么会:

def finDownload(code,report):
    h = httplib2.Http('.cache')
    url = 'http://financials.morningstar.com/ajax/ReportProcess4CSV.html?t=' + code + '&region=AUS&culture=en_us&reportType='+ report + '&period=12&dataType=A&order=asc&columnYear=5&rounding=1&view=raw&productCode=usa&denominatorView=raw&number=1'
    headers, data = h.request(url)
    return data

balancesheet = csv.reader(finDownload('FGE','is'))
for row in balancesheet:
    print row

返回:

['F']
['o']
['r']
['g']
['e']
[' ']
['G']
['r']
['o']
['u']
     (etc...)

代替:

[Forge Group Limited (FGE) Income Statement']

?

【问题讨论】:

    标签: python parsing csv


    【解决方案1】:

    问题是由于文件的迭代是逐行完成的,而字符串的迭代是逐字符完成的。

    您想要StringIO/cStringIO(Python 2)或io.StringIO(Python 3,感谢 John Machin 指点我),因此可以将字符串视为类似文件的对象:

    Python 2:

    mystring = 'a,"b\nb",c\n1,2,3'
    import cStringIO
    csvio = cStringIO.StringIO(mystring)
    mycsv = csv.reader(csvio)
    

    Python 3

    mystring = 'a,"b\nb",c\n1,2,3'
    import io
    csvio = io.StringIO(mystring, newline="")
    mycsv = csv.reader(csvio)
    

    两者都将正确保留引用字段内的换行符:

    >>> for row in mycsv: print(row)
    ...
    ['a', 'b\nb', 'c']
    ['1', '2', '3']
    

    【讨论】:

    • splitlines 是否也从 Python 3 中消失了?我一直比split('\n') 更喜欢它,因为我患有反斜线恐惧症。
    • -3 csvstring 是一个烂名单。通常 CSV 文件以 CR LF 作为行分隔符;不要使用mystring.split('\n'),使用mystring.splitlines()StringIO 并未“消失”,它已重新定位到 io 模块并重命名为 BytesIO。还有一个 StringIO 适用于 py3k str 对象。见docs.python.org/py3k/library/io.html#module-io
    • @JohnMachin:感谢您的评论。我现在已经改写了几次我的答案,所以我希望它现在能够受到密切关注:)
    • @Tim:你快到了。对于 py2,使用cStringIO.StringIO。 OP 的数据中既没有 ' 也没有 "。默认(并且几乎普遍使用)quotechar"。由于您希望使用引用的嵌入式 LF 显示正确的行为,因此最好丢失 ' quotechar。您的 py3 示例以不切实际的 str 对象开头。 Python 提供的urllib.request.urlopen(url).read() 产生bytes。请注意,payload 以 UTF-8 “BOM”开头(当然,对于 py2 和 py3),所有剩余字节都是 ASCII。 HTH :)
    猜你喜欢
    • 1970-01-01
    • 2015-10-29
    • 2011-08-03
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-22
    相关资源
    最近更新 更多