web-dev-qa-db-fra.com

Pandas read_csv à partir de l'URL

J'utilise Python 3.4 avec IPython et j'ai le code suivant. Je ne parviens pas à lire un fichier csv à partir de l'URL donnée:

import pandas as pd
import requests

url="https://github.com/cs109/2014_data/blob/master/countries.csv"
s=requests.get(url).content
c=pd.read_csv(s)

J'ai l'erreur suivante

"Nom de chemin de fichier attendu ou objet de type fichier, type obtenu"

Comment puis-je réparer cela?

94
venom

Mise à jour

De pandas _0.19.2_, vous pouvez maintenant passer l’url directement .


Comme le suggère l'erreur, _pandas.read_csv_ a besoin d'un objet de type fichier comme premier argument.

Si vous voulez lire le csv d'une chaîne, vous pouvez utiliser io.StringIO (Python 3.x) ou _StringIO.StringIO_ (Python 2.x) .

En outre, pour l'URL - https://github.com/cs109/2014_data/blob/master/countries.csv - vous récupérez html réponse, et non csv brut, vous devez utiliser l'URL indiquée par le lien Raw de la page github pour obtenir une réponse csv brute, qui est - https: // raw .githubusercontent.com/cs109/2014_data/master/countries.csv

Exemple -

_import pandas as pd
import io
import requests
url="https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv"
s=requests.get(url).content
c=pd.read_csv(io.StringIO(s.decode('utf-8')))
_
113
Anand S Kumar

Dans la dernière version de pandas (0.19.2), vous pouvez directement passer l'URL

import pandas as pd

url="https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv"
c=pd.read_csv(url)
191
inodb

Comme je l'ai commenté, vous devez utiliser un objet StringIO et le décoder, c'est-à-dire c=pd.read_csv(io.StringIO(s.decode("utf-8"))) si vous utilisez des requêtes, vous devez le décoder comme .content renvoie bytes si vous utilisiez .text, tel quel s = requests.get(url).text c = pd.read_csv(StringIO(s)).

Une approche plus simple consiste à transmettre l’URL correcte des données raw directement à read_csv, vous ne le faites pas passer un fichier comme objet, vous pouvez passer une url pour ne pas avoir besoin de requêtes du tout:

c = pd.read_csv("https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv")

print(c)

Sortie:

                              Country         Region
0                             Algeria         AFRICA
1                              Angola         AFRICA
2                               Benin         AFRICA
3                            Botswana         AFRICA
4                             Burkina         AFRICA
5                             Burundi         AFRICA
6                            Cameroon         AFRICA
..................................

De la docs :

filepath_or_buffer :

chaîne ou descripteur de fichier/StringIO La chaîne peut être une URL. Les modèles d'URL valides incluent http, ftp, s3 et file. Pour les URL de fichier, un hôte est attendu. Par exemple, un fichier local pourrait être file: //localhost/path/to/table.csv

7
Padraic Cunningham

Le problème que vous rencontrez est que la sortie que vous obtenez dans la variable 's' n'est pas un fichier csv, mais un fichier html. Pour obtenir le csv brut, vous devez modifier l'URL en:

' https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv '

Votre deuxième problème est que read_csv attend un nom de fichier, nous pouvons le résoudre en utilisant StringIO à partir du module io. Le troisième problème est que request.get (url) .content fournit un flux d'octets. Nous pouvons résoudre ce problème en utilisant request.get (url) .text.

Le résultat final est ce code:

from io import StringIO

import pandas as pd
import requests
url='https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv'
s=requests.get(url).text

c=pd.read_csv(StringIO(s))

sortie:

>>> c.head()
    Country  Region
0   Algeria  AFRICA
1    Angola  AFRICA
2     Benin  AFRICA
3  Botswana  AFRICA
4   Burkina  AFRICA
4
PabTorre