คำขอ HTTP และการแยกวิเคราะห์ JSON ใน Python


202

ฉันต้องการสืบค้น Google แผนที่แบบไดนามิกผ่าน Google Directions API ตัวอย่างคำขอนี้คำนวณเส้นทางจาก Chicago, IL ไปยัง Los Angeles, CA ผ่านจุดสองจุดใน Joplin, MO และ Oklahoma City, OK:

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

มันกลับส่งผลให้ในรูปแบบ JSON

ฉันจะทำสิ่งนี้ใน Python ได้อย่างไร ฉันต้องการส่งคำขอดังกล่าวรับผลและแยกวิเคราะห์

คำตอบ:


348

ฉันขอแนะนำให้ใช้ไลบรารีคำขอที่ยอดเยี่ยม :

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

เนื้อหาการตอบกลับ JSON: https://requests.readthedocs.io/en/master/user/quickstart/#json-response-content


2
สำหรับฉันฉันต้องทำjson=paramsแทนparams=paramsหรือได้รับข้อผิดพลาด 500 ครั้ง
demongolem

140

requestsโมดูลหลามดูแลทั้งการเรียกข้อมูล JSON และถอดรหัสเนื่องจากการถอดรหัสในตัวของมัน JSON นี่คือตัวอย่างที่นำมาจากเอกสารของโมดูล :

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

ดังนั้นจึงไม่มีประโยชน์ที่จะต้องใช้โมดูลแยกต่างหากเพื่อถอดรหัส JSON


4
หากคุณต้องการเข้ากันได้กับการร้องขอ 0.x (Debian wheezy) คุณควรใช้json.load()หรือjson.loads()แทนเช่นเดียวกับ 0.x jsonเป็นคุณสมบัติแทนที่จะเป็นฟังก์ชัน
nyuszika7h

2
@nyuszika หากคุณใช้เดเบียนถ้าเป็นไปได้ให้ใช้ pip เพื่อรับไลบรารีหลามที่ใหม่กว่า คุณไม่ต้องการใช้รหัสกับไลบรารีหลามเก่าเว้นแต่ว่ามีเหตุผลสำคัญที่จะใช้สิ่งที่ debian มีในที่เก็บ apt
SHernandez

@SHernandez นั่นเป็นจุดที่ถูกต้อง แต่แพ็คเกจบางอย่างอาจขึ้นอยู่กับแพ็คเกจpython-requests(หรือpython3-requests) ดังนั้นคุณจะต้องติดตั้งที่อื่น/usr/localเพื่อหลีกเลี่ยงการทำลายแพ็คเกจเหล่านั้น ในทางกลับกันเมื่อความสะดวกในการพกพา / ความเข้ากันได้เล็กน้อยในความคิดของฉันมันคุ้มค่า
nyuszika7h

3
วิธีการดึงคู่ค่าชื่อเฉพาะจากการตอบสนอง json 'r'?
3lokh

1
ในr.json()(จากคำตอบของฉัน) คุณมีการตอบสนองที่แท้จริง JSON- ถอดรหัส คุณสามารถเข้าถึงได้เหมือนปกติlist/ dict; print r.json()เพื่อดูว่ามันเป็นอย่างไร หรืออ้างถึงเอกสาร API ของบริการที่คุณได้ร้องขอไว้
linkyndy


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
ขอบคุณสำหรับความช่วยเหลือของคุณอย่างไรก็ตามจะต้องมีการบันทึกสิ่งต่อไปนี้: ฟังก์ชัน urllib.urlopen () ได้ถูกลบออกใน Python 3.0 เพื่อสนับสนุน urllib2.urlopen ()
อรุณ

2
อรุณใช่ แต่ไม่มีชื่อ urllib2
Corey Goldberg

3
มันurllib.requestอยู่ใน Python 3
nyuszika7h

มันไม่ทำงาน. json.loads ให้ 'TypeError: วัตถุ JSON ต้องเป็น str ไม่ใช่' HTTPResponse '' และ json.load ให้ 'TypeError: วัตถุ JSON ต้องเป็น str ไม่ใช่' bytes ''
M Hornbacher

16

ใช้ไลบรารีคำร้องขอพิมพ์ผลลัพธ์เพื่อให้คุณสามารถค้นหาคีย์ / ค่าที่คุณต้องการแยกได้ดีขึ้นจากนั้นใช้ซ้อนสำหรับลูปเพื่อวิเคราะห์ข้อมูล ในตัวอย่างฉันแยกเส้นทางการขับขี่ทีละขั้นตอน

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 ฉันจะทำให้ความรู้สึกนี้ออกมาได้อย่างไรเมื่อฉันได้รับข้อมูล? ฉันจะแสดงในรูปแบบภาพ json "คลาสสิค" (เช่นเดียวกับที่คุณได้รับในเบราว์เซอร์ของคุณ) ได้อย่างไร นี่คือสิ่งที่ฉันได้รับใน terminal ของฉัน: [ลิงค์] s13.postimg.org/3r55jajk7/terminal.png
Alexander Starbuck

3
@AlexStarbuck import pprintแล้ว ->pprint.pprint(step['html_instructions'])
Michael

7

ลองสิ่งนี้:

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
คำขอมีฟังก์ชั่น json ของตัวเอง
LilaQ

0

นอกจากนี้สำหรับ Json ที่สวยบนคอนโซล:

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

เป็นไปได้ที่จะใช้การถ่ายโอนข้อมูลด้วยการเยื้อง (โปรดนำเข้า json )

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.