在python中从URL读取.csv数据:额外行

在python中从URL读取.csv数据:额外行,python,url,csv,codec,Python,Url,Csv,Codec,关于stackoverflow的第一篇文章,也是python的新手。我正试图从一个来自地下世界的地点读取天气数据。这应该是直截了当的: import csv import urllib2 url = 'http://www.wunderground.com/weatherstation/WXDailyHistory.asp?ID=KMDLAURE4&day=9&month=6&year=2013&graphspan=day&format=1' res

关于stackoverflow的第一篇文章,也是python的新手。我正试图从一个来自地下世界的地点读取天气数据。这应该是直截了当的:

import csv
import urllib2   
url = 'http://www.wunderground.com/weatherstation/WXDailyHistory.asp?ID=KMDLAURE4&day=9&month=6&year=2013&graphspan=day&format=1'
response = urllib2.urlopen(url)
cr = csv.reader(response)
然而,当我这样做时,在所有数据之间会有一条额外的线。因此,如果我检查.csv输出的前几行,我会得到以下结果:

    cr.next()
    Out[210]: []

    cr.next()
    Out[211]: 
    ['Time',
   blah blah blah fields redacted
     'DateUTC<br>']

    cr.next()
    Out[212]: 
    ['2013-06-09 00:07:00',
      blah blah blah data redacted
     '2013-06-09 04:07:00',
     '']

    cr.next()
    Out[213]: ['<br>']

    cr.next()
    Out[214]: 
    ['2013-06-09 00:22:00',
     blah blah blah data redacted,
     '2013-06-09 04:22:00',
     '']
cr.next()
Out[210]:[]
cr.next()
出[211]:
[“时间”,
诸如此类的字段已编辑
“日期UTC
”] cr.next() 出[212]: ['2013-06-09 00:07:00', 诸如此类的数据已编辑 '2013-06-09 04:07:00', ''] cr.next() Out[213]:['
'] cr.next() 出[214]: ['2013-06-09 00:22:00', 诸如此类的数据被编辑了, '2013-06-09 04:22:00', '']

我可以在文件上循环,每隔一行就扔掉一行,或者检查这行是否只包含
并去掉它。对我来说,这是一个不雅观的解决方案,因为真正的“问题”在于阅读文本。这似乎是“二进制打开”或编解码器问题,但如何检查?谢谢

必须有一种方法告诉wunderground返回真正的CSV格式,而不是HTML格式。但是,您可以通过跳过那些太短的行来解决此问题:

import csv
import urllib2   
url = 'http://www.wunderground.com/weatherstation/WXDailyHistory.asp?ID=KMDLAURE4&day=9&month=6&year=2013&graphspan=day&format=1'
response = urllib2.urlopen(url)
cr = csv.reader(response)

for row in cr:
    if len(row) <= 1: continue
    print row
导入csv
导入urllib2
url='1〕http://www.wunderground.com/weatherstation/WXDailyHistory.asp?ID=KMDLAURE4&day=9&month=6&year=2013&graphspan=day&format=1'
response=urlib2.urlopen(url)
cr=csv.reader(响应)
对于cr中的行:

如果len(row)首先,这不是你问题的答案。这是一种使用不同方法解决问题的替代解决方案。

from urllib import urlopen
from csv import DictReader
from StrinIO import StringIO

url = 'http://api.wunderground.com/api/01f4106be8822ff4/history_201300609/q/MD/Laurel.json'
response = StringIO(urlopen(url).read())
weather = DictReader(response)

# Skips header
weather.next()

for w in weather:
    print w
我使用相同的API,获得相同信息的更好方法是使用JSON响应,正如前面所评论的那样

from json import loads
from urllib import urlopen

url = 'http://api.wunderground.com/api/01f4106be8822ff4/history_201300609/q/MD/Laurel.json'
response = loads(urlopen(url).read())

print 'Date', 'Temperature', 'Dew Point', 'Umidity' 
for w in response['history']['observations']:
    print w['date']['pretty'], w['tempi'], w['dewpti'], w['hum']
回应

Date Temperature Dew Point Umidity
12:15 AM EST on January 29, 2013 32.0 32.0 100
12:36 AM EST on January 29, 2013 32.0 32.0 100
12:57 AM EST on January 29, 2013 32.0 32.0 100
1:18 AM EST on January 29, 2013 32.0 32.0 100
1:39 AM EST on January 29, 2013 32.0 32.0 100
{None: ['2013-06-09 00:07:00', '18.5', '17.2', '1015.8', 'WNW', '285', '0.0', '-1607.4', '92', '-2539.7', '', '', '0.0', 'weatherlink.com 1.10', '2013-06-09 04:07:00', '']}
{None: ['<br>']}
{None: ['2013-06-09 00:22:00', '18.6', '17.8', '1015.8', 'WNW', '285', '0.0', '-1607.4', '93', '-2539.7', '', '', '0.0', 'weatherlink.com 1.10', '2013-06-09 04:22:00', '']}
在官方API中,您可以找到更多信息

这里是您问题的解决方案。这是一种将CSV文件作为字典读取的方法。

from urllib import urlopen
from csv import DictReader
from StrinIO import StringIO

url = 'http://api.wunderground.com/api/01f4106be8822ff4/history_201300609/q/MD/Laurel.json'
response = StringIO(urlopen(url).read())
weather = DictReader(response)

# Skips header
weather.next()

for w in weather:
    print w
回应

Date Temperature Dew Point Umidity
12:15 AM EST on January 29, 2013 32.0 32.0 100
12:36 AM EST on January 29, 2013 32.0 32.0 100
12:57 AM EST on January 29, 2013 32.0 32.0 100
1:18 AM EST on January 29, 2013 32.0 32.0 100
1:39 AM EST on January 29, 2013 32.0 32.0 100
{None: ['2013-06-09 00:07:00', '18.5', '17.2', '1015.8', 'WNW', '285', '0.0', '-1607.4', '92', '-2539.7', '', '', '0.0', 'weatherlink.com 1.10', '2013-06-09 04:07:00', '']}
{None: ['<br>']}
{None: ['2013-06-09 00:22:00', '18.6', '17.8', '1015.8', 'WNW', '285', '0.0', '-1607.4', '93', '-2539.7', '', '', '0.0', 'weatherlink.com 1.10', '2013-06-09 04:22:00', '']}
{None:['2013-06-09 00:07:00','18.5','17.2','1015.8','WNW','285','0.0','-1607.4','92','-2539.7','','','','0.0','weatherlink.com 1.10','2013-06-09 04:07:00','
{None:['
']} {无:['2013-06-09 00:22:00','18.6','17.8','1015.8','WNW','285','0.0','-1607.4','93','-2539.7','','','0.0','weatherlink.com 1.10','2013-06-09 04:22:00','']

在这里,你的结果是直接的。更容易处理。

如果你的结果中有

,那么它是HTML文件而不是(正确的)CSV文件。这种情况很糟糕。我查看了网站。看起来它正在返回csv数据,但内容类型错误,这就是为什么在打开url时会得到格式(
)之类的内容。看起来您只需在数据上循环并忽略/远程导致问题的标记。这似乎不是wunderground API调用,此处讨论:。该API返回XML或JSON,但不返回CSV.Right。我试图避免使用API,因为(在我看来)它更适合获取实时预测数据。太棒了。这很有魅力。我理解该类的最后一部分,即当该行为空或仅包含
\n时,您将该行设置为等于下一行(可能已填充)。让removeblank成为一个类而不是仅仅定义函数背后的原因是什么?我需要一个类来保存响应对象。我喜欢你使用API。谢谢如果我现在不使用这个,我最终会使用它。但是,当我运行代码的顶层时,“print w”语句失败,错误为“TypeError:字符串索引必须是整数”