码迷,mamicode.com
首页 > 其他好文 > 详细

Request常用方法(转)

时间:2018-02-06 12:55:15      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:额外   代理   some   open   expires   multipart   develop   头部   cee   

原文地址:http://www.lihuai.net/program/python/1617.html

Python Requests库:HTTP for Humans 
时间: 2014/12/30 | 分类: Python | 作者: 李坏 | 浏览:287 | 抢沙发 
Python标准库中用来处理HTTP的模块是urllib2,不过其中的API太零碎了,requests是更简单更人性化的第三方库。

用pip下载:

pip install requests 
或者git:

git clone git://github.com/kennethreitz/requests.git 
发送请求:

GET方法

>>> import requests
>>> r = requests.get(https://api.github.com/events)
POST方法:
  
>>> r = requests.post("http://httpbin.org/post")
也可以使用其它方法:

>>> r = requests.put("http://httpbin.org/put")
>>> r = requests.delete("http://httpbin.org/delete")
>>> r = requests.head("http://httpbin.org/get")
>>> r = requests.options("http://httpbin.org/get")

 

 

 

也可以将请求方法放在参数中:

>>> import requests
>>> req = requests.request(GET, http://httpbin.org/get)

 

传递参数或上传文件:

1.如果要将参数放在url中传递,使用params参数,可以是字典或者字符串:

>>> payload = {key1: value1, key2: value2}
>>> r = requests.get("http://httpbin.org/get", params=payload)
>>> r.url
uhttp://httpbin.org/get?key2=value2&key1=value1

 

2.如果要将参数放在request body中传递,使用data参数,可以是字典,字符串或者是类文件对象。

使用字典时将发送form-encoded data:

>>> payload = {key1: value1, key2: value2}
>>> r = requests.post("http://httpbin.org/post", data=payload)
>>> print(r.text)
{
  ...
  "form": {
    "key2": "value2",
    "key1": "value1"
  },
  ...
}

 

 

使用字符串时将直接发送数据:

>>> import json
>>> url = https://api.github.com/some/endpoint
>>> payload = {some: data}
>>> r = requests.post(url, data=json.dumps(payload))

流上传:

with open(massive-body, rb) as f:
    requests.post(http://some.url/streamed, data=f)
Chunk-Encoded上传:

def gen():
    yield hi
    yield there

requests.post(http://some.url/chunked, data=gen())

 

3.如果要上传文件,可以使用file参数发送Multipart-encoded数据,file参数是{ ‘name’: file-like-objects}格式的字典 (or {‘name’:(‘filename’, fileobj)}) :

>>> url = http://httpbin.org/post
>>> files = {file: open(report.xls, rb)}
>>> r = requests.post(url, files=files)
>>> r.text
{
  ...
  "files": {
    "file": "<censored...binary...data>"
  },
  ...
}

 

也可以明确设置filename, content_type and headers:

>>> url = http://httpbin.org/post
>>> files = {file: (report.xls, open(report.xls, rb), application/vnd.ms-excel, {Expires: 0})}
>>> r = requests.post(url, files=files)
>>> print r.text
{
  "args": {}, 
  "data": "", 
  "files": {
    "file": "1\t2\r\n"
  }, 
  "form": {}, 
  "headers": {
    "Content-Type": "multipart/form-data; boundary=e0f9ff1303b841498ae53a903f27e565", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.2.1 CPython/2.7.3 Windows/7", 
  }, 
  "url": "http://httpbin.org/post"
}

 

一次性上传多个文件:

>>> url = http://httpbin.org/post
>>> multiple_files = [(images, (foo.png, open(foo.png, rb), image/png)),
                      (images, (bar.png, open(bar.png, rb), image/png))]
>>> r = requests.post(url, files=multiple_files)
>>> r.text
{
  ...
  files: {images: data:image/png;base64,iVBORw ....}
  Content-Type: multipart/form-data; boundary=3131623adb2043caaeb5538cc7aa0b3a,
  ...
}

 

设置Headers

>>> import json
>>> url = https://api.github.com/some/endpoint
>>> payload = {some: data}
>>> headers = {content-type: application/json}
>>> r = requests.post(url, data=json.dumps(payload), headers=headers)

 

Response对象:

获取unicode字符串,会自动根据响应头部的字符编码(r.encoding)进行解码,当然也可以自己设定r.encoding:

>>> r = requests.get(https://github.com/timeline.json)
>>> r.text
u{"message":"Hello there, wayfaring stranger...

 

获取bytes字符串,会自动解码gzip和deflate数据:

>>> r.content
{"message":"Hello there, wayfaring stranger. ..

 

要存储web图片,可以:

>>> from PIL import Image
>>> from StringIO import StringIO
>>> i = Image.open(StringIO(r.content))

 

可以解码json对象:

>>> r.json()
{udocumentation_url: uhttps://developer...
返回raw response,需要在requests请求中将stream设为True:

>>> r = requests.get(https://github.com/timeline.json, stream=True)
>>> r.raw
<requests.packages.urllib3.response.HTTPResponse object at 0x101194810>
>>> r.raw.read(10)
\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03

 

如果不想一次性处理全部的数据,可以:

tarball_url = https://github.com/kennethreitz/requests/tarball/master
r = requests.get(tarball_url, stream=True)
if int(r.headers[content-length]) < TOO_LONG:
  content = r.content
  ...

 

也可以迭代的处理数据:

with open(filename, wb) as fd:
    for chunk in r.iter_content(chunk_size):
        fd.write(chunk)

 

或者:

import json
import requests
r = requests.get(http://httpbin.org/stream/20, stream=True)
for line in r.iter_lines():
    # filter out keep-alive new lines
    if line:
        print(json.loads(line))

 

获取响应代码:

>>> r = requests.get(http://httpbin.org/get)
>>> r.status_code
200

 

获取响应headers:

>>> r.headers
{
    content-encoding: gzip,
    transfer-encoding: chunked,
    connection: close,
    server: nginx/1.0.4,
    x-runtime: 148ms,
    etag: "e1ca502697e5c9317743dc078f67693f",
    content-type: application/json
}

 

获取发送的headers

>>> r.request.headers
{Accept-Encoding: identity, deflate, compress, gzip,
Accept: */*, User-Agent: python-requests/1.2.0}
Cookie

 

获取cookie,返回CookieJar对象:

>>> url = http://www.baidu.com
>>> r = requests.get(url)
>>> r.cookies

 

将CookieJar转为字典:

>>> requests.utils.dict_from_cookiejar(r.cookies)
{BAIDUID: 84722199DF8EDC372D549EC56CA1A0E2:FG=1, BD_HOME: 0, BDSVRTM: 0}

 

将字典转为CookieJar:

requests.utils.cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True)

 

上传自己设置的cookie,使用cookies参数,可以是字典或者CookieJar对象:

>>> url = http://httpbin.org/cookies
>>> cookies = dict(cookies_are=working)
>>> r = requests.get(url, cookies=cookies)
>>> r.text
{"cookies": {"cookies_are": "working"}}

 

如果需要在会话中保留cookie,需要用到后面要说的Session。

Redirection and History

可以用history属性来追踪redirection

>>> r = requests.get(http://github.com)
>>> r.url
https://github.com/
>>> r.status_code
200
>>> r.history
[<Response [301]>]
Session

 

要在会话中保留状态,可以使用request.Session()。

Session可以使用get,post等方法,Session对象在请求时允许你保留一定的参数和自动设置cookie

s = requests.Session()
s.get(http://httpbin.org/cookies/set/sessioncookie/123456789)   #cookie保留在s中
r = s.get("http://httpbin.org/cookies") #再次访问时会保留cookie
print(r.text)
# ‘{"cookies": {"sessioncookie": "123456789"}}‘

 

也可以自己设置headers,cookies:

s = requests.Session()
s.auth = (user, pass)
s.headers.update({x-test: true})
s.get(http://httpbin.org/headers, headers={x-test2: true})    #  ‘x-test‘ and ‘x-test2‘ 都会被发送

 

预设Request

可以在发送request前做些额外的设定

from requests import Request, Session

s = Session()
req = Request(GET, url,
    data=data,
    headers=header
)
prepped = req.prepare()

# do something with prepped.body
# do something with prepped.headers

resp = s.send(prepped,
    stream=stream,
    verify=verify,
    proxies=proxies,
    cert=cert,
    timeout=timeout
)

print(resp.status_code) 

 

验证

Basic Authentication

>>> from requests.auth import HTTPBasicAuth
>>> requests.get(https://api.github.com/user, auth=HTTPBasicAuth(user, pass))
<Response [200]>

 

因为HTTP Basic Auth很常用,所以也可以直接验证:

>>> requests.get(https://api.github.com/user, auth=(user, pass))
<Response [200]>
Digest Authentication

>>> from requests.auth import HTTPDigestAuth
>>> url = http://httpbin.org/digest-auth/auth/user/pass
>>> requests.get(url, auth=HTTPDigestAuth(user, pass))
<Response [200]>
OAuth 1 Authentication

>>> import requests
>>> from requests_oauthlib import OAuth1
>>> url = https://api.twitter.com/1.1/account/verify_credentials.json
>>> auth = OAuth1(YOUR_APP_KEY, YOUR_APP_SECRET,
                  USER_OAUTH_TOKEN, USER_OAUTH_TOKEN_SECRET)
>>> requests.get(url, auth=auth)
<Response [200]>
也可以使用自己写的验证类。比如某个web服务接受将X-Pizza报头设置成密码的验证,可以这样写验证类:

from requests.auth import AuthBase
class PizzaAuth(AuthBase):
    """Attaches HTTP Pizza Authentication to the given Request object."""
    def __init__(self, username):
        # setup any auth-related data here
        self.username = username
    def __call__(self, r):
        # modify and return the request
        r.headers[X-Pizza] = self.username
        return r

 

使用:

>>> requests.get(http://pizzabin.org/admin, auth=PizzaAuth(kenneth))
<Response [200]>

 

SSL证书验证

检查主机的ssl证书:

>>> requests.get(https://kennethreitz.com, verify=True)
    raise ConnectionError(e)
ConnectionError: HTTPSConnectionPool(host=kennethreitz.com, port=443): Max retries exceeded with url: / (Caused by <class socket.error>: [Errno 10061] )

 

github是有的:

>>> requests.get(https://github.com, verify=True)
<Response [200]>

 

如果你设置验证设置为False,也可以忽略验证SSL证书。

可以读取验证文件:

>>> requests.get(https://kennethreitz.com, cert=(/path/server.crt, /path/key))

 

代理

使用代理:

import requests
proxies = {
  "http": "http://10.10.1.10:3128",
  "https": "http://10.10.1.10:1080",
}
requests.get("http://example.org", proxies=proxies)

 

可以设置环境变量:

$ export HTTP_PROXY="http://10.10.1.10:3128"
$ export HTTPS_PROXY="http://10.10.1.10:1080"
$ python
>>> import requests
>>> requests.get("http://example.org")

 

如果代理需要验证:

proxies = {
    "http": "http://user:pass@10.10.1.10:3128/",
}

Request常用方法(转)

标签:额外   代理   some   open   expires   multipart   develop   头部   cee   

原文地址:https://www.cnblogs.com/Undo-self-blog/p/8421568.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!