当熊猫的read_csv无法读取时,为什么R的read.csv从GitLab URL读取CSV?

问题描述

我注意到熊猫的read_csv()无法读取托管在GitLab上的公共CSV文件

import pandas as pd
df = pd.read_csv("https://gitlab.com/stragu/DSH/-/raw/master/Python/pandas/spi.csv")

我得到的错误(被截断):

HTTPError                                 Traceback (most recent call last)
<ipython-input-3-e1c0b52ee83c> in <module>
----> 1 df = pd.read_csv("https://gitlab.com/stragu/DSH/-/raw/master/Python/pandas/spi.csv")

[...]

~\Anaconda3\lib\urllib\request.py in http_error_default(self,req,fp,code,msg,hdrs)
    647 class HTTPDefaultErrorHandler(BaseHandler):
    648     def http_error_default(self,hdrs):
--> 649         raise HTTPError(req.full_url,hdrs,fp)
    650 
    651 class HTTPRedirectHandler(BaseHandler):

HTTPError: HTTP Error 403: Forbidden

但是,使用R,基函数read.csv()会愉快地读取它:

df <- read.csv("https://gitlab.com/stragu/DSH/-/raw/master/Python/pandas/spi.csv")
head(df)
#>   country_code year   spi
#> 1          AFG 2020 42.29
#> 2          AFG 2019 42.34
#> 3          AFG 2018 40.61
#> 4          AFG 2017 38.94
#> 5          AFG 2016 39.65
#> 6          AFG 2015 38.62

reprex package(v0.3.0)于2020-10-29创建

有什么想法,以及R如何实现它?

使用的版本:

  • R 4.0.3
  • Python 3.7.9
  • 熊猫1.1.3

解决方法

如果您正在寻找解决方法,建议您通过requests库发出GET请求:

import requests
from io import StringIO

url = "https://gitlab.com/stragu/DSH/-/raw/master/Python/pandas/spi.csv"
df = pd.read_csv(StringIO(requests.get(url).text))
df.head()
  country_code  year        spi
0          AFG  2020  42.290001
1          AFG  2019  42.340000
2          AFG  2018  40.610001
3          AFG  2017  38.939999
4          AFG  2016  39.650002

关于它的“为什么”部分,我看到read_csv internally uses urllib for standard URLs,显然该API阻止了该请求,可能是因为它认为您是爬虫。如果我重复相同的过程,但添加“ User-Agent”标头,则请求成功。

TLDR;熊猫做什么和失败:

from urllib.request import Request,urlopen

req = Request(<URL>)
urlopen(req).read() # fails

大熊猫应该为此做些什么:

req = Request(<URL>)
req.add_header('User-Agent',<literally anything>)
urlopen(req).read() # succeeds