zoukankan      html  css  js  c++  java
  • 网络库requests

    主要介绍以下内容
    1.发送HTTP请求
    2.设置HTTP请求头
    3.抓取二进制数据
    4.POST请求
    5.响应数据
    6.上传文件
    7.处理Cookie
    8.维持会话
    9.SSL证书验证
    10.使用代理
    11.超时处理
    12.身份验证
    13.打包请求








    一.发送HTTP请求

    urllib库中的urlopen方法实际上是以GET方法请求网页,而requests中对应的方法是get,该方法可以接收一个url,然后会返回一个对象,通过get方法的返回值,可以获取HTTP响应数据

    1.1使用get方法访问淘宝首页,并获取get方法返回值类型、状态码、响应体、Cookie等信息(出错 SSLError)

    import requests
    # 屏蔽warning信息
    # requests.packages.urllib3.disable_warnings() # 屏蔽也不行,不是urllib3的把,要requests
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36 '}
    r = requests.get('https://www.taobao.com',headers=headers) # raise SSLError(e, request=request);
    print(type(r))
    print(r.status_code)
    print(type(r.text))
    print(r.cookies)
    print(r.text)
    

    get方法返回的是一个requests.model.Response类型的对象

    1.2GET请求

    要想未get请求指定参数,可以直接将参数加在URL后面,用问号(?)分隔,不过还有另外一种更好的方法,就是使用get方法的params参数,该参数是一个字典类型的值,在字典中每一对key-value,就是一对参数值。如果同时在URL和params参数指定GET请求的参数,那么get方法会将参数合并。如果出现同名的参数,会用列表存储,也就是同名参数的值会按出现的先后顺序保存在列表中
    本例使用get方法访问http://httpbin.org/get,并同时使用url和params参数的方式设置GET请求参数,并返回输出结果

    import requests
    data = {
        'name':'Bill',
        'country':'中国',
        'age':20
    }
    
    r = requests.get('http://httpbin.org/get?name=Mike&country=美国&age=40',params=data)
    print(r.text)
    print(r.json())
    print(r.json()['args']['country'])
    

    二.设置HTTP请求头

    2.1添加HTTP请求头

    使用get方法访问http://httpbin.org/get,并设置了一些请求头,包括User-Agent和一个自定义请求头name,其中name的值为中文

    import requests
    from urllib.parse import quote,unquote
    
    headers = {
        'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36',
        'name':quote('李宁')
    }
    
    r = requests.get('http://httpbin.org/get',headers=headers)
    print(r.text)
    print('Name:',unquote(r.json()['headers']['Name']))
    

    三.抓取二进制数据

    本例使用get方法抓取一个png格式的图像文件,并将其保存为本地文件

    import requests
    
    r = requests.get('http://t.cn/EfgN7gz')
    print(r.text)
    with open('Python从菜鸟到高手.png','wb') as f:
        f.write(r.content)
    
    

    四。POST请求

    在发送POST请求时需要指定data参数,该参数是一个字典类型的值,每一对key-value是一对POST请求参数(表单字段)

    import requests
    data = {
        'name':'Bill',
        'country':'中国',
        'age':20
    }
    
    r = requests.post('http://httpbin.org/post',data=data)
    print(r.text)
    print(r.json())
    print(r.json()['form']['country'])
    

    五。响应数据

    使用get方法向简书发送一个请求,然后得到并输出相应的响应结果

    import requests
    
    headers = {
        'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36',
    }
    
    r = requests.get('http://www.jianshu.com',headers=headers)
    print(type(r.status_code),r.status_code)
    print(type(r.headers),r.headers)
    print(type(r.cookies),r.cookies)
    print(type(r.url),r.url)
    print(type(r.history),r.history)
    
    if not r.status_code == requests.codes.okay:
        print("failed")
    else:
        print("ok")
    

    requests提供了一个code对象,可以直接查看状态码对应的标识(一个字符串),在<requests根目录目录>/requests/status_codes.py

    _codes = {
    
        # Informational.
        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'),
    }
    

    六.上传文件

    在运行本例之前,应先运行upload_server.py文件
    采用的是Post方法的files参数,files参数的值可以是BufferedReader对象,该对象可以用Python语言的内置函数open返回;就是一个字典形式,file为键的字典,值为打开一个文件的对象。

    import requests
    
    files1 = {'file':open('Python从菜鸟到高手.png','rb')}
    r1 = requests.post('http://127.0.0.1:5000', files=files1)
    print(r1.text)
    files2 = {'file':open('Python从菜鸟到高手.png','rb')}
    r2 = requests.post('http://httpbin.org/post',files=files2)
    print(r2.text)
    

    7.处理Cookie(cookie失效,我也不知道如何用cookie返回原有保持cookie的值)

    有两种方式设置Coolie:1.headers参数;2.cookies参数

    7.1Get和Post方法都有这两个参数,如果使用cookies参数,需要创建RequestsCookieJar对象,并使用set方法设置每一个Cookie

    import requests
    r1 = requests.get('http://www.baidu.com')
    print(r1.cookies)
    for key,value in r1.cookies.items():
        print(key,'=',value)
    
    # 获取简书首页内容
    headers = {
        'Host':'www.jianshu.com',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36',
        'Cookie': 'sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2226065565%22%2C%22first_id%22%3A%2217b59029450769-04d60dc1f07d6d-c343365-921600-17b59029451bcc%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%2C%22%24latest_utm_source%22%3A%22desktop%22%2C%22%24latest_utm_medium%22%3A%22timeline%22%7D%2C%22%24device_id%22%3A%2217b59029450769-04d60dc1f07d6d-c343365-921600-17b59029451bcc%22%7D'
    
    }
    
    r2 = requests.get('https://www.jianshu.com',headers=headers)
    print(r2.text)
    

    另外一种设置Cookie的方式

    requests.cookies.RequestsCookieJar()
    jar.set(key,value)

    headers = {
        'Host':'www.jianshu.com',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36',
    }
    cookies = 'sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2226065565%22%2C%22first_id%22%3A%2217b59029450769-04d60dc1f07d6d-c343365-921600-17b59029451bcc%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%2C%22%24latest_utm_source%22%3A%22desktop%22%2C%22%24latest_utm_medium%22%3A%22timeline%22%7D%2C%22%24device_id%22%3A%2217b59029450769-04d60dc1f07d6d-c343365-921600-17b59029451bcc%22%7D'
    jar = requests.cookies.RequestsCookieJar()
    for cookie in cookies.split(';'):
        key, value = cookie.split('=',1)
        jar.set(key,value)
    r3 = requests.get('http://www.jianshu.com',cookies = jar,headers=headers)
    print(r3.text)
    

    八.维持会话(使用同一会话)

    在requests中为我们提供了Session对象,可以在无需用户干预Cookie的情况下维持Session.达到不断向服务端发送同一个ID,客户端就可以在服务端找到对应的Session对象,一些爬虫需要作为同一个客户端来多次抓取页面,也就是说这些抓取动作需要在同一个Session中完成。通过Session对象的get、post等方法可以在同一个Session中向服务端发送请求。


    这里分别使用传统的方法和Session对象向服务端发送请求,并通过url设置Cookie
    可以使用requests.Session()赋值给一个对象,然后改对象再用get请求方式请求url,这样下次请求时就有改cookie字段在返回的响应体中

    import requests
    # 不使用Session
    requests.get('http://httpbin.org/cookies/set/name/Bill')
    r1 = requests.get('http://httpbin.org/cookies')
    print(r1.text)
    
    # 使用Session
    session = requests.Session()
    session.get('http://httpbin.org/cookies/set/name/Bill')
    r2 = session.get('http://httpbin.org/cookies')
    print(r2.text)
    
    

    不使用Session对象,第二次请求无法获得第一次请求的Cookie.反之,可以

    九.SSL证书验证

    nginx搭建HTTPPS服务器,然后通过requests发送请求,并捕捉证书验证(待补;nginx在windows下怎么用,如歌生成自己的签名证书 ssl)

    十.使用代理(该代理失效)

    指定proxies参数,该参数是一个字典类型的值,每一对key-value表示一个代理的协议,如http,https
    本例设置了HTTP和HTTPS代理,并通过代理访问天猫首页,最后输出响应内容

    import requests
    proxies = {
        'http':'http://144.123.68.152:25653',
        'https':'http://144.123.68.152:25653'
    }
    
    r = requests.get('https://www.tmall.com/',proxies=proxies)
    print(r.text)
    

    十一.超时

    import requests,requests.exceptions
    try:
        r = requests.get('https://www.jd.com',timeout = 0.001)
        print(r.text)
    except requests.exceptions.Timeout as e:
        print(e)
    
    # 抛出连接超时异常
    requests.get('https://www.jd.com', timeout=(0.01, 0.001))
    
    # 永久等待,不会抛出超时异常
    requests.get('https://www.jd.com', timeout=None)
    

    十二.身份验证

    requests包进行身份验证只需设置auth即可,auth参数的值是一个HTTPBasicAuth对象,封装了用户名和密码;运行之前编写的AuthServer.py文件,这是一个支持Basic验证的服务器

    import requests
    
    from requests.auth import HTTPBasicAuth
    
    r = requests.get('http://localhost:5000',auth=HTTPBasicAuth('bill','1234'))
    print(r.status_code)
    print(r.text)
    

    十三.将请求打包

    在使用urllib时,可以将请求打包,也就是将所有要发送给服务端的请求信息都放到Request对象中,然后直接发送这个对象即可。requests也可以完成同样工作,在requests中也有一个Request类,用于封装请求信息,然后调用Session的prepare_request方法处理Request对象,并返回一个requests.model.Response对象,最后通过Session.send方法发送Response对象


    本例使用Request对象封装请求,通过Session.send方法发送请求,然后输出响应结果

    from requests import Request,Session
    
    url = 'http://httpbin.org/post'
    
    data = {
        'name':'Bill',
        'age':30
    }
    headers = {
        'country':'China'
    }
    
    session = Session()
    req = Request('post',url,data=data,headers=headers)
    prepared = session.prepare_request(req)
    r = session.send(prepared)
    print(type(r))
    print(r.text)
    
    努力拼搏吧,不要害怕,不要去规划,不要迷茫。但你一定要在路上一直的走下去,尽管可能停滞不前,但也要走。
  • 相关阅读:
    cmd的操作命令导出导入.dmp文件
    转:String数组初始化
    Oracle计算时间差
    WEB-INF目录与META-INF目录的作用
    【神乎其神】这些EXCEL技巧,太神奇了,赶紧收藏!
    报错: The type ByteInputStream is not accessible due to restriction on required library
    ModelAndView对象作用
    shiro使用
    包装类型的比较,如:Integer,Long,Double
    转一个distinct用法,很有帮助
  • 原文地址:https://www.cnblogs.com/wkhzwmr/p/15227851.html
Copyright © 2011-2022 走看看