Chr*_*ris 30 python csv url python-3.x
我一直在努力解决这个简单的问题,所以我想我会寻求帮助.我正在尝试将国家医学图书馆ftp站点的期刊文章列表读入Python 3.3.2(在Windows 7上).期刊文章位于.csv文件中.
我试过以下代码:
import csv
import urllib.request
url = "ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/file_list.csv"
ftpstream = urllib.request.urlopen(url)
csvfile = csv.reader(ftpstream)
data = [row for row in csvfile]
Run Code Online (Sandbox Code Playgroud)
它会导致以下错误:
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
data = [row for row in csvfile]
File "<pyshell#4>", line 1, in <listcomp>
data = [row for row in csvfile]
_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)
Run Code Online (Sandbox Code Playgroud)
我认为我应该使用字符串而不是字节?任何有关简单问题的帮助,以及对出现问题的解释都将非常感激.
Die*_*anz 44
问题依赖于urllib返回字节.作为证明,您可以尝试使用浏览器下载csv文件并将其作为常规文件打开,问题就消失了.
可以通过适当的编码将字节解码为字符串.例如:
import csv
import urllib.request
url = "ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/file_list.csv"
ftpstream = urllib.request.urlopen(url)
csvfile = csv.reader(ftpstream.read().decode('utf-8')) # with the appropriate encoding
data = [row for row in csvfile]
Run Code Online (Sandbox Code Playgroud)
最后一行也可以是:data = list(csvfile)可以更容易阅读.
顺便说一句,由于csv文件非常大,它可能会减慢和消耗内存.也许最好使用发电机.
编辑: 使用Steven Rumbalski提出的编解码器,因此没有必要读取整个文件进行解码.内存消耗减少,速度提高.
import csv
import urllib.request
import codecs
url = "ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/file_list.csv"
ftpstream = urllib.request.urlopen(url)
csvfile = csv.reader(codecs.iterdecode(ftpstream, 'utf-8'))
for line in csvfile:
print(line) # do something with line
Run Code Online (Sandbox Code Playgroud)
请注意,出于同样的原因,不会创建列表.
即使已经有一个已经接受的答案,我还是想通过展示我是如何使用requests包来实现类似的东西(有时被视为替代方法urlib.request)来增加知识体系.
codecs.itercode()用于解决原始问题的基础仍然与接受的答案相同.
import codecs
from contextlib import closing
import csv
import requests
url = "ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/file_list.csv"
with closing(requests.get(url, stream=True)) as r:
reader = csv.reader(codecs.iterdecode(r.iter_lines(), 'utf-8'))
for row in reader:
print row
Run Code Online (Sandbox Code Playgroud)
在这里,我们还看到通过包提供的流的使用,requests以避免必须首先通过网络将整个文件加载到内存中(如果文件很大,可能需要很长时间).
我认为它可能有用,因为它帮助了我,因为我使用的requests而不是urllib.requestPython 3.6.
一些想法(例如使用closing())是从这个类似的帖子中挑选出来的
| 归档时间: |
|
| 查看次数: |
25305 次 |
| 最近记录: |