Gấu trúc read_csv từ url


138

Tôi đang sử dụng Python 3.4 với IPython và có đoạn mã sau. Tôi không thể đọc tệp csv từ URL đã cho:

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)

Tôi có lỗi sau

"Tên đường dẫn tệp dự kiến ​​hoặc đối tượng giống như tệp, có loại"

Làm thế nào tôi có thể sửa lỗi này?


Bạn sẽ cần một cái gì đó giống như c=pd.read_csv(io.StringIO(s.decode("utf-8")))nhưng bạn đang nhận được html không phải là tệp csv vì vậy nó sẽ không hoạt động
Padraic Cickyham

3
Tôi khá chắc chắn URL bạn muốn là "https://raw.github.com/cs109/2014_data/blob/master/countries.csv".
kylie.a

@venom, chọn câu trả lời phổ biến hơn là câu trả lời đúng
ibodi

Câu trả lời:


166

Cập nhật

Từ gấu trúc 0.19.2bây giờ bạn có thể chỉ cần truyền url trực tiếp .


Giống như lỗi cho thấy, pandas.read_csvcần một đối tượng giống như tệp làm đối số đầu tiên.

Nếu bạn muốn đọc csv từ một chuỗi, bạn có thể sử dụng io.StringIO(Python 3.x) hoặc StringIO.StringIO(Python 2.x) .

Ngoài ra, đối với URL - https://github.com/cs109/2014_data/blob/master/countries.csv - bạn đang nhận được htmlphản hồi, không phải là csv thô, bạn nên sử dụng url được cung cấp bởi Rawliên kết trong trang github cho nhận được phản hồi csv thô, đó là - https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv

Thí dụ -

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

Điều gì xảy ra nếu phản hồi lớn và tôi muốn truyền phát thay vì tiêu thụ bộ nhớ cho nội dung được mã hóa, nội dung được giải mã và đối tượng StringIO?
akaihola

9
Trong phiên bản mới nhất của gấu trúc, bạn có thể cung cấp url trực tiếp tức làc=pd.read_csv(url)
inodb

Thật kỳ lạ là tôi có phiên bản mới hơn pandas(0.23.4), nhưng tôi không thể cung cấp url trực tiếp. Câu trả lời này đã giúp tôi làm việc đó.
Antti

1
"Cập nhật từ gấu trúc 0.19.2 bây giờ bạn có thể chỉ cần truyền url trực tiếp." Trừ khi bạn không thể vì bạn cần truyền các đối số xác thực, trong trường hợp đó, ví dụ ban đầu là rất cần thiết.
Aaron Hall

Giải pháp này vẫn có giá trị nếu bạn cần xử lý lỗi tốt hơn bằng cách sử dụng mã HTTP có thể được trả về bởi đối tượng yêu cầu (ví dụ: 500 -> có thể cần thử lại, 404 -> không thử lại)
JulienV

235

Trong phiên bản mới nhất của gấu trúc ( 0.19.2), bạn có thể trực tiếp chuyển url

import pandas as pd

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

có vẻ như sử dụng trực tiếp thay vì yêu cầu trực tiếp không sử dụng cache yêu cầu ngay cả khi được sử dụng
shadi

5
Mã đó trả về urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)>vì giao thức https mà urllib không thể xử lý.
đa cấp

Đối với những người sử dụng Python 2, bạn sẽ phải sử dụng Python 2.7.10+.
avelis

Dường như có một số vấn đề khi đọc csv từ một URL. Tôi đọc tệp một lần từ bộ nhớ cục bộ và một lần từ URL, tôi liên tục gặp lỗi từ URL. Sau đó, tôi đã kích hoạt error_bad_lines = Sai và hơn 99% dữ liệu đã bị bỏ qua. URL là liên kết . Khi tôi đọc tệp, hình dạng của tập dữ liệu được tìm thấy là (88,1), điều này hoàn toàn sai
Rishik Mani

10

Như tôi đã nhận xét, bạn cần sử dụng một đối tượng StringIO và giải mã tức là c=pd.read_csv(io.StringIO(s.decode("utf-8")))nếu sử dụng các yêu cầu, bạn cần giải mã là .content trả về byte nếu bạn đã sử dụng .text bạn sẽ chỉ cần truyền s như là s = requests.get(url).textc = pd.read_csv(StringIO(s)).

Một cách tiếp cận đơn giản hơn là truyền trực tiếp url chính xác của dữ liệu thôread_csv , bạn không phải truyền một tệp như đối tượng, bạn có thể chuyển một url để bạn không cần yêu cầu gì cả:

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

print(c)

Đầu ra:

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

Từ các tài liệu :

filepath_or_buffer :

chuỗi hoặc xử lý tệp / StringIO Chuỗi có thể là một URL. Các lược đồ URL hợp lệ bao gồm http, ftp, s3 và tệp. Đối với URL tệp, một máy chủ được mong đợi. Chẳng hạn, một tệp cục bộ có thể là tệp: //localhost/path/to/table.csv


1
Bạn có thể cung cấp url trực tiếp cho gấu trúc read_csv! tất nhiên! đó là một giải pháp đơn giản hơn nhiều so với giải pháp tôi tìm thấy! : D
PabTorre

1
@pabtorre, vâng, một ví dụ về lý do tại sao đọc tài liệu là một ý tưởng tốt.
Padraic Cickyham

6

Vấn đề bạn gặp phải là đầu ra bạn nhận được vào biến 's' không phải là csv, mà là tệp html. Để có được csv thô, bạn phải sửa đổi url thành:

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

Vấn đề thứ hai của bạn là read_csv mong đợi một tên tệp, chúng ta có thể giải quyết điều này bằng cách sử dụng StringIO từ mô-đun io. Vấn đề thứ ba là request.get (url) .content cung cấp một luồng byte, chúng ta có thể giải quyết vấn đề này bằng cách sử dụng request.get (url) .text.

Kết quả cuối cùng là mã này:

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

đầu ra:

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

2
url = "https://github.com/cs109/2014_data/blob/master/countries.csv"
c = pd.read_csv(url, sep = "\t")

Vui lòng cung cấp giải thích làm thế nào giải pháp của bạn hoạt động.
Selim Yıldız

0

Để nhập dữ liệu qua URL trong gấu trúc, chỉ cần áp dụng mã đơn giản bên dưới, nó hoạt động thực sự tốt hơn.

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

Nếu bạn gặp sự cố với dữ liệu thô thì chỉ cần đặt 'r' trước URL

import pandas as pd
train = pd.read_table(r"https://urlandfile.com/dataset.csv")
train.head()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.