🎯 Trình duyệt đám mây tùy chỉnh, chống phát hiện được hỗ trợ bởi Chromium tự phát triển, thiết kế dành cho trình thu thập dữ liệu webtác nhân AI. 👉Dùng thử ngay
Quay lại blog

JMESPath Web Scraping: Truy vấn API JSON theo cách khai báo

Emily Chen
Emily Chen

Advanced Data Extraction Specialist

23-Jul-2026

Tóm tắt:

  • jmespath truy vấn JSON một cách rõ ràng. Một biểu thức định hình lại phản hồi API lồng nhau thành các bản ghi phẳng - không có vòng lặp, không cần đi bộ qua từ điển thủ công.
  • Các API JSON là đích lý tưởng nhất để thu thập dữ liệu. Nhiều trang web xây dựng trang của họ từ một điểm cuối JSON phía backend; chỉ cần lấy JSON đó và dữ liệu sẽ đến dưới dạng đã được cấu trúc sẵn.
  • Những gì jmespath không làm là lấy dữ liệu. Nó không có khách hàng HTTP và không phân tích HTML; bạn đưa cho nó một đối tượng JSON đã giải mã và nó truy vấn trên đó.
  • Lấy dữ liệu qua Scrapeless khi API được bảo vệ. Một lần chạy trực tiếp đã lấy một API sản phẩm thông qua Scrapeless Universal Scraping API, sau đó sử dụng jmespath để chọn, lọc và sắp xếp kết quả.
  • Lọc và chiếu trên một dòng. products[?price < \50`].titletrả về sáu sản phẩm có giá dưới 50 đô la;sort_by(products, &price)[0]` trả về sản phẩm rẻ nhất.
  • Miễn phí để bắt đầu ở phía lấy dữ liệu. Tạo khóa API Scrapeless của bạn tại app.scrapeless.com.

jmespath là gì, và không phải là gì

jmespath là một ngôn ngữ truy vấn cho JSON. Bạn viết một biểu thức mô tả hình dạng bạn muốn, và thư viện sẽ đi qua tài liệu và trả về nó - các phép chiếu rút một trường từ mỗi phần tử của danh sách, các bộ lọc chỉ giữ lại các phần tử phù hợp với điều kiện, và các phép đa chọn hash tái tạo lại mỗi phần tử thành một bản ghi nhỏ hơn. Đây là cùng một ngôn ngữ biểu thức mà AWS CLI sử dụng cho cờ --query, được chuẩn hóa bởi tiêu chuẩn JMESPath, và có sẵn như một thư viện Python nhỏ.

Nó là một ngôn ngữ truy vấn, không phải là một công cụ thu thập dữ liệu. jmespath không có khách hàng HTTP, không lấy URL và không phân tích HTML - nó hoạt động trên một giá trị JSON mà bạn đã giải mã trước đó, được định nghĩa bởi tiêu chuẩn trao đổi dữ liệu JSON. Vì vậy, một thiết lập "thu thập dữ liệu web jmespath" là hai lớp: một cái gì đó trả về JSON, và jmespath định hình lại nó. Điều này quan trọng vì một phần lớn dữ liệu trên các trang web hiện đại được phục vụ bởi một API JSON phía backend mà trang gọi ở chế độ nền; truy cập vào điểm cuối đó trực tiếp sẽ bỏ qua việc phân tích HTML hoàn toàn. Khi điểm cuối bị giới hạn địa lý hoặc giới hạn tốc độ, hướng dẫn này sẽ lấy nó qua Scrapeless Universal Scraping API. Đối với phần HTML của thu thập dữ liệu, hướng dẫn thu thập dữ liệu web Python sẽ đề cập đến các bộ chọn.

Cài đặt

jmespath và requests là toàn bộ công cụ. Phiên bản mà hướng dẫn này được viết là jmespath 1.0.1:

bash Copy
pip install "jmespath==1.0.1" requests

Giữ cho khóa của bạn trong môi trường, không bao giờ ở trong mã nguồn:

bash Copy
export SCRAPELESS_API_KEY="sk_your_scrapeless_key"

Lấy dữ liệu từ một API JSON qua Scrapeless

Lớp lấy dữ liệu trả về JSON thô. Bởi vì điểm cuối cung cấp JSON thay vì một trang đã được kết xuất, js_render sẽ không được bật; API Scrapeless xử lý yêu cầu, định tuyến proxy, và bất kỳ kiểm soát truy cập nào phía trước điểm cuối, và trả về nội dung được định nghĩa bởi tiêu chuẩn ngữ nghĩa HTTP. Giải mã nó một lần và jmespath sẽ tiếp nhận:

python Copy
# fetch.py — lấy một API JSON qua Scrapeless, sau đó truy vấn nó
import json
import os

import jmespath
import requests

resp = requests.post(
    "https://api.scrapeless.com/api/v2/unlocker/request",
    headers={"Content-Type": "application/json", "x-api-token": os.environ["SCRAPELESS_API_KEY"]},
    json={"actor": "unlocker.webunlocker", "input": {"url": "https://dummyjson.com/products?limit=10", "js_render": False}},
    timeout=120,
)
resp.raise_for_status()
payload = json.loads(resp.json()["data"])

print("sản phẩm trong trang:", jmespath.search("length(products)", payload))
print("tiêu đề đầu tiên:", jmespath.search("products[0].title", payload))
print("tổng số có sẵn:", jmespath.search("total", payload))

Chạy thử sẽ đọc cấu trúc phản hồi mà không cần một vòng lặp nào:

text Copy
sản phẩm trong trang: 10
tiêu đề đầu tiên: Essence Mascara Lash Princess
tổng số có sẵn: 194

Cuộc gọi Scrapeless là lớp lấy dữ liệu - Universal Scraping API trả về nội dung JSON, và payload bây giờ là một đối tượng Python thông thường mà jmespath có thể truy vấn.

Định hình lại và lọc với jmespath

Mục tiêu của jmespath là biến một phản hồi dài dòng thành chính xác các bản ghi bạn muốn. Một phép chiếu với một hash đa chọn tái tạo lại mỗi sản phẩm; một biểu thức lọc chỉ giữ lại các phần tử phù hợp; sort_by sắp xếp chúng - tất cả như những biểu thức, không phải mã thủ tục:

python Copy
# query.py — định hình lại, lọc và sắp xếp trong ba biểu thức
import json
import os

import jmespath
import requests

resp = requests.post(
"https://api.scrapeless.com/api/v2/unlocker/request",
    headers={"Content-Type": "application/json", "x-api-token": os.environ["SCRAPELESS_API_KEY"]},
    json={"actor": "unlocker.webunlocker", "input": {"url": "https://dummyjson.com/products?limit=10", "js_render": False}},
    timeout=120,
)
resp.raise_for_status()
payload = json.loads(resp.json()["data"])

records = jmespath.search("products[].{title: title, price: price, rating: rating}", payload)
under_50 = jmespath.search("products[?price < `50`].title", payload)
cheapest = jmespath.search("sort_by(products, &price)[0].{title: title, price: price}", payload)

print("records:", len(records))
print("first record:", json.dumps(records[0], ensure_ascii=False))
print("under $50:", len(under_50))
print("cheapest:", json.dumps(cheapest, ensure_ascii=False))

Mỗi dòng là một truy vấn thực hiện công việc của một vòng lặp:

text Copy
records: 10
first record: {"title": "Essence Mascara Lash Princess", "price": 9.99, "rating": 2.56}
under $50: 6
cheapest: {"title": "Red Nail Polish", "price": 8.99}

Đó là toàn bộ extractor: một POST để lấy JSON, ba biểu thức để định hình nó. Bảng băm đa chọn {title: title, price: price} là xương sống — nó loại bỏ các trường bạn không cần và đổi tên các trường bạn giữ lại, vì vậy những gì bạn lưu trữ là chính xác những gì bạn yêu cầu.

Nhận khóa API của bạn trên gói miễn phí: app.scrapeless.com

Mẫu nâng cao

  • Lọc trước khi trình chiếu. products[?rating > \4.5`].{title: title}` giữ lại các kết quả thỏa mãn trước, sau đó định hình chúng; sắp xếp ống theo cách này giữ cho biểu thức dễ đọc và kết quả nhỏ.
  • Làm phẳng danh sách lồng nhau với []. Khi các bản ghi lồng các danh sách riêng của chúng, products[].reviews[].rating làm phẳng mỗi đánh giá xếp hạng qua mỗi sản phẩm thành một danh sách — toán tử làm phẳng thực hiện những gì mà một vòng lặp đôi sẽ làm.
  • Kết nối các biểu thức với |. products | length(@)sort_by(@, &price) | [0] chuỗi một kết quả vào biểu thức tiếp theo; @ là nút hiện tại, đây là cách bạn đưa đầu ra của một truy vấn vào một truy vấn khác.
  • Bảo vệ chống lại các khóa bị thiếu. jmespath trả về None cho một đường dẫn không có thay vì báo lỗi, vì vậy một trường mà chỉ một số bản ghi mang sẽ không làm hỏng truy vấn — kiểm tra None khi bạn lưu trữ nó.

Khắc phục sự cố

  • json.loads báo lỗi trên phản hồi. Điểm cuối trả về HTML, không phải JSON — thường là một trang lỗi hoặc trang chặn. Xác nhận URL là API JSON và không phải trang HTML gọi nó, và rằng việc lấy đã thành công trước khi giải mã.
  • Một trình chiếu trả về danh sách rỗng. Đường dẫn không khớp với hình dạng của tài liệu. In các khóa cấp cao và đi xuống một cấp một lần; Các API JSON lồng các mảng của chúng dưới một khóa như products hoặc results, không ở gốc.
  • Một bộ lọc không khớp với gì cả. Các ký tự dấu ngã là bắt buộc cho số và chuỗi trong một bộ lọc — price < \50`, không phải price < 50`. Nếu không có dấu ngã, giá trị được đọc là tên trường.
  • Kết quả giữ lại các trường bạn không muốn. Bạn đã sử dụng một trình chiếu đơn giản products[] thay vì một bảng băm đa chọn. Thêm .{title: title, price: price} để chọn chỉ các trường cần giữ.

Kết luận

jmespath xứng đáng có vị trí là lớp biến một phản hồi JSON thành các bản ghi mà không cần mã quy trình: các trình chiếu, bộ lọc và sắp xếp dưới dạng các biểu thức đơn lẻ. Lớp giúp bạn có được JSON là việc lấy — một API backend là nguồn sạch nhất, và một POST Scrapeless trả về nội dung của nó qua bất kỳ rào cản nào tại điểm cuối. Nối hai cái lại với nhau và một nguồn cung cấp sản phẩm dài dòng biến thành bốn trường bạn thực sự lưu trữ.

Tạo một tài khoản Scrapeless miễn phí để nhận khóa API, và tài liệu dành cho nhà phát triển bao gồm các tham số unlocker.webunlocker. Kiểm tra giá Scrapeless khi bạn lên kế hoạch cho một công việc định kỳ.

Câu hỏi thường gặp

H: jmespath có thể tự động quét các trang web không?

Không. jmespath truy vấn một giá trị JSON mà bạn đã có; nó không có client HTTP và không truy xuất URL hoặc phân tích HTML. Kết hợp nó với một lớp lấy — ở đây là API Scraping Toàn cầu của Scrapeless, mà trả về nội dung JSON — và jmespath định hình nó thành các bản ghi.

H: Tại sao lại quét một API JSON thay vì trang HTML?

Bởi vì dữ liệu đã đến được cấu trúc. Nhiều trang thực hiện từ một điểm cuối JSON backend mà họ gọi trong nền; gõ vào điểm cuối đó bỏ qua việc phân tích HTML và duy trì chọn lọc hoàn toàn, và jmespath biến phản hồi thành chính xác các bản ghi bạn muốn.

H: jmespath khác gì so với jsonpath?
Cả hai truy vấn JSON, nhưng jmespath có một đặc tả chính thức và một ngôn ngữ biểu thức gọn gàng với các phép chiếu, bộ lọc, hàm và băm đa chọn giúp định hình lại đầu ra. Cú pháp đa chọn của nó — đổi tên và loại bỏ các trường trong truy vấn — là tính năng khiến nó phù hợp để trích xuất.

H: Nếu trang web không có API JSON thì sao?

Vậy hãy phân tích HTML thay vào đó: lấy trang đã được xử lý thông qua Scrapeless và sử dụng một thư viện chọn lọc. jmespath chỉ áp dụng khi nguồn là JSON; hai cách tiếp cận này bao quát hai hình thức mà dữ liệu đến.

H: Việc lấy dữ liệu từ API JSON có hợp pháp không?

Ngôn ngữ truy vấn không thay đổi các quy tắc thu thập. Chỉ lấy các điểm cuối công khai, tôn trọng các điều khoản của trang web và các chỉ thị của rô-bốt được tiêu chuẩn hóa bởi Giao thức loại trừ rô-bốt, giữ cho khối lượng trong giới hạn và xử lý bất kỳ dữ liệu cá nhân nào theo các luật áp dụng cho bạn.

Tại Scrapless, chúng tôi chỉ truy cập dữ liệu có sẵn công khai trong khi tuân thủ nghiêm ngặt các luật, quy định và chính sách bảo mật trang web hiện hành. Nội dung trong blog này chỉ nhằm mục đích trình diễn và không liên quan đến bất kỳ hoạt động bất hợp pháp hoặc vi phạm nào. Chúng tôi không đảm bảo và từ chối mọi trách nhiệm đối với việc sử dụng thông tin từ blog này hoặc các liên kết của bên thứ ba. Trước khi tham gia vào bất kỳ hoạt động cạo nào, hãy tham khảo ý kiến ​​cố vấn pháp lý của bạn và xem xét các điều khoản dịch vụ của trang web mục tiêu hoặc có được các quyền cần thiết.

Bài viết phổ biến nhất

Danh mục