zoukankan      html  css  js  c++  java
  • requests:

    1、保存图片:

    import requests
    url = "http://dmimg.5054399.com/allimg/pkm/pk/22.jpg"
    response = requests.get(url = url)
    查看状态码:
    print(response.status_code)
    查看文本数据:
    print(response.text)
    查看字节:
    print(response.content)
    with open("豆芽.jpg","wb") as f:
    """wb字节转图片"""
    f.write(response.content)
    2、
    import requests
    response = requests.get(url="https://www.cnblogs.com/Neeo/articles/10669652.html%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95%E5%87%BA%E7%8E%B0%E5%8E%9F%E5%9B%A0")
    print(response.text)
    查看网页编码:
    print(response.encoding)
    转码:
    response.encoding = "utf-8"
    查看URL:
    print(response.url)
    查看响应头:
    print(response.headers)
    with open("a.html","w",encoding="utf-8") as f:
    """w清空写文本"""
    f.write(response.text)
    查看json数据并get获取参数:
    response = requests.get(url="http://neeo.cc:6001/get?k1=v1&k2=v2")
    print(response.json())
    获取cookie数据:
    print(response.cookies)
    url = "http://dmimg.5054399.com/allimg/pkm/pk/22.jpg"
    response = requests.get(url=url)
    生成器获取数据并保存图片指定大小下载:
    with open("22.jpg","wb") as f:
    for i in response.iter_content(chunk_size=128):
    f.write(i)
    请求类型:
    print(response.request)
    返回请求记录
    print(response.history)
    构造一个方法并获取json数据:
    response = requests.request(method="get",url="http://neeo.cc:6001/get")
    print(response.json())
    获取参数:
    d = {
    "k1":"v1"
    }
    r = requests.request(method="get",url="http://neeo.cc:6001/get",params = d)
    print(r.json())
    参数为json的接口
    j = {"userName":"test","password":"1234","gender":1,"phoneNum":"110","email":"beihe@163.com","address":"Beijing"}
    r = requests.request(method="post",url="http://neeo.cc:6002/pinter/com/register",json = j)
    print(r.json())
    结果:{'code': '0', 'message': '注册成功', 'data': None}
    data:
    d = {
    "userName":"admin",
    "password":"1234",
    }
    r = requests.request(method="post",url="http://neeo.cc:6002/pinter/com/login",data = d)
    print(r.json())
    结果:{'code': '0', 'message': 'success', 'data': None}

    3、

    get、put、post底层代码:

    # -*- coding: utf-8 -*-

    """
    requests.api
    ~~~~~~~~~~~~

    This module implements the Requests API.

    :copyright: (c) 2012 by Kenneth Reitz.
    :license: Apache2, see LICENSE for more details.
    """

    from . import sessions


    def request(method, url, **kwargs):
    """Constructs and sends a :class:`Request <Request>`.

    :param method: method for the new :class:`Request` object.
    :param url: URL for the new :class:`Request` object.
    :param params: (optional) Dictionary, list of tuples or bytes to send
    in the query string for the :class:`Request`.
    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
    object to send in the body of the :class:`Request`.
    :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
    :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
    :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
    :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
    ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
    or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string
    defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
    to add for the file.
    :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
    :param timeout: (optional) How many seconds to wait for the server to send data
    before giving up, as a float, or a :ref:`(connect timeout, read
    timeout) <timeouts>` tuple.
    :type timeout: float or tuple
    :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.
    :type allow_redirects: bool
    :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
    :param verify: (optional) Either a boolean, in which case it controls whether we verify
    the server's TLS certificate, or a string, in which case it must be a path
    to a CA bundle to use. Defaults to ``True``.
    :param stream: (optional) if ``False``, the response content will be immediately downloaded.
    :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
    :return: :class:`Response <Response>` object
    :rtype: requests.Response

    Usage::

    >>> import requests
    >>> req = requests.request('GET', 'https://httpbin.org/get')
    <Response [200]>
    """

    # By using the 'with' statement we are sure the session is closed, thus we
    # avoid leaving sockets open which can trigger a ResourceWarning in some
    # cases, and look like a memory leak in others.
    with sessions.Session() as session:
    return session.request(method=method, url=url, **kwargs)


    def get(url, params=None, **kwargs):
    r"""Sends a GET request.

    :param url: URL for the new :class:`Request` object.
    :param params: (optional) Dictionary, list of tuples or bytes to send
    in the query string for the :class:`Request`.
    :param **kwargs: Optional arguments that ``request`` takes.
    :return: :class:`Response <Response>` object
    :rtype: requests.Response
    """

    kwargs.setdefault('allow_redirects', True)
    return request('get', url, params=params, **kwargs)


    def options(url, **kwargs):
    r"""Sends an OPTIONS request.

    :param url: URL for the new :class:`Request` object.
    :param **kwargs: Optional arguments that ``request`` takes.
    :return: :class:`Response <Response>` object
    :rtype: requests.Response
    """

    kwargs.setdefault('allow_redirects', True)
    return request('options', url, **kwargs)


    def head(url, **kwargs):
    r"""Sends a HEAD request.

    :param url: URL for the new :class:`Request` object.
    :param **kwargs: Optional arguments that ``request`` takes.
    :return: :class:`Response <Response>` object
    :rtype: requests.Response
    """

    kwargs.setdefault('allow_redirects', False)
    return request('head', url, **kwargs)


    def post(url, data=None, json=None, **kwargs):
    r"""Sends a POST request.

    :param url: URL for the new :class:`Request` object.
    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
    object to send in the body of the :class:`Request`.
    :param json: (optional) json data to send in the body of the :class:`Request`.
    :param **kwargs: Optional arguments that ``request`` takes.
    :return: :class:`Response <Response>` object
    :rtype: requests.Response
    """

    return request('post', url, data=data, json=json, **kwargs)


    def put(url, data=None, **kwargs):
    r"""Sends a PUT request.

    :param url: URL for the new :class:`Request` object.
    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
    object to send in the body of the :class:`Request`.
    :param json: (optional) json data to send in the body of the :class:`Request`.
    :param **kwargs: Optional arguments that ``request`` takes.
    :return: :class:`Response <Response>` object
    :rtype: requests.Response
    """

    return request('put', url, data=data, **kwargs)


    def patch(url, data=None, **kwargs):
    r"""Sends a PATCH request.

    :param url: URL for the new :class:`Request` object.
    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
    object to send in the body of the :class:`Request`.
    :param json: (optional) json data to send in the body of the :class:`Request`.
    :param **kwargs: Optional arguments that ``request`` takes.
    :return: :class:`Response <Response>` object
    :rtype: requests.Response
    """

    return request('patch', url, data=data, **kwargs)


    def delete(url, **kwargs):
    r"""Sends a DELETE request.

    :param url: URL for the new :class:`Request` object.
    :param **kwargs: Optional arguments that ``request`` takes.
    :return: :class:`Response <Response>` object
    :rtype: requests.Response
    """

    return request('delete', url, **kwargs)
    4、
    requests库是Python语言编写,基于urllib,采用Apache2 Licensed开源协议的HTTP库。
    它相对于urllib更加方便,大大节约了代码量,完全满足了HTTP测试相关需求。

    urllib是Python内置的HTTP请求库。urllib 模块提供的上层接口,使访问 www 和 ftp 上的数据就像访问本地文件一样,并且它也是requests的底层库。

    其中包括4个主要模块:

    • urllib.request:请求模块。
    • urllib.error:异常处理模块。
    • urllib.parse:URL解析模块。
    • urllib.robotparser:robots.txt解析模块。

    在Python2.x中,分为urllib和urllib2,简单来说,urllib2是urllib的增强版,但urllib中的函数又比urllib2多一些,对于简单的下载之类的,urllib绰绰有余,如果涉及到实现HTTP身份验证或者cookie或者扩展编写自定义协议,urllib2更好一些。

    • urllib支持设置编码的函数urllib.urlencode,在模拟登陆的时候经常需要传递经过post编码之后的参数,如果不想使用第三方库完成模拟登录,就必须使用到标准库中的urllib。urllib提供一些比较原始基础的方法而urllib2并没有,比如urllib中的urlencode方法用来GET查询字符串的产生。

    • urllib2比较有优势的地方在于urllib2.openurl中可以接受一个Request类的实例来设置Request参数,来修改/设置Header头从而达到控制HTTP Request的header部分的目的,也可以修改用户代理,设置cookie等,但urllib仅可以接受URL。这就意味着,如果你访问一个网站想更改User Agent(可以伪装你的浏览器),你就需要使用urllib2。
    • urllib2模块没有加入urllib.urlretrieve函数以及urllib.quote等一系列quote和unquote功能,这个时候就需要urllib的辅助。

    因此,在Python2.x中,这两个库可以搭配使用。
    而urllib3则是增加了连接池等功能,两者互相都有补充的部分。
    那么Python3.x中呢,urllib和urllib2都合并到了urllib中了,所以,啥也别想了,Python3.x即将一统江湖,所以,我们还是踏实儿的学习Python3.x下的urllib吧。

    再来看看Python2.x和Python3.x的区别。
    在Python2.x中,urlopen方法在urllib下:

    import urllib2 response = urllib2.urlopen()

    在Python3.x中,urlopen方法就移动到了urllib.request下:

    import urllib.request response = urllib.request.urlopen()

    import urllib
    response = urllib.request.urlopen('http://www.baidu.com')
    # 获取bytes类型的数据
    # print(response.read())
    # 想要获取到字符串类型的数据,需要使用 decode 转码为字符串
    print(response.read().decode('utf-8'))

    发送post请求

    import urllib.request
    import urllib.parse
    data = bytes(urllib.parse.urlencode({'world': 'hello'}), encoding='utf-8')
    response = urllib.request.urlopen(url='http://httpbin.org/post', data=data)
    print(response.read().decode('utf-8'))

    首先,需要了解一个http://httpbin.org这个网站,HTTPBin是以Python+Flask写的一款工具,它包含了各类的HTTP场景,且每个接口一定都有返回。

    data参数需要字节类型的数据,所以,我们首先用bytes转码,然后将我们的字典使用urllib.parse.urlencode并指定编码方式完成编码。

    另外,data参数用来控制请求方式,如果请求中有data则是post请求,否则为get请求。

    timeout

    import socket
    import urllib.request
    import urllib.error
    try:
        # 没有超时,正常返回json格式的内容
        # response = urllib.request.urlopen(url='http://www.httpbin.org/get', timeout=2)
        # 超时会抛出异常,由异常语句捕获
        response = urllib.request.urlopen(url='http://www.httpbin.org/get', timeout=0.1)
        print(response.read().decode('utf-8'))
    except urllib.error.URLError as e:
        # print(e)  # <urlopen error timed out>
        if isinstance(e.reason, socket.timeout):
            print(e.reason)  # timed out

    e.reason为错误原因。timeout单位是秒。

    响应

     

    现在来研究urlopen返回对象提供的方法:

    • read(),readline(),readlines(),fileno(), close():这些方法与文件对象一样。
    • info():返回一个httplibHTTPMessage对象,表示远程服务器返回的头信息。
    • getcode():返回HTTP状态码。
    • geturl():返回请求的url。

    响应类型

    import urllib.request
    response = urllib.request.urlopen(url='http://www.httpbin.org/get')
    print(response)  # <http.client.HTTPResponse object at 0x07B65270>
    print(type(response))  # <class 'http.client.HTTPResponse'>

    状态码

    import urllib.request
    response = urllib.request.urlopen(url='http://www.httpbin.org/get')
    print(response.status)  # 200

    响应头

    import urllib.request
    response = urllib.request.urlopen(url='http://www.httpbin.org/get')
    print(response.headers)  
    print(response.getheaders())  # 列表类型的响应头
    print(response.getheader('Server', None))  # 获取特定的响应头

    响应体

    import urllib.request
    response = urllib.request.urlopen(url='http://www.httpbin.org')
    # print(response.read())
    print(response.read().decode('utf-8'))

    之前说过,urllib获取到的内容是字节形式,我们通过read读出来之后需要使用decode解码。

    request对象

     

    上面我们发送一些简单的请求没问题,但是复杂的请求(比如带headers)就力有不逮了。这个时候,我们需要学习一个Request来定制复杂的请求参数了。

    import urllib.request
    request = urllib.request.Request(url='http://www.httpbin.org')
    response = urllib.request.urlopen(request)
    print(response.read().decode('utf-8'))

    首先,我们使用urllib.request.Request来构建一个request对象,然后传给urlopen即可。

    再来看一个复杂点的带headers。

    import urllib.request
    import urllib.parse
    # 指定url
    url='http://www.httpbin.org/post'
    # 自定义headers
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"}
    # 自定义data参数并编码为bytes类型
    data_dict = {"username": "zhangkai"}
    data = bytes(urllib.parse.urlencode(data_dict), encoding='utf-8')
    # 使用urllib.request.Request构造request对象
    request = urllib.request.Request(url=url, data=data, headers=headers, method='POST')
    # 将request对象交给urlopen发请求去吧
    response = urllib.request.urlopen(request)
    print(response.read().decode('utf-8'))

    再来看一个add_headers方法。

    import urllib.request
    import urllib.parse
    
    url='http://www.httpbin.org/post'
    # 这里跟上面的示例区别就是不在单独指定headers字典
    # headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"}
    data_dict = {"username": "zhangkai"}
    data = bytes(urllib.parse.urlencode(data_dict), encoding='utf-8')
    request = urllib.request.Request(url=url, data=data, method='POST')
    # 而是使用构造好的request对象下面的add_header方法添加header,换汤不换药....
    request.add_header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36")
    response = urllib.request.urlopen(request)
    print(response.read().decode('utf-8'))

    add_header方法作为添加headers的补充方式,如果有多个header键值对,可以使用for循环一一添加进去.....

    会了构造request对象,我们基本能应付大部分的网站了。

    再来看看更复杂的一些用法,以应对更多的复杂环境,比如携带cookie什么的。

    Cookie

     

    获取cookie

    import urllib.request
    import http.cookiejar
    
    # 声明 cookiejar 对象
    cookie = http.cookiejar.CookieJar()
    # 使用handler处理cookie对象
    handler = urllib.request.HTTPCookieProcessor(cookie)
    opener = urllib.request.build_opener(handler)
    # 当opener.open发送请求
    response = opener.open('http://www.baidu.com')
    # 当response有了结果之后,会自动将cookie信息保存到上面声明的cookie对象中去
    print(cookie)

    http.cookiejar提供一个永久性的cookie对象。并且cookiejar有3个子类:

    • CookieJar:管理HTTP cookie值、存储HTTP请求生成的cookie、向传出的HTTP请求添加cookie的对象。整个cookie都存储在内存中,对CookieJar实例进行垃圾回收后cookie也将丢失。
    • FileCookieJar (filename,delayload=None,policy=None):从CookieJar派生而来,用来创建FileCookieJar实例,检索cookie信息并将cookie存储到文件中。filename是存储cookie的文件名。delayload为True时支持延迟访问访问文件,即只有在需要时才读取文件或在文件中存储数据。
    • MozillaCookieJar (filename,delayload=None,policy=None):从FileCookieJar派生而来,创建与Mozilla浏览器 cookies.txt兼容的FileCookieJar实例。
    • LWPCookieJar (filename,delayload=None,policy=None):从FileCookieJar派生而来,创建与libwww-perl标准的 Set-Cookie3 文件格式兼容的FileCookieJar实例。

    大多数情况下,我们只用CookieJar(),如果需要和本地文件交互,就用 MozillaCookjar() 或 LWPCookieJar()

    补充:libwww-perl集合是一组Perl模块,它为万维网提供简单而一致的应用程序编程接口。该库的主要重点是提供允许您编写WWW客户端的类和函数。

    将cookie写入文件

    我们知道cookie是保持登录会话信息的凭证,那么在获取到cookie后写入本地,在cookie失效前,后续访问再读取本地文件,并在请求中携带,以达到继续保持登录信息的状态。

    import urllib.request
    import http.cookiejar
    
    '''
    写入cookie对象到本地
    '''
    url = 'http://www.baidu.com'
    file_name = 'cookie.txt'
    # 这里将cookie信息处理成火狐浏览器cookie格式
    cookie = http.cookiejar.MozillaCookieJar(file_name)
    # LWPCookieJar格式cookie
    # cookie = http.cookiejar.LWPCookieJar(file_name)
    # 使用handler处理cookie对象
    handler = urllib.request.HTTPCookieProcessor(cookie1)
    opener = urllib.request.build_opener(handler)
    response1 = opener.open(url)
    # 将cookie信息保存到本地文件
    cookie1.save(ignore_discard=True, ignore_expires=True)
    
    '''
    读取本地cookie信息
    '''
    # 以什么格式保存,就以什么格式读出来,这里都用MozillaCookieJar
    cookie2 = http.cookiejar.MozillaCookieJar()
    # 使用load方法从本地读取cookie信息
    cookie2.load(file_name, ignore_discard=True, ignore_expires=True)
    # 放到handle中
    handler = urllib.request.HTTPCookieProcessor(cookie2)
    opener = urllib.request.build_opener(handler)
    response2 = opener.open(url)
    print(response2.read().decode('utf-8'))

    saveload中,有两个参数需要说明:

    • ignore_discard:保存cookie,即使设置为丢弃的cookie也保存。
    • ignore_expires:如果cookie已过期也要保存到文件,并且如果文件存在则覆盖。后续可以使用load或者revert方法恢复保存的文件。

    代理

     
    import urllib.request
    # 调用ProxyHandler 代理ip的形式是字典
    # 付费代理
    # money_proxy = {"协议":"username:pwd@ip:port"}
    proxy_handler = urllib.request.ProxyHandler({'sock5': 'localhost:1080'})
    # 使用build_opener构建opener对象
    opener = urllib.request.build_opener(proxy_handler)
    # 调用opener的open方法向指定url发请求
    response = opener.open('http://www.httpbin.org/get')
    print(response.read().decode('utf-8'))
    '''
    {
      "args": {}, 
      "headers": {
        "Accept-Encoding": "identity", 
        "Host": "www.httpbin.org", 
        "User-Agent": "Python-urllib/3.6"
      }, 
      "origin": "124.64.16.181, 124.64.16.181", 
      "url": "https://www.httpbin.org/get"
    }
    '''

    {'sock5': 'localhost:1080'}sock5是协议,localhost:1080是走本地的1080端口。

    其实urlopen在内部也是调用了opener.open方法发送请求。

    另外,返回结果origin是访问IP,而这个IP正好是我们使用的代理IP。

    下载

     

    我们可以使用urllib下载图片,文件等到本地。

    import urllib.request
    url = 'http://n.sinaimg.cn/news/1_img/upload/cf3881ab/69/w1000h669/20190912/bed4-iepyyhh6925213.jpg' 
    filename = 'a.jpg'
    # 使用urlretrieve进行下载操作
    urllib.request.urlretrieve(url=url, filename=filename)

    除此之外,我们还可以使用urllib.urlcleanup()来清除urllib.urlretrieve所产生的缓存。

    urllib.error

     

    urllib中的异常处理有3个:

    • urllib.error.URLError:捕获关于url的错误,只有一个返回方法reason,错误原因。
    • urllib.error.HTTPError:捕获关于http的错误,有3个返回方法。code,http中定义的http状态码;reason,错误原因;headers,响应头。
    • urllib.error.ContentTooShortError:当urlretrieve检测到下载数据量小于预期时,会引发此异常。

    urllib.error.URLError

    import urllib.request
    import urllib.error
    
    try:
        # 这里将 cnblogs 写成 cnblogsww
        # response = urllib.request.urlopen(url='https://www.cnblogsww.com/Neeo/p/1083589221.html')
        print(response.read().decode('utf-8'))
    except urllib.error.ContentTooShortError as e:
        print('ContentTooShortError: ', e.reason)

    urllib.error.HTTPError

    import urllib.request
    import urllib.error
    
    try:
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"}
        # 不存在的 103048922222.html
        response = urllib.request.urlopen(url='https://www.cnblogs.com/Neeo/p/103048922222.html')
        print(response.read())
    except urllib.error.HTTPError as e:
        print('HTTPError: ', e.reason, e.headers, e.code)

    urllib.error.ContentTooShortError

    这个错误比较重要,因为我们在下载文件时,很可能会因为各种原因导致下载没有完成就失败了。这个时候,我们就可以使用ContentTooShortError来捕捉错误从新下载。如果重新下载还是下载失败,可以考虑使用递归,下载失败就重新下,直到下载成功。

    import urllib.request
    import urllib.error
    
    try:
        url = 'http://n.sinaimg.cn/news/1_img/upload/cf3881ab/69/w1000h669/20190912/bed4-iepyyhh6925213.jpg'
        filename = 'a.jpg'
        urllib.request.urlretrieve(url=url, filename=filename)
    except urllib.error.ContentTooShortError as e:
        print('ContentTooShortError: ', e.reason)
        # 如果下载失败,就重新下载
        urllib.request.urlretrieve(url=url, filename=filename)
        
        
    def get_file(url, filename):
        """ 使用递归进行重新下载,直到下载成功为止 """
        try:
            urllib.request.urlretrieve(url=url, filename=filename)
            print('download done ......')
        except urllib.error.ContentTooShortError:
            get_file(url, filename)
    url = "http://n.sinaimg.cn/news/1_img/upload/cf3881ab/69/w1000h669/20190912/bed4-iepyyhh6925213.jpg"
    filename = 'a.jpg'
    get_file(url, filename)

    urllib.parse

     

    urllib.parse定义了URL的标准接口,实现对于URL的各种操作,包括解析、合并、编码、解码,使用之前需导入。

    urllib.parse.urlparse

    urllib.parse.urlparse以元组的形式返回URL解析后的6个组件。对应的URL结构一般是这样的:

    scheme://netloc/path;parameters?query#fragment

    每个元组项都是一个字符串,也可能是空的。

    返回的元组中:

    • scheme:协议。
    • netloc:域名。
    • path:路径。
    • params:参数。
    • query:查询条件,一般用于个get请求的URL。
    • fragment:锚点。

    基本使用:

    import urllib.parse
    urllib.parse.urlparse(url, scheme='', allow_fragments=True)
    • url:待解析的url
    • scheme:协议,如果URL中没有协议,则使用该参数设置协议,如果有协议,该参数不生效
    • allow_fragments:是否忽略锚点,默认为True,表示表示不忽略,False表示忽略

    示例:

    import urllib.parse
    
    result = urllib.parse.urlparse('https://www.cnblogs.com/Neeo/p/10864123.html?k1=v1#python')
    print(result)
    
    '''
    ParseResult(scheme='https', netloc='www.cnblogs.com', path='/Neeo/p/10864123.html', params='', query='k1=v1', fragment='python')
    '''

    urllib.parse.urlunparse

    urlparse相反,urllib.parse.urlunparse用来构造URL。

    import urllib.parse
    
    url_components = ['https', 'www.cnblogs.com', '/Neeo/p/10864123.html', '', '', 'python']
    result = urllib.parse.urlunparse(url_components)
    print(result)  # https://www.cnblogs.com/Neeo/p/10864123.html#python

    url_components中,顺序必须遵循:

    scheme, netloc, url, params, query, fragment

    也就是6个选项都要有值,如果没有也要填充空字符串占位。

    urllib.parse.urljoin

    urllib.parse.urljoin用来拼接URL。

    import urllib.parse
    # 将两个url拼接成一个完整的url,base_url + sub_url
    print(urllib.parse.urljoin('https://www.cnbogs.com', '/Neeo/p/10864123.html'))
    # 如果每个参数中都有相应的参数的话,比如都有协议,那么将以后面的为准
    print(urllib.parse.urljoin('https://www.cnbogs.com', 'http://www.baidu.com/Neeo/p/10864123.html'))

    注意,urljoin方法只能接受两个url参数:

    urljoin(base, url, allow_fragments=True)

    别意淫它能跟os.path.join一样可劲儿的往后拼!

    urllib.parse.urlencode

    urllib.parse.urlencode将字典类型的参数序列化为url编码后的字符串,常用来构造get/post请求的参数k1=v1&k2=v2

    import urllib.parse
    
    params = {"k1": "v1", "k2": "v2"}
    encode_params = urllib.parse.urlencode(params)
    print('https://www.baidu.com?' + encode_params)  # https://www.baidu.com?k1=v1&k2=v2
    # 这里用urljoin不好使, 它在处理base url时会将 ? 干掉
    print(urllib.parse.urljoin('https://www.baidu.com', encode_params))  # https://www.baidu.com/k1=v1&k2=v2
    # 或者你继续使用拼接....好蛋疼
    print(urllib.parse.urljoin('https://www.baidu.com', '?' + encode_params))  # https://www.baidu.com?k1=v1&k2=v2

    urllib.parse.quote系列

    按照标准,URL只允许一部分ASCII字符(数字字母和部分符号),其他的字符如汉字是不符合URL标准的。所以在使用URL的时候,要进行URL编码。

    urllib提供了urllib.parse.quoteurllib.parse.quote_plus进行URL编码。

    urllib.parse.quote_plusurllib.parse.quote更近一步,会对/符号进行编码。

    urllib.parse.unquoteurllib.parse.unquote_plus则是将编码后的URL进行还原。

    import urllib.parse
    
    url = 'https://www.baidu.com/s?&wd=张开'
    
    result = urllib.parse.quote(url)
    print(result)  # https%3A//www.baidu.com/s%3F%26wd%3D%E5%BC%A0%E5%BC%80
    result_plus = urllib.parse.quote_plus(url)
    print(result_plus)  # https%3A%2F%2Fwww.baidu.com%2Fs%3F%26wd%3D%E5%BC%A0%E5%BC%80
    
    un_result = urllib.parse.unquote(result)
    print(un_result)  # https://www.baidu.com/s?&wd=张开
    
    un_result_plus = urllib.parse.unquote_plus(result_plus)
    print(un_result_plus)  # https://www.baidu.com/s?&wd=张开

    urllib.robotparser

     

    我们可以利用urllib.robotparser对爬取网站的Robots协议进行分析。

    那问题来了,什么是Robots协议?

    Robots协议

     

    Robots协议(也称为爬虫协议、机器人协议等)的全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。robots.txt文件是一个文本文件,放在站点的根目录下。

    当一个搜索蜘蛛访问一个站点时,它会首先检查该站点根目录下是否存在robots.txt,如果存在,搜索机器人就会按照该文件中的内容来确定访问的范围;如果该文件不存在,所有的搜索蜘蛛将能够访问网站上所有没有被口令保护的页面。

    禁止所有爬虫访问任何内容

    User-Agent:  *
    Disallow:  /

    允许所有爬虫访问任何内容

    User-Agent:  *
    Disallow: 

    允许某些爬虫访问某些目录

    User-agent:  Baiduspider
    Allow:  /article
    Allow:  /oshtml
    Disallow:  /product/
    Disallow:  /
    
    User-Agent:  Googlebot
    Allow:  /article
    Allow:  /oshtml
    Allow:  /product
    Allow:  /spu
    Allow:  /dianpu
    Allow:  /oversea
    Allow:  /list
    Disallow:  /
    
    User-Agent:  *
    Disallow:  /

    关于爬虫名称

    爬虫名称所属公司网址
    Baiduspider 百度 www.baidu.com
    Googlebot 谷歌 www.google.com
    Bingbot 微软必应 cn.bing.com
    360Spider 360搜索 www.so.com
    Yisouspider 神马搜索 http://m.sm.cn/
    Sogouspider 搜狗搜索 https://www.sogou.com/
    Yahoo! Slurp 雅虎 https://www.yahoo.com/

    RobotFileParser

     

    robotpaser模块提供RobotFileParser类来解析robots.txt文件,判断是否允许爬取网站的某一目录。

    在实例化类时传入robots.txt。

    import urllib.robotparser
    response = urllib.robotparser.RobotFileParser(url='https://www.zhihu.com/robots.txt')
    response.read()

    或者通过实例化对象调用set_url方法传入robots.txt。

    import urllib.robotparser
    
    response = urllib.robotparser.RobotFileParser()
    response.set_url('https://www.zhihu.com/robots.txt')
    response.read()

    whatever,都需要使用response.read()读出来,不然后面解析不到。

    常用方法:

    • set_url(url):用来设置 robots.txt 文件链接,如果在初次实例化 RobotFileParser 类的时候传入了 url 参数,那么就不需要再次调用此方法设置了。
    • read():读取 robots.txt 文件并将读取结果交给 parse() 解析器进行解析。
    • parse(lines):用来解析 robots.txt 文件内容,分析传入的某些行的协议内容。
    • can_fetch(useragent, url):需要两个参数,User-Agent、所要抓取的 URL 链接,返回此搜索引擎是否允许抓取此 URL,返回结果为 True、False。
    • mtime():返回上次抓取分析 robots.txt 文件的时间,这对于需要对 robots.txt 进行定期检查更新的长时间运行的网络爬虫非常有用 。
    • modified():同样的对于长时间分析和抓取的搜索爬虫很有帮助,将当前时间设置为上次抓取和分析 robots.txt 的时间。
    • crawl_delay(useragent):返回抓取延迟时间的值,从相应的 User-Agent 的 robots.txt 返回 Crawl-delay 参数的值。 如果没有这样的参数,或者它不适用于指定的 User-Agent,或者此参数的 robots.txt 条目语法无效,则返回 None。
    • request_rate(useragent):从robots.txt返回Request-rate参数的内容,作为命名元组RequestRate(requests,seconds)。 如果没有这样的参数,或者它不适用于指定的useragent,或者此参数的robots.txt条目语法无效,则返回None。(Python3.6新增方法)

    示例:

    import urllib.robotparser
    
    response = urllib.robotparser.RobotFileParser(url='https://www.zhihu.com/robots.txt')
    # 要有读操作
    response.read()
    # 判断某一个网址是否能爬取
    print(response.can_fetch('Googlebot', 'https://www.zhihu.com/question/268464407/answer/804631692'))  # True
    print(response.can_fetch('*', 'https://www.zhihu.com/question/268464407/answer/804631692'))  # False
    
    # 返回上一次抓取分析 robots.txt 的时间
    print(response.mtime())  # 1568542822.1876643
    
    # 将当前时间设置为上次抓取和分析 robots.txt 的时间
    response.modified()
    
    # 返回 robots.txt 文件对请求频率的限制
    print(response.request_rate('MSNBot').requests)  # 1
    print(response.request_rate('*'))  # None
    
    # 返回 robots.txt 文件对抓取延迟限制
    print(response.crawl_delay('*'))  # None
    print(response.crawl_delay('MSNBot'))  # 10

    使用parser方法读取和分析robots.txt。

    import urllib.robotparser
    import urllib.request
    
    # 实例化 RobotFileParser 对象
    response = urllib.robotparser.RobotFileParser()
    # 使用parser读取 robots.txt 文件
    result = urllib.request.urlopen('https://www.zhihu.com/robots.txt').read().decode('utf-8').split('
    ')
    response.parse(result)
    
    # 判断url是否可爬取
    print(response.can_fetch('Googlebot', 'https://www.zhihu.com/question/268464407/answer/804631692'))  # True
    print(response.can_fetch('*', 'https://www.zhihu.com/question/268464407/answer/804631692'))  # False

     

    requests库的主要方法

    方法描述
    requests.request() 构造一个请求,支持以下各种方法
    requests.get() 获取html的主要方法
    requests.head() 获取html头部信息的主要方法
    requests.post() 向html网页提交post请求的方法
    requests.put() 向html网页提交put请求的方法
    requests.patch() 向html提交局部修改的请求
    requests.delete() 向html提交删除请求
    requests.Session() session相关

    requests.request(method, url, **kwargs)类能够构造一个请求,支持不同的请求方式。

    import requests
    
    response = requests.request(method='get', url='https://www.baidu.com')
    print(response.status_code)

    request类中来看看几个参数:

    • method:请求方式。
    • url:请求URL。
    • **kwargs:
      • params:字典或者字节序列,作为参数增加到url中,使用这个参数可以把一些键值对以k1=v1&k2=v2的模式增加到url中,get请求中用的较多。
      • data:字典、字节序列或者文件对象,重点作为向服务器提供或提交资源,作为请求的请求体,与params不同放在url上不同。它也可以接受一个字符串对象。
      • json:json格式的数据,可以向服务器提交json类型的数据。
      • headers:字典,定义请求的请求头,比如可以headers字典定义user agent。
      • cookies:字典或者CookieJar。
      • auth:元组,用来支持HTTP认证功能。
      • files:字典,用来向服务器传输文件。
      • timeout:指定超时时间。
      • proxies:字典,设置代理服务器。
      • allow_redirects:开关,是否允许对URL进行重定向,默认为True。
      • stream:开关,是否对获取内容进行立即下载,默认为False,也就是立即下载。这里需要说明的,stream一般应用于流式请求,比如说下载大文件,不可能一次请求就把整个文件都下载了,不现实,这种情况下,就要设置stream=True,requests无法将连接释放回连接池,除非下载完了所有数据,或者调用了response.close。
      • verify:开关,用于SSL证书认证,默认为True。
      • cert:用于设置保存本地SSL证书路径。

    流式请求,指的不是请求是流,而是请求返回的数据流,返回一点取一点,而普通的请求是返回完毕你再取内容。

    响应对象支持的属性

     
    import requests
    
    response = requests.request(method='get', url='http://www.httpbin.org/get')

    当一个请求被发送后,会有一个response响应。requests同样为这个response赋予了相关方法:

    • response:响应对象。
    • response.status_code:请求返回状态码。
    • response.text:字符串形式的响应内容。
    • response.json():返回响应的是json类型的数据,如果响应的类型不是json,则抛出ValueError
    • response.content:二进制的响应内容。
    • response.iter_content(chunk_size):生成器,在stream=True的情况下,当遍历生成器时,以块的形式返回,也就是一块一块的遍历要下载的内容。避免了遇到大文件一次性的将内容读取到内存中的弊端,如果stream=False,全部数据作为一个块返回。chunk_size参数指定块大小。
    • response.iter_lines():生成器,当stream=True时,迭代响应数据,每次一行,也就是一行一行的遍历要下载的内容。同样避免了大文件一次性写入到内存中的问题。当然,该方法不安全。至于为啥不安全,咱也不知道,咱也不敢问,主要是官网上没说!经查,如果多次调用该方法,iter_lines不保证重新进入时的安全性,因此可能会导致部分收到的数据丢失。
    • response.cookies:响应中的cookie信息。
    • response.cookies.get_dict():以字典的形式返回cookies信息。
    • response.cookies.items():以列表的形式返回cookies信息。
    • response.headers:响应头字典。取其中的指定key,response.headers.get('Content-Type', '哎呀,没取到!')
    • response.reqeust:请求类型。
    • response.url:请求的URL。
    • response.reason:响应HTTP状态的文本原因。
    • response.encoding:响应结果的编码方式。
    • response.encoding = “gbk”:修该响应编码方式,比如说响应结果的编码是utf-8,通过这么response.encoding = “gbk”指定为gbk。
    • response.apparent_encoding:根据响应字节流中去chardet库中匹配,返回编码方式,并不保证100%准确。
    • response.history:以列表的形式返回请求记录。列表内的请求以最老到最新排序。

    see also:HTTP协议状态码 | chardet

    requests.get()

     

    requests.get(url, params=None, **kwargs)发送GET请求。相关参数:

    • url,请求的URL。
    • params参数: 可选url中的额外参数,字典或者字节流格式。
    • **kwargs:参见requests.request中的kwargs。

    params参数

     

    get请求难免会带一些额外的参数K1=V1&K2=V2

    我们可以手动的拼接:

    import requests
    
    response = requests.get(url='http://www.httpbin.org/get?k1=v1&k2=v2')
    print(response.url)  # http://www.httpbin.org/get?k1=v1&k2=v2
    print(response.json().get('args'))  # {'k1': 'v1', 'k2': 'v2'}

    虽然没问题,但是稍显麻烦。

    现在,我们可以使用params参数来解决这个问题。

    import requests
    
    params = {"user": "张开", "pwd": "666"}
    response = requests.get(url='http://www.httpbin.org/get', params=params)
    print(response.url)  # http://www.httpbin.org/get?user=%E5%BC%A0%E5%BC%80&pwd=666
    print(response.json().get('args'))  # {'pwd': '666', 'user': '张开'}

    headers

     

    再来看,GET请求中如何携带headers。

    import requests
    headers = {"user-agent": UserAgent().random}
    response = requests.get(url='http://www.httpbin.org/get', headers=headers)
    print(response.json()['headers']['User-Agent'])  # Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5

    关于 fake_useragent:https://www.cnblogs.com/Neeo/articles/11525001.html

    cookies

     

    来看,GET请求中如何携带cookies。

    import requests
    from fake_useragent import UserAgent
    cookies = {
        "user": "zhangkai",
        "pwd": "666"
    }
    response = requests.get(url='http://www.httpbin.org/cookies', cookies=cookies)
    print(response.json())  # {'cookies': {'pwd': '666', 'user': 'zhangkai'}}

    因为url的返回值是json形式cookies也在里面,所以我们要去json中取,而不是从response.cookies取。

    再来看响应中的cookies:

    import requests
    
    url = 'http://www.baidu.com'
    response = requests.get(url=url)
    print(response.cookies)  # <RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
    print(response.cookies.get_dict())  # {'BDORZ': '27315'}
    print(response.cookies.items())  # [('BDORZ', '27315')]

    你可以将response.cookies返回的是字典,它支持字典有关的方法。

    文件下载

     

    如果你访问的是一个小文件,或者图片之类的,我们可以直接写入到本地就完了,也就是不用管stream,让它默认为False即可。

    来个美女图片提提神!

    import requests
    import webbrowser
    
    url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1568638318957&di=1d7f37e7caece1c39af05b624f42f0a7&imgtype=0&src=http%3A%2F%2Fimg3.duitang.com%2Fuploads%2Fitem%2F201501%2F17%2F20150117224236_vYFmL.jpeg'
    
    response = requests.get(url=url)
    f = open('a.jpeg', 'wb')
    f.write(response.content)
    f.close()
    webbrowser.open('a.jpeg')

    过瘾不?

    那要是下载大文件,可就不能这么干了:

    import requests
    import webbrowser
    
    
    url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1568638318957&di=1d7f37e7caece1c39af05b624f42f0a7&imgtype=0&src=http%3A%2F%2Fimg3.duitang.com%2Fuploads%2Fitem%2F201501%2F17%2F20150117224236_vYFmL.jpeg'
    
    response = requests.get(url=url, stream=True)
    with open('a.jpeg', 'wb') as f:
        for chunk in response.iter_content(chunk_size=256):
            f.write(chunk)
    webbrowser.open('a.jpeg')

    使用response.iter_content(chunk_size=256)一块一块下载,并且可以指定chunk_size大小。

    当然,也可以使用response.iter_lines一行一行遍历下载,但是官网说不安全,所以,忘掉它吧。

    requests.post()

     

    requests.post(url, data=None, json=None, **kwargs)发送POST请求,相关参数:

    • url:请求的URL。
    • data:可选参数,请求中携带表单编码的字典、bytes或者文件对象。
    • json:请求中携带json类型的数据。
    • **kwargs:参见requests.request中的kwargs。

    在post请求中,data与json既可以是str类型,也可以是dict类型。

    区别:

    1、不管json是str还是dict,如果不指定headers中的content-type,默认为application/json

    2、data为dict时,如果不指定content-type,默认为application/x-www-form-urlencoded,相当于普通form表单提交的形式

    3、data为str时,如果不指定content-type,默认为application/json

    4、用data参数提交数据时,request.body的内容则为a=1&b=2的这种形式,用json参数提交数据时,request.body的内容则为'{"a": 1, "b": 2}'的这种形式

    实际应用时候,需要根据后端服务处理的方式来确定

    data参数

     
    import requests
    
    url = 'http://www.httpbin.org/post'
    # data为字典
    data_dict = {"k1": "v1"}
    response = requests.post(url=url, data=data_dict)
    print(response.json())
    
    # data为字符串
    data_str = "abc"
    response = requests.post(url=url, data=data_str)
    print(response.json(), type(response.json()['data']))
    
    # data为文件对象
    
    file = open('a.jpg', 'rb')
    response = requests.post(url=url, data=file)
    print(response.json())

    上述的基于data参数上传文件,不如使用专门的files参数来的合适。

    文件上传

     

    基于POST请求的文件上传,使用files参数。

    import requests
    file = {"file": open('a.jpg', 'rb')}
    response = requests.post('http://www.httpbin.org/post', files=file)
    print(response.json())

    json参数

     
    import requests
    
    url = 'http://www.httpbin.org/post'
    response = requests.post(url=url, json={"user": "zhangkai"})
    print(response.json())

    requests.head()

     

    requests.head(url, **kwargs)发送HEAD请求,相关参数:

    • url:请求URL。
    • **kwargs:参见requests.request中的kwargs。
    import requests
    
    url = 'http://httpbin.org/get'
    response = requests.head(url=url)
    print(response.headers)
    '''
    {
        'Access-Control-Allow-Credentials': 'true', 
        'Access-Control-Allow-Origin': '*', 
        'Content-Encoding': 'gzip', 
        'Content-Type': 'application/json', 
        'Date': 'Mon, 16 Sep 2019 10:58:07 GMT', 
        'Referrer-Policy': 'no-referrer-when-downgrade', 
        'Server': 'nginx', 
        'X-Content-Type-Options': 'nosniff', 
        'X-Frame-Options': 'DENY', 
        'X-XSS-Protection': '1; mode=block', 
        'Connection': 'keep-alive'
    }
    '''

    使用requests.head(url, **kwargs)的优点就是以较少的流量获得响应头信息,也可以用在分页中。

    requests.put()

     

    requests.put(url, data=None, **kwargs)发送PUT请求,相关参数:

    • url:请求URL。
    • data:可选参数,请求中携带表单编码的字典、bytes或者文件对象。
    • **kwargs:参见requests.request中的kwargs。
    import requests
    
    url = 'http://www.httpbin.org/put'
    data_dict = {"k1": "v1"}
    response = requests.put(url=url, data=data_dict)
    print(response.json())
    '''
    {
        'args': {}, 
        'data': '', 
        'files': {}, 
        'form': {'k1': 'v1'}, 
        'headers': {
            'Accept': '*/*', 
            'Accept-Encoding': 'gzip, deflate', 
            'Content-Length': '5', 
            'Content-Type': 'application/x-www-form-urlencoded', 
            'Host': 'www.httpbin.org', 
            'User-Agent': 'python-requests/2.19.1'
        }, 
        'json': None, 
        'origin': '1.202.184.14, 1.202.184.14', 
        'url': 'https://www.httpbin.org/put'
    }
    '''

    requests.patch()

     

    requests.patch(url, data=None, **kwargs)发送PATCH请求,相关参数:

    • url:请求URL。
    • data:可选参数,请求中携带表单编码的字典、bytes或者文件对象。
    • **kwargs:参见requests.request中的kwargs。
    import requests
    
    url = 'http://www.httpbin.org/patch'
    data_dict = {"k1": "v1"}
    response = requests.patch(url=url, data=data_dict)
    print(response.json())
    '''
    {   
        'args': {}, 
        'data': '', 
        'files': {}, 
        'form': {'k1': 'v1'}, 
        'headers': {
            'Accept': '*/*', 
            'Accept-Encoding': 'gzip, deflate', 
            'Content-Length': '5', 
            'Content-Type': 'application/x-www-form-urlencoded', 
            'Host': 'www.httpbin.org', 
            'User-Agent': 'python-requests/2.19.1'
        }, 
        'json': None, 
        'origin': '1.202.184.14, 1.202.184.14', 
        'url': 'https://www.httpbin.org/patch'
    }
    '''

    在requests中,PATCH请求和PUT类似。而区别:

    • PATCH是对PUT方法的补充,用来对已知资源进行局部更新。
    • PATCH相比PUT更加节省带宽。

    requests.delete()

     

    requests.head(url, **kwargs)发送DELETE请求,相关参数:

    • url:请求URL。
    • **kwargs:参见requests.request中的kwargs。
    import requests
    
    test_url = 'https://api.github.com'
    
    def get_url(url):
        return '/'.join([test_url,url])
    
    email = '24xxxxx48@qq.com'
    
    def delete_email():
        r = requests.delete(get_url('user/emails'),json = email ,auth=('username','password'))
        print(r.status_code)
        print(r.text)
        print(r.request.headers)
    
    delete_email()

    将email,用户名,密码,换成自己的GitHub的。

    requests.Session()

     

    requests.Session()可以用来帮我们保持会话。

    import requests
    session = requests.Session()
    
    session.get('http://www.httpbin.org/cookies/set/username/root')
    response = session.get('http://www.httpbin.org/cookies')
    print(response.json())  # {'cookies': {'username': 'root'}}

    证书验证

     

    在之前,这个知识点还能拿12306网站举例的时候.....

    如果你请求的https协议的网址,那么人家网站首先会检测你的证书是否是合法的,如果不合法,会抛出SSLError。怎么处理呢。

    证书验证这里,有两种方式处理。第一种就是使用verify,是否进行证书校验,默认是True。我们选择不校验。

    import requests
    
    response = requests.get(url='https://www.12306.cn', verify=False)
    print(response.status_code)

    但有的时候,会有一个Warnning警告,建议你加证书验证。

    我们可以选择忽略这个警告:

    import requests
    from requests.packages import urllib3
    urllib3.disable_warnings()
    response = requests.get(url='https://www.12306.cn', verify=False)
    print(response.status_code)

    也可以选择提供一个CA证书:

    import requests
    
    response = requests.get(url='https://www.12306.cn', cert=('/path/server.crt', 'path/key'))
    print(response.status_code)

    很明显,我们没有什么CA证书,这就看个热闹吧。

    代理设置

     

    代理:就是你访问一个网站,其实并不是你直接访问的,而是你发请求给A机器,A机器取请求B机器。B返回给A,A再返回给你。代理就是中间人的意思。为什么需要代理?因为:反爬虫网站一般使用IP来识别一个机器。老是一个IP在不停访问网站,该网站就会把这个IP拉入黑名单,不允许访问。这时,就需要很多IP再扰乱反爬虫工具的思维,避免封IP。

    普通代理

    import requests
    
    proxies = {
        "http": "http://10.10.1.10:3128",
        "https": "https://10.10.1.10:1080",
    }
    
    response = requests.get(url='https://www.12306.cn', proxies=proxies)
    print(response.status_code)

    代理需要用户名和密码

    import requests
    
    proxies = {
        "http": "http://user:password@10.10.1.10:3128",
    }
    response = requests.get(url='https://www.12306.cn', proxies=proxies)
    print(response.status_code)

    支持sock代理

    想要支持sock代理,那么首先要下载:

    pip install requests[socks]

    完事在用:

    import requests
    proxies = {
        'http': 'socks5://user:pass@host:port',
        'https': 'socks5://user:pass@host:port'
    }
    respone=requests.get('https://www.12306.cn',proxies=proxies)
    print(respone.status_code)

    超时

     

    超时,在规定的时间无响应。

    import requests
    respone=requests.get('https://www.12306.cn', timeout=0.0001)

    认证设置

     

    有些网站,会弹出一个提示框,要求你输入用户名和密码。

    import requests
    from requests.auth import HTTPBasicAuth
    
    response = requests.get(url='https://www.12306.cn', auth=HTTPBasicAuth(username='user', password='123'))
    print(response.status_code)

    HTTPBasicAuth的简写形式:

    import requests
    
    response = requests.get(url='https://www.12306.cn', auth=('user', '123'))
    print(response.status_code)

    异常处理

     

    异常处理相关异常类主要在requests.exceptions下,可以根据需求去翻看源码。

    import requests
    from requests.exceptions import ReadTimeout, ConnectionError, RequestException
    
    try:
        # RequestException
        # response = requests.get(url='https://www.12306.com')
    
        # ReadTimeout
        # response = requests.get(url='https://www.12306.cn', timeout=0.01)
    
        # ConnectionError ,断网演示...
        response = requests.get(url='https://xueqiu.com/stock/f10/finmainindex.json')
        # print(response.status_code)
    except ReadTimeout as e:
        print('ReadTimeout:', e)
    except ConnectionError as e:
        print('ConnectionError:', e)
    except RequestException as e:
        print('RequestException:', e)
  • 相关阅读:
    (判断是否为弱联通分量) poj 2762
    (最大生成树) poj 1979
    (暴力) bzoj 2208
    (BFS) bzoj 1102
    (并查集) bzoj 1161
    (数学) bzoj 1800
    (博弈) bzoj 2460
    (dinic) poj 3469
    (双端队列优化的SPFA) bzoj 2100
    (判断负环) bzoj 2019
  • 原文地址:https://www.cnblogs.com/zhang-da/p/12203843.html
Copyright © 2011-2022 走看看