Module urllib đã thay đổi cách truy cập hàm request trong Python 3. Điều này có nghĩa là nếu bạn thử tham chiếu hàm "urlopen" theo cách làm trong Python 2, bạn sẽ gặp lỗi AttributeError: 'module' object has no attribute 'urlopen'.
Hướng dẫn này nói về ý nghĩa của lỗi này và tại sao nó được ném ra. Nó đi qua một ví dụ để bạn học cách khắc phục.
AttributeError: 'module' object has no attribute 'urlopen'
Module "urllib" cung cấp nhiều hàm liên quan đến mở URL và đọc dữ liệu từ trang web. Cú pháp sử dụng thư viện này khác nhau giữa Python 2 và Python 3.
Trong Python 2, "urlopen" là một phần của module "urllib". Điều này có nghĩa là bạn có thể import nó vào mã bằng urllib.urlopen. Trong Python 3, "urlopen" là một phần của module "request" bên trong module "urllib":
- Python 2: urllib -> urlopen
- Python 3: urllib -> request -> urlopen
Module "request" là nơi nhiều hàm yêu cầu web trong gói "urllib" được gom lại. AttributeError được ném ra khi bạn cố truy cập thuộc tính từ module không chứa thuộc tính đó. Trong trường hợp này, "urlopen" không phải là một phần của module "urllib".
Ví dụ minh họa
Xây dựng chương trình truy xuất dữ liệu từ dịch vụ JSONPlaceholder. Dịch vụ này cung cấp dữ liệu giả để bạn dùng cho ví dụ.
Truy xuất một bài viết với ID #2. Đầu tiên, import module urllib:
import urllib
Câu lệnh này cho phép bạn dùng hàm từ module "urllib" trong chương trình.
Tiếp theo, tạo yêu cầu dùng "urlopen". Điều này cho phép bạn truy xuất dữ liệu từ endpoint trên API JSONPlaceholder:
data = urllib.urlopen("https://jsonplaceholder.typicode.com/posts/2")
contents = data.read()
print(as_json)
Mã này đọc dữ liệu cho bài viết ID #2 trên API JSONPlaceholder.
Mã in phản hồi từ yêu cầu, định dạng chuỗi JSON, ra console bằng câu lệnh print. Chạy mã và xem kết quả:
Traceback (most recent call last): File "main.py", line 4, indata = urllib.urlopen("https://jsonplaceholder.typicode.com/posts/2") AttributeError: module 'urllib' has no attribute 'urlopen'
Chương trình trả về lỗi.
Giải pháp
Bạn đang dùng cú pháp Python 2 để truy cập phương thức "urlopen". "urlopen" không phải thuộc tính của "urllib" trong Python 3. Bạn tham chiếu "urlopen" như thuộc tính của "urllib" nên chương trình không chạy đúng.
Để khắc phục, import module "request" từ module "urllib". Module này chứa phương thức "urlopen":
import urllib.request
Tiếp theo, thay đổi mã để tham chiếu module urllib.request khi truy xuất dữ liệu từ API JSONPlaceholder:
data = urllib.request.urlopen("https://jsonplaceholder.typicode.com/posts/2")
contents = data.read().decode('utf-8')
print(contents)
Mã này sẽ đọc nội dung endpoint API chúng ta gọi. Chạy mã:
{
"userId": 1,
"id": 2,
"title": "qui est esse",
"body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
}
Bạn đã giải mã phản hồi nhận được bằng phương thức decode(). Làm điều này để bạn có thể đọc giá trị trả về bởi phương thức urlopen() dưới dạng chuỗi.
Kết luận
Hàm "urlopen" không phải đối tượng của "urllib" trong Python 3. Để truy cập hàm này, import "urllib.request" vào mã và tham chiếu hàm urllib.request.urlopen().
Bây giờ bạn đã có kiến thức để khắc phục lỗi Python này như một chuyên gia!