I am trying to loop through a tab-delimited file of election results using Python. The following code does not work, but when I use a local file with the same results (the commented out line), it does work as expected.
The only thing I can think of is some headers or content type I need to pass the url, but I cannot figure it out.
Why is this happening?
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
Results in:
...
['', '']
['', '']
['2']
['3']
['1']
['1']
['8']
['', '']
['D']
['a']
['v']
['i']
['d']
[' ']
['F']
['r']
['a']
['z']
['i']
['e']
['', '']
...
so whats happening, well, a call to
help
may shed some light.so it appears that
csv.reader
expects an iterator of some kind which will return a line, but we are passing a string which iterates on a char bases which is why its parsing character by character, one way to fix this would be to generate a temp file, but we don't need to, we just need to pass any iterable object.note the following, which simply splits the string to a list of lines, before its fed to the reader.
this seems to work.
I also recommend using
csv.DictReader
its quite useful.basically it returns a dictionary for every row, using the header as the key, this way we don't need to keep track of the order but instead just the name making a bit easier for us ie
row['Votes']
seems more readable thenrow[4]
...Perhaps you want to sniff the dialect through the csv API:
This will produce the correct output.
See also
http://docs.python.org/library/csv.html#csv.Sniffer
Simple problem: The csv.reader didn't expect a string for its input.
Simple solution: Change the input to:
data.splitlines()
.The csv reader expects an iterable that returns lines one at a time. A string, unfortunately, iterates a character at a time. To solve the problem, use splitlines() to turn the string into a list of lines:
This works perfectly:
The first parameter to
csv.reader
should be:as per the docs, and you are passing a string, not a file object. A string behaves as a list of single characters hence the behavior you are observing.