zoukankan      html  css  js  c++  java
  • python requests模块

    简介

    Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库,Requests它会比urllib更加方便,可以节约我们大量的工作。

    安装

    pip快速安装

    pip3 install requests
    

    使用

    先上一串代码

    response.text返回的是Unicode格式,通常需要转换为utf-8格式,否则就是乱码。response.content是二进制模式,可以下载视频之类的,如果想看的话需要decode成utf-8格式。
    不管是通过response.content.decode("utf-8)的方式还是通过response.encoding="utf-8"的方式都可以避免乱码的问题发生

    import requests
    response = requests.get("https://www.baidu.com")
    print(type(response))
    print(response.status_code)
    print(type(response.text))
    
    response.encoding = "utf-8"
    print(response.text)
    print(response.cookies)
    print(response.content)
    print(response.content.decode("utf-8"))
    

    请求方式

    HTTP请求的方法:
    HTTP/1.1协议中共定义了八种方法(有时也叫“动作”),来表明Request-URL指定的资源不同的操作方式。
    HTTP1.0定义了三种请求方法:GET, POST 和 HEAD方法。
    HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法

    • 1.OPTIONS
      返回服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性。
    • 2.HEAD
      向服务器索与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以再不必传输整个响应内容的情况下,就可以获取包含在响应小消息头中的元信息。
    • 3.GET
      向特定的资源发出请求。注意:GET方法不应当被用于产生“副作用”的操作中,例如在Web Application中,其中一个原因是GET可能会被网络蜘蛛等随意访问。Loadrunner中对应get请求函数:web_link和web_url
    • 4.POST
      向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 Loadrunner中对应POST请求函数:web_submit_data,web_submit_form
    • 5.PUT
      向指定资源位置上传其最新内容。
    • 6.DELETE
      请求服务器删除Request-URL所标识的资源。
    • 7.TRACE
      回显服务器收到的请求,主要用于测试或诊断。
    • 8.CONNECT
      HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。

    注意:
    1)方法名称是区分大小写的,当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码405(Mothod Not Allowed);当服务器不认识或者不支持对应的请求方法时,应返回状态码501(Not Implemented)。
    2)HTTP服务器至少应该实现GET和HEAD/POST方法,其他方法都是可选的,此外除上述方法,特定的HTTP服务器支持扩展自定义的方法。

    import requests
    r1 = requests.post("http://httpbin.org/post")
    r2 = requests.put("http://httpbin.org/put")
    r3 = requests.delete("http://httpbin.org/delete")
    r4 = requests.head("http://httpbin.org/get")
    r5 = requests.options("http://httpbin.org/get")
    
    print(r1)
    print(r2)
    print(r3)
    print(r4)
    print(r5)
    
    基本Get
    import requests
    url = 'https://www.baidu.com'
    response = requests.get(url)
    print(response.text)
    

     

    带参数的GET请求

    如果想查询http://httpbin.org/get页面的具体参数,需要在url里面加上,例如我想看有没有Host=httpbin.org这条数据,url形式应该是http://httpbin.org/get?Host=httpbin.org

    下面提交的数据是往这个地址传送data里面的数据。

    import requests
    url = 'http://httpbin.org/get'
    
    data = {
       'name':'zhangsan',
       'age':'25'
    }
    
    response = requests.get(url,params=data)
    print(response.url)
    print(response.text)
    
    json数据

    从下面的数据中我们可以得出,如果结果:
    requests中response.json()方法等同于json.loads(response.text)方法。

    import requests
    import json
    
    response = requests.get("http://httpbin.org/get")
    print(type(response.text))
    print(response.text)
    print(response.json())
    print(json.loads(response.text))
    print(type(response.json()))
    
    添加header
    import requests
    url = 'https://www.zhihu.com/'
    
    headers = {
         'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36'
    }
    response = requests.get(url,headers=headers)
    print(response.text)
    
    基本post请求

    通过post把数据提交到url地址,等同于以字典的形式提交form表单里面的数据。

    import requests
    url = 'https://httpbin.org/post'
    data = {
       'name':'jack',
       'age':'23'
    }
    response = requests.post(url,data=data)
    print(response.text)
    

    执行结果:

    {
      "args": {},
      "data": "",
      "files": {},
      "form": {
        "age": "23",
        "name": "jack"
      },
      "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate",
        "Content-Length": "16",
        "Content-Type": "application/x-www-form-urlencoded",
        "Host": "httpbin.org",
        "User-Agent": "python-requests/2.24.0",
        "X-Amzn-Trace-Id": "Root=1-61386488-14f223f6476ba61903060b45"
      },
      "json": null,
      "origin": "101.230.216.177",
      "url": "https://httpbin.org/post"
    }
    
    响应
    import requests
    
    response = requests.get("http://www.baidu.com")
    # 打印请求页面的状态码
    print(type(response.status_code),response.status_code)
    # 打印请求网址的headers所有信息
    print(type(response.headers),response.headers)
    # 打印请求网址的cookies信息
    print(type(response.cookies),response.cookies)
    # 打印请求网址的地址
    print(type(response.url),response.url)
    # 打印请求的历史记录(以列表的形式显示)
    print(type(response.history),response.history)
    

    执行结果:

    <class 'int'> 200
    <class 'requests.structures.CaseInsensitiveDict'> {'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no-transform', 
    'Connection': 'keep-alive', 'Content-Encoding': 'gzip', 'Content-Type': 'text/html', 'Date': 'Wed, 08 Sep 2021 07:27:36 GMT', 'Last-Modified': 'Mon, 23 Jan 2017 13:27:36 GMT', 'Pragma': 'no-cache', 'Server': 'bfe/1.0.8.18', 'Set-Cookie': 'BDORZ=27315; max-age=86400; domain=.baidu.com; path=/', 'Transfer-Encoding': 'chunked'}
    <class 'requests.cookies.RequestsCookieJar'> <RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
    <class 'str'> http://www.baidu.com/
    <class 'list'> []
    

    内置状态码

    100: ('continue',),
    101: ('switching_protocols',),
    102: ('processing',),
    103: ('checkpoint',),
    122: ('uri_too_long', 'request_uri_too_long'),
    200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\o/', '✓'),
    201: ('created',),
    202: ('accepted',),
    203: ('non_authoritative_info', 'non_authoritative_information'),
    204: ('no_content',),
    205: ('reset_content', 'reset'),
    206: ('partial_content', 'partial'),
    207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'),
    208: ('already_reported',),
    226: ('im_used',),
    
    # Redirection.重定向
    300: ('multiple_choices',),
    301: ('moved_permanently', 'moved', '\o-'),
    302: ('found',),
    303: ('see_other', 'other'),
    304: ('not_modified',),
    305: ('use_proxy',),
    306: ('switch_proxy',),
    307: ('temporary_redirect', 'temporary_moved', 'temporary'),
    308: ('permanent_redirect',
          'resume_incomplete', 'resume',), # These 2 to be removed in 3.0
    
    # Client Error.客户端错误
    400: ('bad_request', 'bad'),
    401: ('unauthorized',),
    402: ('payment_required', 'payment'),
    403: ('forbidden',),
    404: ('not_found', '-o-'),
    405: ('method_not_allowed', 'not_allowed'),
    406: ('not_acceptable',),
    407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'),
    408: ('request_timeout', 'timeout'),
    409: ('conflict',),
    410: ('gone',),
    411: ('length_required',),
    412: ('precondition_failed', 'precondition'),
    413: ('request_entity_too_large',),
    414: ('request_uri_too_large',),
    415: ('unsupported_media_type', 'unsupported_media', 'media_type'),
    416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'),
    417: ('expectation_failed',),
    418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'),
    421: ('misdirected_request',),
    422: ('unprocessable_entity', 'unprocessable'),
    423: ('locked',),
    424: ('failed_dependency', 'dependency'),
    425: ('unordered_collection', 'unordered'),
    426: ('upgrade_required', 'upgrade'),
    428: ('precondition_required', 'precondition'),
    429: ('too_many_requests', 'too_many'),
    431: ('header_fields_too_large', 'fields_too_large'),
    444: ('no_response', 'none'),
    449: ('retry_with', 'retry'),
    450: ('blocked_by_windows_parental_controls', 'parental_controls'),
    451: ('unavailable_for_legal_reasons', 'legal_reasons'),
    499: ('client_closed_request',),
    
    # Server Error.服务端错误
    500: ('internal_server_error', 'server_error', '/o\', '✗'),
    501: ('not_implemented',),
    502: ('bad_gateway',),
    503: ('service_unavailable', 'unavailable'),
    504: ('gateway_timeout',),
    505: ('http_version_not_supported', 'http_version'),
    506: ('variant_also_negotiates',),
    507: ('insufficient_storage',),
    509: ('bandwidth_limit_exceeded', 'bandwidth'),
    510: ('not_extended',),
    511: ('network_authentication_required', 'network_auth', 'network_authentication'),
    
    import requests
    response = requests.get('http://www.jianshu.com/404.html')
    # 使用requests内置的字母判断状态码
    # 如果response返回的状态码是非正常的就返回404错误
    if response.status_code != requests.codes.ok:
      print('404')
    # 如果页面返回的状态码是200,就打印下面的状态
    response = requests.get('https://www.baidu.com')
    if response.status_code == 200:
       print('200')
    

    执行结果:

    404
    200
    

    requests的高级操作

    文件上传
    import requests
    url = "http://httpbin.org/post"
    files = {"files":open("test.jpg","rb")}
    response = requests.post(url,files=files)
    print(response.text)
    
    获取cookie
    import requests
    response = requests.get('https://www.baidu.com')
    print(response.cookies)
    
    for key,value in response.cookies.items():
       print(key,'==',value)
    

    执行结果:

    <RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
    BDORZ == 27315
    

    cookie与session的区别

    简易版:

    • 1.session在服务器端,cookie 在客户端(浏览器)
    • 2.session默认被存在在服务器的一个文件里(不是内存)
    • 3.session的运行依赖session id,而session id是存在cookie中的,也就是说,如果浏览器禁用了cookie,同时,session也会失效(但是可以通过其它方式实现,比如在url中传递session_id)
    • 4.session可以放在文件、数据库、或内存中都可以。
    • 5.用户验证这种场合一般会用session。因此,维持一个会话的核心就是客户端的唯一标识,即session id。

    详细版:

    • 1.由于HTTP协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识具体的用户,这个机制就是Session.典型的场景比如购物车,当你点击下单按钮时,由于HTTP协议无状态,所以并不知道是哪个用户操作的,所以服务端要为特定的用户创建了特定的Session,用于标识这个用户,并且跟踪用户,这样才知道购物车里面有几本书。这个Session是保存在服务端的,有一个唯一标识。在服务端保存Session的方法很多,内存、数据库、文件都有。集群的时候也要考虑Session的转移,在大型的网站,一般会有专门的Session服务器集群,用来保存用户会话,这个时候 Session 信息都是放在内存的,使用一些缓存服务比如Memcached之类的来放 Session。
    • 2.思考一下服务端如何识别特定的客户?这个时候Cookie就登场了。每次HTTP请求的时候,客户端都会发送相应的Cookie信息到服务端。实际上大多数的应用都是用 Cookie 来实现Session跟踪的,第一次创建Session的时候,服务端会在HTTP协议中告诉客户端,需要在 Cookie 里面记录一个Session ID,以后每次请求把这个会话ID发送到服务器,我就知道你是谁了。有人问,如果客户端的浏览器禁用了 Cookie 怎么办?一般这种情况下,会使用一种叫做URL重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如 sid=xxxxx 这样的参数,服务端据此来识别用户。
    • 3.Cookie其实还可以用在一些方便用户的场景下,设想你某次登陆过一个网站,下次登录的时候不想再次输入账号了,怎么办?这个信息可以写到Cookie里面,访问网站的时候,网站页面的脚本可以读取这个信息,就自动帮你把用户名给填了,能够方便一下用户。这也是Cookie名称的由来,给用户的一点甜头。
    • 4.总结一下:Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中;
      Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。

    http是无状态协议

    无状态是指,当浏览器给服务器发送请求的时候,服务器响应客户端请求。但是当同一个浏览器再次发送请求给服务器的时候,服务器并不知道他就是刚才的那个浏览器。简单的说,就是服务器不会去记得你,所以就是http的无状态协议。

    会话维持

    cookie的一个作用就是可以用于模拟登陆,做会话维持。

    import requests
    session = requests.session()
    session.get('http://httpbin.org/cookies/set/number/123456')
    response = session.get('http://httpbin.org/cookies')
    print(response.text)
    

    执行结果:

    {
      "cookies": {
        "number": "123456"
      }
    }
    

    证书验证

    无证书访问
    import requests
    response = requests.get('https://www.12306.cn')
    # 在请求https时,requests会进行证书的验证,如果验证失败则会抛出异常
    print(response.status_code)
    
    关闭证书验证
    import requests
    # 关闭验证,但是仍然会报出证书警告
    response = requests.get('https://www.12306.cn',verify=False)
    print(response.status_code)
    
    消除验证证书的警报
    import requests
    from requests.packages import urllib3
    
    urllib3.disable_warnings()
    response = requests.get('https://www.12306.cn',verify=False)
    print(response.status_code)
    

    手动设置证书

    import requests
    # 证书路径,写真实的
    response = requests.get('https://www.12306.cn',cert=('/path/server.crt','/path/key'))
    print(response.status_code)
    

    代理设置

    设置普通代理
    import requests
    proxies = {
       "http":"http://127.0.0.1:9743",
       "https":"https://127.0.0.1:9743",
    }
    response = requests.get("https://www.taobao.com",proxies=proxies)
    print(response.status_code)
    
    设置用户名和密码代理
    import requests
    proxies = {
       "http": "http://user:password@127.0.0.1:9743",
    }
    response = requests.get("https://www.taobao.com",proxies=proxies)
    print(response.status_code)
    

    超时时间

    通过timeout参数可以设置超时的时间

    import requests
    from requests.exceptions import ReadTimeout
    
    try:
        # 设置必须在500ms内收到响应,不然或抛出ReadTimeout异常
        response = requests.get("http://httpbin.org/get",timeout=0.5)
        print(response.status_code)
    except ReadTimeout:
       print('timeout')
    
    认证设置

    通过碰到需要认证的网站可以通过requests.auth模块实现

    import requests
    from requests.auth import HTTPBasicAuth
    # 方法一:
    # r = requests.get('http://120.27.34.24:9001', auth=HTTPBasicAuth('user','123'))
    # 方法二:
    r = requests.get('http://120.27.34.24:9001',auth=('user','123'))
    print(r.status_code)
    
    异常处理

    关于reqeusts的异常在这里可以看到详细内容:http://www.python-requests.org/en/master/api/#exceptions
    所有的异常都是在requests.excepitons中。

    从源码我们可以看出
    RequestException继承IOError,
    HTTPError,ConnectionError,Timeout继承RequestionException
    ProxyError,SSLError继承ConnectionError
    ReadTimeout继承Timeout异常
    这里列举了一些常用的异常继承关系,详细的可以看:
    http://cn.python-requests.org/zh_CN/latest/_modules/requests/exceptions.html#RequestException
    通过下面的例子进行简单的演示:

    import requests
    from requests.exceptions import ReadTimeout,ConnectionError,RequestException
    try:
       response = requests.get("http://httpbin.org/get",timeout=0.5)
       print(response.status_code)
    except ReadTimeout:
       print('Timeout')
    except ConnectionError:
       print('Connection error')
    except RequestException:
       print('Error')
    

    首先被捕捉的异常是timeout,当把网络断掉的haul就会捕捉到ConnectionError,如果前面异常都没有捕捉到,最后也可以通过RequestExctption捕捉到。

  • 相关阅读:
    【转】【SEE】基于SSE指令集的程序设计简介
    【转】【Asp.Net】asp.net服务器控件创建
    ControlTemplate in WPF ——ScrollBar
    ControlTemplate in WPF —— Menu
    ControlTemplate in WPF —— Expander
    ControlTemplate in WPF —— TreeView
    ControlTemplate in WPF —— ListBox
    ControlTemplate in WPF —— ComboBox
    ControlTemplate in WPF —— TextBox
    ControlTemplate in WPF —— RadioButton
  • 原文地址:https://www.cnblogs.com/even160941/p/15244110.html
Copyright © 2011-2022 走看看