Pandy read_csv z adresu url


138

Używam języka Python 3.4 z IPythonem i mam następujący kod. Nie mogę odczytać pliku CSV z podanego adresu URL:

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)

Mam następujący błąd

„Oczekiwana nazwa ścieżki do pliku lub obiekt podobny do pliku, pobrano typ”

Jak mogę to naprawić?


Potrzebowałbyś czegoś takiego, c=pd.read_csv(io.StringIO(s.decode("utf-8")))ale otrzymujesz z powrotem html, a nie plik csv, więc to nie zadziała
— Padraic Cunningham

3
Jestem prawie pewien, że żądany adres URL to "https://raw.github.com/cs109/2014_data/blob/master/countries.csv".
— kylie.a

@venom, wybrał bardziej popularną odpowiedź jako właściwą
— ibodi

Odpowiedzi:


166

Aktualizacja

Z pand 0.19.2możesz teraz bezpośrednio przekazać adres URL .


Tak jak sugeruje błąd, pandas.read_csvjako pierwszy argument potrzebny jest obiekt podobny do pliku.

Jeśli chcesz odczytać plik csv z łańcucha, możesz użyć io.StringIO(Python 3.x) lub StringIO.StringIO(Python 2.x) .

Również w przypadku adresu URL - https://github.com/cs109/2014_data/blob/master/countries.csv - otrzymujesz htmlodpowiedź zwrotną, a nie surowy csv, powinieneś użyć adresu URL podanego w Rawlinku na stronie github dla uzyskiwanie nieprzetworzonej odpowiedzi csv, czyli - https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv

Przykład -

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')))

Co się stanie, jeśli odpowiedź jest duża i chcę ją przesyłać strumieniowo, zamiast zużywać pamięć na zawartość zakodowaną, zdekodowaną i obiekt StringIO?
— akaihola

9
W najnowszej wersji pandy można podać adres URL bezpośrednio tjc=pd.read_csv(url)
— inodb

Co ciekawe, mam nowszą wersję pandas(0.23.4), ale nie mogłem bezpośrednio podać adresu URL. Ta odpowiedź pomogła mi w uruchomieniu.
— Antti

1
„Aktualizacja z pand w wersji 0.19.2, możesz teraz bezpośrednio przekazać adres URL”. Chyba że nie możesz, ponieważ musisz przekazać argumenty uwierzytelniające, w takim przypadku oryginalny przykład jest bardzo potrzebny.
— Aaron Hall

To rozwiązanie jest nadal cenne, jeśli potrzebujesz lepszej obsługi błędów przy użyciu kodów HTTP, które mogą być zwracane przez obiekt żądania (np.: 500 ->
— ponowna próba

235

W najnowszej wersji pandas ( 0.19.2) możesz bezpośrednio podać adres URL

import pandas as pd

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

wygląda na to, że używanie tego bezpośrednio zamiast żądań bezpośrednio nie używa pamięci podręcznej żądań, nawet jeśli jest używane
— shadi

5
Ten kod powraca z urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)>powodu protokołu https, którego urllib nie obsługuje.
— multigoodverse

Osoby korzystające z Pythona 2 będą musiały używać Pythona 2.7.10+.
— avelis

Wydaje się, że wystąpił problem z odczytem pliku csv z adresu URL. Czytałem plik raz z pamięci lokalnej i raz z adresu URL, ciągle otrzymywałem błędy z adresu URL. Następnie włączyłem error_bad_lines = False i ponad 99% danych zostało zignorowanych. Adres URL to link . Kiedy przeczytałem plik, okazało się, że kształt zbioru danych to (88,1), co jest całkowicie błędne
— Rishik Mani

10

Jak skomentowałem, musisz użyć obiektu StringIO i zdekodować, tj. c=pd.read_csv(io.StringIO(s.decode("utf-8")))Jeśli używasz żądań, musisz zdekodować, ponieważ .content zwraca bajty, jeśli użyłeś .text, po prostu musisz przekazać s tak, jak jest s = requests.get(url).textc = pd.read_csv(StringIO(s)).

Prostszym podejściem jest przekazanie prawidłowego adresu URL surowych danych bezpośrednio do read_csv, nie musisz przekazywać pliku takiego jak obiekt, możesz przekazać adres URL, aby w ogóle nie potrzebować żądań:

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

print(c)

Wynik:

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

Z dokumentów :

filepath_or_buffer :

ciąg lub uchwyt pliku / StringIO Ciąg może być adresem URL. Prawidłowe schematy adresów URL obejmują http, ftp, s3 i file. W przypadku adresów URL plików oczekiwany jest host. Na przykład lokalny plik może mieć postać file: //localhost/path/to/table.csv


1
Możesz podać adres URL bezpośrednio do pandy read_csv! oczywiście! to znacznie prostsze rozwiązanie niż to, które znalazłem! :RE
— PabTorre

1
@pabtorre, tak, przykład, dlaczego czytanie dokumentów jest dobrym pomysłem.
— Padraic Cunningham

6

Problem polega na tym, że wynik, który otrzymujesz do zmiennej 's', nie jest plikiem csv, ale plikiem html. Aby uzyskać nieprzetworzony plik csv, musisz zmodyfikować adres URL na:

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

Drugim problemem jest to, że read_csv oczekuje nazwy pliku, możemy to rozwiązać za pomocą StringIO z modułu io. Trzeci problem polega na tym, że request.get (url) .content dostarcza strumień bajtów, możemy to rozwiązać za pomocą request.get (url) .text.

Wynik końcowy to ten kod:

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))

wynik:

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


0

Aby zaimportować dane przez adres URL w pandach, po prostu zastosuj prosty poniższy kod, który działa lepiej.

import pandas as pd
train = pd.read_table("https://urlandfile.com/dataset.csv")
train.head()

Jeśli masz problemy z nieprzetworzonymi danymi, po prostu wstaw „r” przed adresem URL

import pandas as pd
train = pd.read_table(r"https://urlandfile.com/dataset.csv")
train.head()
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.