Yêu cầu HTTP và phân tích cú pháp JSON trong Python


202

Tôi muốn tự động truy vấn Google Maps thông qua API chỉ đường của Google. Ví dụ, yêu cầu này tính toán tuyến đường từ Chicago, IL đến Los Angeles, CA thông qua hai điểm dừng ở Joplin, MO và Oklahoma City, OK:

http://maps.googleapis.com/maps/api/directions/json?origin=Chicago,IL&destination=Los+Angele,CA&waypoint=Joplin,MO|Oklahoma+City,OK&sensor=false

Nó trả về một kết quả ở định dạng JSON .

Làm thế nào tôi có thể làm điều này trong Python? Tôi muốn gửi một yêu cầu như vậy, nhận kết quả và phân tích nó.

Câu trả lời:


348

Tôi khuyên bạn nên sử dụng thư viện yêu cầu tuyệt vời :

import requests

url = 'http://maps.googleapis.com/maps/api/directions/json'

params = dict(
    origin='Chicago,IL',
    destination='Los+Angeles,CA',
    waypoints='Joplin,MO|Oklahoma+City,OK',
    sensor='false'
)

resp = requests.get(url=url, params=params)
data = resp.json() # Check the JSON Response Content documentation below

Nội dung phản hồi JSON: https://requests.readthedocs.io/en/master/user/quickstart/#json-response-content


2
Đối với tôi, tôi cần phải làm json=paramsthay vì params=paramshoặc tôi nhận được một lỗi 500.
demongolem

140

Các requestsmô-đun Python sẽ chăm sóc của cả hai lấy dữ liệu JSON và giải mã nó, do bộ giải mã dựng sẵn JSON của nó. Dưới đây là một ví dụ được lấy từ tài liệu của mô-đun :

>>> import requests
>>> r = requests.get('https://github.com/timeline.json')
>>> r.json()
[{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...

Vì vậy, không có việc phải sử dụng một số mô-đun riêng biệt để giải mã JSON.


4
Nếu bạn cần tương thích với các yêu cầu 0.x (Debian wheezy), bạn nên sử dụng json.load()hoặc json.loads()thay vào đó, như trong 0.x, jsonlà một thuộc tính chứ không phải là một hàm.
nyuszika7h

2
@nyuszika Nếu bạn đang sử dụng debian, nếu có thể, hãy sử dụng pip để nhận các thư viện python mới hơn. Bạn không muốn mã hóa với các thư viện python cũ, trừ khi có một lý do quan trọng để sử dụng những gì debian có trong kho apt.
SHernandez

@SHernandez Đó là một điểm hợp lệ, nhưng một số gói có thể phụ thuộc vào gói python-requests(hoặc python3-requests), vì vậy bạn sẽ cần phải cài đặt ở nơi khác ngoài /usr/localviệc tránh phá vỡ các gói đó. Mặt khác, khi tính di động / khả năng tương thích là không đáng kể, theo tôi nó đáng giá.
nyuszika7h

3
Làm cách nào để chỉ trích xuất một cặp giá trị tên cụ thể từ phản hồi json 'r'?
3lokh

1
Trong r.json()(từ câu trả lời của tôi) bạn có phản hồi thực tế, được giải mã JSON. Bạn có thể truy cập nó như bình thường list/ dict; print r.json()để xem nó trông như thế nào Hoặc tham khảo tài liệu API của dịch vụ bạn đã yêu cầu.
linkyndy

37

requests.json()phương thức tích hợp sẵn

import requests
requests.get(url).json()

25
import urllib
import json

url = 'http://maps.googleapis.com/maps/api/directions/json?origin=Chicago,IL&destination=Los+Angeles,CA&waypoints=Joplin,MO|Oklahoma+City,OK&sensor=false'
result = json.load(urllib.urlopen(url))

3
Cảm ơn sự giúp đỡ của bạn, tuy nhiên cần lưu ý những điều sau: Hàm urllib.urlopen () đã bị xóa trong Python 3.0 có lợi cho urllib2.urlopen ().
Arun

2
Arun, vâng, nhưng nó không còn được đặt tên là urllib2
Corey Goldberg

3
urllib.requestở trong Python 3.
nyuszika7h

Nó không hoạt động. json.loads đưa ra 'TypeError: đối tượng JSON phải là str, không phải' HTTPResponse '' và json.load cho 'TypeError: đối tượng JSON phải là str, không phải là' byte ''
M Hornbacher

16

Sử dụng thư viện yêu cầu, in đẹp các kết quả để bạn có thể xác định vị trí các khóa / giá trị bạn muốn trích xuất tốt hơn, sau đó sử dụng các vòng lặp lồng nhau để phân tích dữ liệu. Trong ví dụ tôi trích xuất từng bước hướng dẫn lái xe.

import json, requests, pprint

url = 'http://maps.googleapis.com/maps/api/directions/json?'

params = dict(
    origin='Chicago,IL',
    destination='Los+Angeles,CA',
    waypoints='Joplin,MO|Oklahoma+City,OK',
    sensor='false'
)


data = requests.get(url=url, params=params)
binary = data.content
output = json.loads(binary)

# test to see if the request was valid
#print output['status']

# output all of the results
#pprint.pprint(output)

# step-by-step directions
for route in output['routes']:
        for leg in route['legs']:
            for step in leg['steps']:
                print step['html_instructions']

Michael, làm thế nào tôi có thể hiểu được điều này một khi tôi có được dữ liệu? Làm cách nào để hiển thị nó ở định dạng trực quan json "cổ điển" (giống như định dạng bạn nhận được trong trình duyệt của mình)? Đây là những gì tôi nhận được trong thiết bị đầu cuối của mình: [link] s13.postimg.org/3r55jajk7/terminal.png
Alexander Starbuck

3
@AlexStarbuck import pprintsau đó ->pprint.pprint(step['html_instructions'])
Michael

7

Thử cái này:

import requests
import json

# Goole Maps API.
link = 'http://maps.googleapis.com/maps/api/directions/json?origin=Chicago,IL&destination=Los+Angeles,CA&waypoints=Joplin,MO|Oklahoma+City,OK&sensor=false'

# Request data from link as 'str'
data = requests.get(link).text

# convert 'str' to Json
data = json.loads(data)

# Now you can access Json 
for i in data['routes'][0]['legs'][0]['steps']:
    lattitude = i['start_location']['lat']
    longitude = i['start_location']['lng']
    print('{}, {}'.format(lattitude, longitude))

1
yêu cầu có chức năng json riêng
LilaQ

0

Cũng cho Json đẹp trên console:

 json.dumps(response.json(), indent=2)

có thể sử dụng bãi chứa với thụt lề. (Vui lòng nhập json )

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.