Pandas read_csv dari url

147

Saya menggunakan Python 3.4 dengan IPython dan memiliki kode berikut. Saya tidak dapat membaca file csv dari URL yang diberikan:

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)

Saya mengalami kesalahan berikut

"Nama jalur file yang diharapkan atau objek seperti file, punya tipe"

Bagaimana cara memperbaikinya?

bisa ular
sumber
Anda akan memerlukan sesuatu seperti c=pd.read_csv(io.StringIO(s.decode("utf-8")))tetapi Anda mendapatkan html kembali bukan file csv sehingga tidak akan berfungsi
Padraic Cunningham
4
Saya cukup yakin URL yang Anda inginkan adalah "https://raw.github.com/cs109/2014_data/blob/master/countries.csv".
kylieCatt
@venom, pilih jawaban yang lebih populer sebagai jawaban yang benar
ibodi

Jawaban:

178

Memperbarui

Dari panda 0.19.2sekarang Anda bisa meneruskan url secara langsung .


Sama seperti kesalahan yang disarankan, pandas.read_csvmembutuhkan objek seperti file sebagai argumen pertama.

Jika Anda ingin membaca csv dari sebuah string, Anda dapat menggunakan io.StringIO(Python 3.x) atau StringIO.StringIO(Python 2.x) .

Selain itu, untuk URL - https://github.com/cs109/2014_data/blob/master/countries.csv - Anda mendapatkan htmlrespons balik , bukan csv mentah, Anda harus menggunakan url yang diberikan oleh Rawtautan di laman github untuk mendapatkan respons csv mentah, yaitu - https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv

Contoh -

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')))
Anand S Kumar
sumber
Bagaimana jika responsnya besar dan saya ingin mengalirkannya alih-alih menghabiskan memori untuk konten yang dikodekan, konten yang didekodekan, dan objek StringIO?
akaihola
11
Dalam versi terbaru dari panda Anda dapat memberikan url secara langsung yaituc=pd.read_csv(url)
inodb
Anehnya saya memiliki versi yang lebih baru pandas(0.23.4), tetapi saya tidak dapat memberikan url secara langsung. Jawaban ini membantu saya membuatnya bekerja.
Antti
2
"Perbarui Dari pandas 0.19.2 Anda sekarang dapat langsung meneruskan url." Kecuali Anda tidak bisa karena Anda perlu meneruskan argumen otentikasi, dalam hal ini contoh asli sangat diperlukan.
Aaron Hall
Solusi ini masih berguna jika Anda memerlukan penanganan kesalahan yang lebih baik menggunakan kode HTTP yang mungkin dikembalikan oleh objek permintaan (mis .: 500 -> coba lagi mungkin diperlukan, 404 -> tidak coba lagi)
JulienV
246

Di versi terbaru pandas ( 0.19.2) Anda dapat langsung meneruskan url

import pandas as pd

url="https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv"
c=pd.read_csv(url)
inodb
sumber
tampaknya menggunakan ini secara langsung daripada meminta secara langsung tidak menggunakan cache-permintaan bahkan jika digunakan
shadi
5
Kode itu kembali urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)>karena protokol https yang tidak dapat ditangani urllib.
multigoodverse
Untuk mereka yang menggunakan Python 2, Anda harus menggunakan Python 2.7.10+.
avelis
Sepertinya ada masalah saat membaca csv dari URL. Saya membaca file satu kali dari penyimpanan lokal dan sekali dari URL, saya terus mendapatkan kesalahan dari URL. Saya kemudian mengaktifkan error_bad_lines = False dan lebih dari 99% data diabaikan. URL-nya adalah tautan . Setelah saya membaca file tersebut, bentuk kumpulan data ternyata (88,1), yang sepenuhnya salah
Rishik Mani
Sepertinya tidak berfungsi dengan baik, saya mendapat masalah kesalahan urlopen:<urlopen error [Errno 11004] getaddrinfo failed>
ShinNShirley
11

Seperti yang saya komentari Anda perlu menggunakan objek StringIO dan decode yaitu c=pd.read_csv(io.StringIO(s.decode("utf-8")))jika menggunakan permintaan, Anda perlu mendekode sebagai. Konten mengembalikan byte jika Anda menggunakan. Teks Anda hanya perlu melewati s seperti s = requests.get(url).textc = pd.read_csv(StringIO(s)).

Pendekatan yang lebih sederhana adalah dengan meneruskan url yang benar dari data mentah secara langsung ke read_csv, Anda tidak harus meneruskan file seperti objek, Anda dapat meneruskan url sehingga Anda tidak memerlukan permintaan sama sekali:

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

print(c)

Keluaran:

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

Dari dokumen :

filepath_or_buffer :

string atau file handle / StringIO String itu bisa berupa URL. Skema URL yang valid termasuk http, ftp, s3, dan file. Untuk URL file, sebuah host diharapkan. Misalnya, file lokal dapat berupa file: //localhost/path/to/table.csv

Padraic Cunningham
sumber
1
Anda dapat memberi makan url langsung ke pandas read_csv! tentu saja! itu solusi yang jauh lebih sederhana daripada yang saya temukan! : D
PabTorre
1
@pabtorre, ya, contoh mengapa membaca dokumen adalah ide yang bagus.
Padraic Cunningham
Yang bekerja, dalam kasus saya meskipun, saya harus mengatur param sepfungsi pd.read_csv, seperti: pd.read_csv(StringIO(s), sep='\t'). Jika saya menggunakan pengaturan default sep=None, itu akan menimbulkan kesalahanError tokenizing data. C error: Expected 1 fields in line 6, saw 5
ShinNShirley
Mengapa saya masih mendapatkan satu kolom untuk url ini? ebi.ac.uk/Tools/services/rest/clustalo/result/…
webNoob13
9

Masalah yang Anda hadapi adalah bahwa output yang Anda dapatkan ke variabel 's' bukanlah csv, tetapi file html. Untuk mendapatkan csv mentah, Anda harus mengubah url ke:

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

Masalah kedua Anda adalah read_csv mengharapkan nama file, kita dapat menyelesaikannya dengan menggunakan StringIO dari modul io. Masalah ketiga adalah request.get (url) .content mengirimkan aliran byte, kita dapat menyelesaikannya menggunakan teks request.get (url).

Hasil akhirnya adalah kode ini:

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

keluaran:

>>> c.head()
    Country  Region
0   Algeria  AFRICA
1    Angola  AFRICA
2     Benin  AFRICA
3  Botswana  AFRICA
4   Burkina  AFRICA
PabTorre
sumber
2
url = "https://github.com/cs109/2014_data/blob/master/countries.csv"
c = pd.read_csv(url, sep = "\t")
Gursimran Singh
sumber
Mohon berikan penjelasan bagaimana solusi Anda bekerja.
Selim Yildiz
Ini dapat menimbulkan kesalahan url :urlopen error [Errno 11004] getaddrinfo failed
ShinNShirley
0

Untuk Mengimpor Data melalui URL di pandas cukup terapkan kode sederhana di bawah ini bekerja lebih baik.

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

Jika Anda mengalami masalah dengan data mentah, cukup letakkan 'r' sebelum URL

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