Проста функція URL GET / POST у Python


80

Я не можу здатися Google, але я хочу функцію, яка робить це:

Прийміть 3 аргументи (або більше, будь-які):

  • URL
  • словник параметрів
  • POST або GET

Поверніть мені результати та код відповіді.

Чи є фрагмент, який це робить?


Питання незрозуміле - це стосується локальної URL-адреси, тобто. ви пишете сервер або віддалену URL-адресу, тобто. ви пишете клієнта?
Чарльз Даффі,

Будь ласка, використовуйте більше описових назв у майбутньому.
Кіссакі,

Відповіді:


111

запитів

https://github.com/kennethreitz/requests/

Ось декілька поширених способів його використання:

import requests
url = 'https://...'
payload = {'key1': 'value1', 'key2': 'value2'}

# GET
r = requests.get(url)

# GET with params in URL
r = requests.get(url, params=payload)

# POST with form-encoded data
r = requests.post(url, data=payload)

# POST with JSON 
import json
r = requests.post(url, data=json.dumps(payload))

# Response, status etc
r.text
r.status_code

httplib2

https://github.com/jcgregorio/httplib2

>>> from httplib2 import Http
>>> from urllib import urlencode
>>> h = Http()
>>> data = dict(name="Joe", comment="A test comment")
>>> resp, content = h.request("http://bitworking.org/news/223/Meet-Ares", "POST", urlencode(data))
>>> resp
{'status': '200', 'transfer-encoding': 'chunked', 'vary': 'Accept-Encoding,User-Agent',
 'server': 'Apache', 'connection': 'close', 'date': 'Tue, 31 Jul 2007 15:29:52 GMT', 
 'content-type': 'text/html'}

Ви також можете використатиfrom httplib2 import Http as h
3k

3
@ 3k Ні, він створює екземпляр Httpкласу, не псевдонім:, h = Http()ні h = Http.
ecstaticpeon

@ecstaticpeon ви дуже праві, я, мабуть, дуже втомився. дякую за виправлення!
3к-

Було б непогано, якби ви зробили це рідною мовою без сторонніх бібліотек.
Користувач

52

Ще простіше: за допомогою модуля запитів .

import requests
get_response = requests.get(url='http://google.com')
post_data = {'username':'joeb', 'password':'foobar'}
# POST some form-encoded data:
post_response = requests.post(url='http://httpbin.org/post', data=post_data)

Щоб надіслати дані, які не кодуються у формі, надішліть їх серіалізовано у вигляді рядка (приклад взято з документації ):

import json
post_response = requests.post(url='http://httpbin.org/post', data=json.dumps(post_data))
# If using requests v2.4.2 or later, pass the dict via the json parameter and it will be encoded directly:
post_response = requests.post(url='http://httpbin.org/post', json=post_data)

3
Мені довелося обернути post_data в json.dumps (), перш ніж це спрацювало для мене:data=json.dumps(post_data)
Метт,

1
@Matt, я думаю, що це залежить від того, чи хочете ви надіслати дані, закодовані у формі (просто передайте dict), або дані, які не кодуються у формі (передайте рядок даних JSON). Я посилаюся на документи тут: docs.python-requests.org/en/latest/user/quickstart/…
ropable

чи існує якась версія цього модуля для Windows?
TheGoodUser

@TheGoodUser Ця бібліотека (та багато інших) зібрана для Windows та доступна тут: lfd.uci.edu/~gohlke/pythonlibs/#requests
ropable

33

Ви можете використати це, щоб обернути urllib2:

def URLRequest(url, params, method="GET"):
    if method == "POST":
        return urllib2.Request(url, data=urllib.urlencode(params))
    else:
        return urllib2.Request(url + "?" + urllib.urlencode(params))

Це поверне об'єкт Request, який має дані результатів та коди відповідей.


11
Я віддаю перевагу цьому за дотримання стандартної бібліотеки.
Чарльз Даффі,

це має бути url + "?" замість url + '&'?
Пауло Скардін

1
Це приємно, але якщо бути точним, сам Requestоб’єкт не має даних результатів чи кодів відповідей - його потрібно «запитувати» за допомогою такого методу urlopen.
Бах

@Bach У вас є приклад коду, який відповідає "запитуваному" фрагменту, наприклад urlopen, з методом URLRequest тут? Я ніде не можу знайти.
Єрм

@theJerm, я посилався на це. Спробуйте, r = urllib2.urlopen(url)а потім r.readlines()і / або r.getcode(). Ви також можете розглянути можливість використання Запитів .
Бах

10
import urllib

def fetch_thing(url, params, method):
    params = urllib.urlencode(params)
    if method=='POST':
        f = urllib.urlopen(url, params)
    else:
        f = urllib.urlopen(url+'?'+params)
    return (f.read(), f.code)


content, response_code = fetch_thing(
                              'http://google.com/', 
                              {'spam': 1, 'eggs': 2, 'bacon': 0}, 
                              'GET'
                         )

[Оновлення]

Деякі з цих відповідей старі. Сьогодні я б використовував requestsмодуль, як відповідь robaple.


9

Я знаю, що ви просили GET та POST, але я надам CRUD, оскільки це може знадобитися іншим на всякий випадок: (це було перевірено в Python 3.7 )

#!/usr/bin/env python3
import http.client
import json

print("\n GET example")
conn = http.client.HTTPSConnection("httpbin.org")
conn.request("GET", "/get")
response = conn.getresponse()
data = response.read().decode('utf-8')
print(response.status, response.reason)
print(data)


print("\n POST example")
conn = http.client.HTTPSConnection('httpbin.org')
headers = {'Content-type': 'application/json'}
post_body = {'text': 'testing post'}
json_data = json.dumps(post_body)
conn.request('POST', '/post', json_data, headers)
response = conn.getresponse()
print(response.read().decode())
print(response.status, response.reason)


print("\n PUT example ")
conn = http.client.HTTPSConnection('httpbin.org')
headers = {'Content-type': 'application/json'}
post_body ={'text': 'testing put'}
json_data = json.dumps(post_body)
conn.request('PUT', '/put', json_data, headers)
response = conn.getresponse()
print(response.read().decode(), response.reason)
print(response.status, response.reason)


print("\n delete example")
conn = http.client.HTTPSConnection('httpbin.org')
headers = {'Content-type': 'application/json'}
post_body ={'text': 'testing delete'}
json_data = json.dumps(post_body)
conn.request('DELETE', '/delete', json_data, headers)
response = conn.getresponse()
print(response.read().decode(), response.reason)
print(response.status, response.reason)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.