(轉)python requests 高級用法 -- 包括SSL 證書錯誤的解決方案


我在使用requests訪問某個https網站時出現錯誤 

error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

找到這篇文章 http://python.codemach.com/pythonrequests-gao-ji-yong-fa.html

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Session Objects會話對象

 

Session對象在請求時允許你堅持一定的參數。此外,還堅持由Session實例的所有請求的cookie。

 

讓我們堅持在請求時使用

 

s = requests.Session()

 

s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')

r = s.get("http://httpbin.org/cookies")

 

print r.text

# '{"cookies": {"sessioncookie":"123456789"}}'

 

會話也可以用於提供默認的數據的請求的方法。這是通過提供的數據會話對象的屬性:

 

s = requests.Session()

s.auth = ('user', 'pass')

s.headers.update({'x-test': 'true'})

 

# both 'x-test' and 'x-test2' are sent

s.get('http://httpbin.org/headers', headers={'x-test2': 'true'})

 

任何字典將被合並session級別的設置的值傳遞給請求方法。方法級別的參數覆蓋會話參數。

 

從一個字典參數中取值

 

如果你想在一個session中刪除一個參數,那么你只需要設置它為none,他便自動被刪去。

 

 

在一個session中的所有值都包含直接提供給你。參閱Session API文檔了解更多信息。

 

請求和響應對象

 

>>> r = requests.get('http://en.wikipedia.org/wiki/Monty_Python')

 

查看

 

>>> r.headers

{'content-length': '56170', 'x-content-type-options': 'nosniff','x-cache':

'HIT from cp1006.eqiad.wmnet, MISS from cp1010.eqiad.wmnet','content-encoding':

'gzip', 'age': '3080', 'content-language': 'en', 'vary':'Accept-Encoding,Cookie',

'server': 'Apache', 'last-modified': 'Wed, 13 Jun 2012 01:33:50 GMT',

'connection': 'close', 'cache-control': 'private, s-maxage=0, max-age=0,

must-revalidate', 'date': 'Thu, 14 Jun 2012 12:59:39 GMT', 'content-type':

'text/html; charset=UTF-8', 'x-cache-lookup': 'HIT fromcp1006.eqiad.wmnet:3128,

MISS from cp1010.eqiad.wmnet:80'}

 

但是,如果我們想要得到我們的服務器發送的報頭,我們只需訪問請求,然后請求標頭:

 

>>> r.request.headers

{'Accept-Encoding': 'identity, deflate, compress, gzip',

'Accept': '*/*', 'User-Agent': 'python-requests/1.2.0'}

 

准備請求

 

當你在API呼叫或會話呼叫收到一個Response對象,請求屬性實際上是PreparedRequest使用。在某些情況下,發送請求之前,你不妨做一些額外的工作,身體或頭(或任何其他真的)。這個簡單的配方如下:

 

from requests import Request, Session

 

s = Session()

prepped = Request('GET',  # or any other method, 'POST', 'PUT', etc.

                 url,

                 data=data

                 headers=headers

                 # ...

                 ).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,

             # etc.

             )

print(resp.status_code)

 

既然你沒有做什么特別的請求對象,你准備立即修改的PreparedRequest的對象。然后,您可以發送您所要發送的請求的其他參數。*或Sesssion中。*。

 

SSL證書驗證

 

請求可以驗證SSL證書的HTTPS請求,就像一個網絡瀏覽器。檢查主機的SSL證書,您可以使用校驗參數:

 

>>> requests.get('https://kennethreitz.com', verify=True)

requests.exceptions.SSLError: hostname 'kennethreitz.com' doesn't matcheither of '*.herokuapp.com', 'herokuapp.com'

 

我沒有對這個域的SSL設置,所以它的失敗。好極了 Github上雖然沒有:

 

>>> requests.get('https://github.com', verify=True)

<Response [200]>

 

您也可以通過驗證一個私人證書CA_BUNDLE文件的路徑。您還可以設置環境變量的REQUESTS_CA_BUNDLE。

 

如果你設置驗證設置為False,也可以忽略驗證SSL證書。

 

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

<Response [200]>

 

如果指定了錯誤的路徑或無效的證書:

 

>>> requests.get('https://kennethreitz.com',cert='/wrong_path/server.pem')

SSLError: [Errno 336265225] _ssl.c:347: error:140B0009:SSLroutines:SSL_CTX_use_PrivateKey_file:PEM lib

 

主體內容工作流程

 

默認情況下,當你提出一個請求時,機體的反應是立即下載。您可以重寫此行為,並推遲下載響應的身體,直到您訪問Response.content,與流參數的屬性:

 

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

  ...

 

您可以進一步控制的使用的Response.iter_content和Response.iter_lines方法的工作流程,或從基本的urllib3 urllib3.HTTPResponse在Response.raw閱讀。

 

保持活動

 

需要注意的是發布的連接會回到池會重用所有以讀取的數據:

確保為設置數據流false或閱讀Response對象的內容屬性。

 

流上傳

 

請求支持它允許你發送大量的沒有讀取到內存的流或文件流上傳,。要流和上傳,只需為你的身體提供了一個類似文件的對象:

 

with open('massive-body') as f:

    requests.post('http://some.url/streamed', data=f)

 

塊編碼請求:

 

還請支持分塊傳輸編碼傳出和傳入的請求。要發送一個數據塊編碼的請求,只是提供一個生成器(或任何沒有長度的迭代器)為您的BODY:

 

def gen():

    yield 'hi'

    yield 'there'

 

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

 

事件鈎子:

 

請求有一個鈎子,系統,你可以用它來處理申請過程中的部分或信號事件的處理。

 

您可以指定一個鈎子函數在每個請求的基礎上,通過一個{hook_name:callback_function}字典的鈎請求參數:

 

hooks=dict(response=print_url)

 

那CALLBACK_FUNCTION將收到的數據塊作為第一個參數。

 

>>> requests.get('http://httpbin.org',hooks=dict(response=print_url))

http://httpbin.org

<Response [200]>

 

自定義身份驗證

 

這callback_function將收到一大塊的數據作為第一個參數。

 

from requests.auth import AuthBase

 

class PizzaAuth(AuthBase):

    """Attaches HTTP Pizza Authentication tothe given Request object."""

    def __init__(self, username):

        # setup any auth-related datahere

        self.username = username

 

    def __call__(self, r):

        # modify and return the request

        r.headers['X-Pizza'] =self.username

        return r

 

Then, we can make a request using our Pizza Auth:

 

>>> requests.get('http://pizzabin.org/admin',auth=PizzaAuth('kenneth'))

<Response [200]>

 

 

代理

 

import requests

 

proxies = {

  "http": "http://10.10.1.10:3128",

  "https": "http://10.10.1.10:1080",

}

 

requests.get("http://example.org", proxies=proxies)

 

您還可以配置代理服務器環境HTTP_PROXY and HTTPS_PROXY.

 

$ 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")

 

To use HTTP Basic Auth with your proxy, use the http://user:password@host/syntax:

 

proxies = {

    "http":"http://user:pass@10.10.1.10:3128/",

}

 

遵守:

 

要求是為了符合相關的規范和RFC的合規性,不會造成困難,為用戶。這受到關注,可能會導致一些看似尋常的行為,可能對那些不熟悉有關規范。

 

編碼:

 

如果沒有明確的字符集是在HTTP頭中的Content-Type頭中包含文本。在這種情況下,RFC 2616指定默認的字符集必須是ISO-8859-1

 

HTTP動詞

 

要求提供訪問幾乎是全方位的HTTP動詞:GET,OPTIONS,HEAD,POST,PUT,PATCH和DELETE。下面提供了詳細的例子,使用這些不同的動詞在請求中,使用GitHub的API。

 

>>> import requests

>>> r =requests.get('https://api.github.com/repos/kennethreitz/requests/git/commits/a050faf084662f3a352dd1a941f2c7c9f886d4ad')

 

 

因此,GitHub的返回JSON。我們可以使用r.json的方法來解析為Python對象。

 

>>> commit_data = r.json()

>>> print commit_data.keys()

[u'committer', u'author', u'url', u'tree', u'sha', u'parents', u'message']

>>> print commit_data[u'committer']

{u'date': u'2012-05-10T11:10:50-07:00', u'email': u'me@kennethreitz.com',u'name': u'Kenneth Reitz'}

>>> print commit_data[u'message']

makin' history

 

請求可以很容易地使用各種形式的認證,包括很常見的基本身份驗證。

 

>>> from requests.auth import HTTPBasicAuth

>>> auth = HTTPBasicAuth('fake@example.com','not_a_real_password')

>>> r = requests.post(url=url, data=body, auth=auth)

>>> r.status_code

201

>>> content = r.json()

>>> print content[u'body']

Sounds great! I'll get right on it.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM