Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 1037|回复: 0

(转)python requests 高级用法 -- 包括SSL 证书错误的解决方案

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-11 03:20:40 | 显示全部楼层 |阅读模式

    我摘取地址为:http://www.cnblogs.com/tk091/p/3671160.html

    我在使用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.

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-22 18:42 , Processed in 0.134212 second(s), 28 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表