Python-通过代理读取大型在线csv
我有一个在线的Huuuuge csv,我不想在不下载的情况下逐行阅读。但是这个文件在一个代理后面。 我写了这段代码:Python-通过代理读取大型在线csv,python,python-requests,Python,Python Requests,我有一个在线的Huuuuge csv,我不想在不下载的情况下逐行阅读。但是这个文件在一个代理后面。 我写了这段代码: 导入请求 作为pd进口熊猫 输入io cafile='mycert.crt' 代理={“http”:http://ipproxy:port,“https”:http://ipproxy:port"} auth=HttpNtlmAuth('Username','Password') url='1〕http://myurl/ressources.csv' content=reques
导入请求
作为pd进口熊猫
输入io
cafile='mycert.crt'
代理={“http”:http://ipproxy:port,“https”:http://ipproxy:port"}
auth=HttpNtlmAuth('Username','Password')
url='1〕http://myurl/ressources.csv'
content=requests.get(url,proxies=proxies,auth=auth,verify=cafile)
csv\u read=pd.read\u csv(io.StringIO(content.decode('utf-8'))
模式='mypattern'
对于csv_中的行,请阅读:
如果行[0]==模式:
打印(行)
打破
上面的代码可以正常工作,但是由于csv文件的大小,“content=requests.get(…”行需要花费太多时间!”
所以我的问题是:
是否可以通过代理逐行读取在线csv?
以最好的方式,我希望阅读第一行,检查它是否等于我的模式,如果是=中断,如果不是=阅读第二行,依此类推
感谢您的帮助请求。get调用将获取整个文件。您需要实现自己的HTTP代码,一直到套接字级别,以便能够在内容进入时以简单的HTTP get方法处理内容 获得部分结果并分割下载的唯一方法是添加HTTP,如果提供文件支持的服务器是这样的话。(
requests
可以让您设置这些头)
输入高级使用请求:
好消息是请求可以在引擎盖下为你做到这一点-
您可以在调用请求时设置stream=True
参数,它甚至可以让您逐行迭代内容
以下是要求的在引擎盖下的大致功能,以便您可以逐行获取内容:
它将获得reasobale大小的数据块,但肯定不等于一次一行(想想~80字节对100.000字节),因为否则每行都需要一个新的HTTP请求,每个请求的开销也不小,即使是通过相同的TCP连接进行的
无论如何,由于CSV是一种文本格式,在相应地设置范围标题之前,请求和任何其他软件都无法知道行的大小,更不用说要读取的“下一行”的确切大小
因此,要使其工作,必须使用Python代码:
- 如果存在缓冲区,则接受CSV的“新行”请求
文本行,生成下一行
- 否则,对
下一个100KB左右
- 将下载的数据连接到
最后下载行的剩余部分
- 在以下位置拆分下载的数据:
二进制数据中的最后一行馈送
- 保存该文件的其余部分
最后一行
- 将二进制缓冲区转换为文本(您必须
在多字节编码中注意多字节字符边界
(如utf-8)-但在换行时剪切可能会节省您的时间)
- 让出
下一行
您可以将stream=True
传递给请求。get
可避免立即获取整个结果。在这种情况下,您可以通过response.raw
访问伪文件对象,您可以基于此构建CSV阅读器(或者,响应对象具有iter\u内容
和iter\u行
方法,但我不知道将其提供给CSV解析器有多容易)
然而虽然stdlib的csv
模块只产生一系列列表或dict,因此很容易懒惰,但pandas返回一个不懒惰的数据帧,因此您需要获得每个数据块的数据帧或类似的东西。根据Masklin的回答,我的代码现在是这样的:
导入请求
cafile='mycert.crt'
代理={“http”:http://ipproxy:port,“https”:http://ipproxy:port"}
auth=HttpNtlmAuth('Username','Password')
url='1〕http://myurl/ressources.csv'
模式='mypattern'
r=requests.get(url,stream=True,proxies=proxies,verify=cafile)
如果r.encoding为无:
r、 编码='ISO-8859-1'
对于r.iter\u行中的行(decode\u unicode=True):
如果line.split(“;”)[0]==模式:
打印(行)
打破
这是否回答了您的问题?或者您可以使用请求的stream=True
模式和resp.iter\u lines()
:我错过了这一点-我更新了答案以提供此选项。效果非常好!stream=True选项除以4请求时间!如果某些用户需要,我只为他们编写下面的代码!谢谢!