fox*_*ja7 19 python csv python-requests
我正在尝试使用Python循环选项卡分隔的选举结果文件.以下代码不起作用,但是当我使用具有相同结果的本地文件(注释掉的行)时,它确实按预期工作.
我唯一能想到的是我需要传递网址的一些标题或内容类型,但我无法弄清楚.
为什么会这样?
import csv
import requests
r = requests.get('http://vote.wa.gov/results/current/export/MediaResults.txt')
data = r.text
#data = open('data/MediaResults.txt', 'r')
reader = csv.reader(data, delimiter='\t')
for row in reader:
print row
Run Code Online (Sandbox Code Playgroud)
结果是:
...
['', '']
['', '']
['2']
['3']
['1']
['1']
['8']
['', '']
['D']
['a']
['v']
['i']
['d']
[' ']
['F']
['r']
['a']
['z']
['i']
['e']
['', '']
...
Run Code Online (Sandbox Code Playgroud)
Sam*_*lar 39
所以什么事情发生了,好吧,打电话help可能会有所启发.
>>> help(csv.reader)
reader(...)
csv_reader = reader(iterable [, dialect='excel']
[optional keyword args])
for row in csv_reader:
process(row)
The "iterable" argument can be any object that returns a line
of input for each iteration, such as a file object or a list. The
optional "dialect" parameter is discussed below. The function
also accepts optional keyword arguments which override settings
provided by the dialect.
Run Code Online (Sandbox Code Playgroud)
所以看起来csv.reader需要一种会返回一行的迭代器,但我们传递一个字符串,它迭代一个字符串,这就是为什么它按字符解析字符,解决这个问题的一种方法就是生成一个临时文件,但我们不需要,我们只需要传递任何可迭代对象.
请注意以下内容,它只是将字符串拆分为行列表,然后再将其输入读取器.
import csv
import requests
r = requests.get('http://vote.wa.gov/results/current/export/MediaResults.txt')
data = r.text
reader = csv.reader(data.splitlines(), delimiter='\t')
for row in reader:
print row
Run Code Online (Sandbox Code Playgroud)
这似乎有效.
我也建议使用csv.DictReader它非常有用.
>>> reader = csv.DictReader(data.splitlines(), delimiter='\t')
>>> for row in reader:
... print row
{'Votes': '417141', 'BallotName': 'Michael Baumgartner', 'RaceID': '2', 'RaceName': 'U.S. Senator', 'PartyName': '(Prefers Republican Party)', 'TotalBallotsCastByRace': '1387059', 'RaceJurisdictionTypeName': 'Federal', 'BallotID': '23036'}
{'Votes': '15005', 'BallotName': 'Will Baker', 'RaceID': '2', 'RaceName': 'U.S. Senator', 'PartyName': '(Prefers Reform Party)', 'TotalBallotsCastByRace': '1387059', 'RaceJurisdictionTypeName': 'Federal', 'BallotID': '27435'}
Run Code Online (Sandbox Code Playgroud)
基本上它会为每一行返回一个字典,使用标题作为键,这样我们就不需要跟踪顺序了,而只是为了让我们更容易点名,即row['Votes']看起来更具可读性row[4]......
这非常有效:
import csv
reader = csv.reader(open('./MediaResults.txt'),
delimiter='\t')
for row in reader:
print row
Run Code Online (Sandbox Code Playgroud)
第一个参数csv.reader应该是:
任何支持迭代器协议的对象,每次调用next()方法时都返回一个字符串
根据文档,您传递的是字符串,而不是文件对象.字符串表现为单个字符的列表,因此表示您正在观察的行为.
简单的问题:该csv.reader没想到它的输入字符串.
简单的解决方案: 将输入更改为:data.splitlines().
csv阅读器需要一个一次返回一行的iterable.遗憾的是,字符串一次迭代一个字符.要解决此问题,请使用splitlines()将字符串转换为行列表:
reader = csv.reader(data.splitlines(), delimiter='\t')
for row in reader:
print row
Run Code Online (Sandbox Code Playgroud)