zoukankan      html  css  js  c++  java
  • python网络爬虫之二requests模块

    requests http请求库
    requests是基于python内置的urllib3来编写的,它比urllib更加方便,特别是在添加headers,
    post请求,以及cookies的设置上,处理代理请求,用几句话就可以实现,而urllib比较繁琐,
    requests比urllib方便多了,requests是一个简单易用的http请求库。
    
    官方网站是:
    简单实例:
    import requests 
    response = requests.get("https://www.baidu.com/")
    print(type(response))
    print(response.status_code)
    print(type(response.text))
    print(response.text)
    print(response.cookies)
    
    这样我们就很方便的把请求的cookies获取出来了。
    
    各种请求方式:
    import requests
    requests.get("http://httpbin.org/get")
    requests.post("http://httpbin.org/post")
    requests.put("http://httpbin.org/put")
    requests.delete("http://httpbin.org/delete")
    requests.head("http://httpbin.org/get")
    requests.options("http://httpbin.org/get")
    
    
    一.基本的GET请求
    1. 基本的http get请求:
    import requests
    response = requests.get("http://httpbin.org/get")
    print(response.text)
    我们可以通过response.text获取请求内容。
    
    2. 带参数的get请求
    import requests
    response = requests.get("http://httpbin.org/get?name=germey&age=22")
    print(response.text)
    带参数请求:我们只需在链接地址后面加问好?然后后面带参数的名和值,参数和参数
    之间用与&隔开。
    另外requests函数也提供了一个params参数,可以代表用户向浏览器的请求,这样我们
    就可以使用json字典的形式传递参数:
    如:
    格式如下:
    response = requests.get(url,params=data)
    
    import requests
    data = {
        "name":"germey",
        "age":22
    }
    response = requests.get("http://httpbin.org/get",params=data)
    print(response.text)
    
    3. 解析成json格式数据,这样方式在ajax请求的时候非常常用。
    import requests
    import json
    response = requests.get("http://httpbin.org/get")
    print(type(response))            #是一个class返回对象<class 'requests.models.Response'>
    print(type(response.text))       #是一个字符串文本对象<class 'str'>
    print(response.text)             #是一个字符串文本
    print(type(response.json()))     #是一个json字典对象<class 'dict'>
    print(response.json())           #是一个json字典文本,数据与下面相同
    print(json.loads(response.text)) #是一个json字典文本,数据与上面相同
    #而json.loads实际上是对返回的字符串对象进行一个json序列化操作,
    #实际上json.loads(response.text)=response.json()
    
    
    4. 获取二进制数据
    是指下载文本数据,图片,视频时的下载对象,此时需要将文本,图片,视频等数据转换
    成二进制数据,然后再将文本,图片,视频等数据保存到文件,此时我们就可以得到我们
    想要的文本,图片和视频等数据了。
    import requests
    response = requests.get("https://avatars1.githubusercontent.com/u/29205487?s=40&v=4")
    print(type(response.text))           #是一个字符串文本对象<class 'str'>
    print(type(response.content))        #是一个bytes字节码对象<class 'bytes'>
    print(response.text)                 #是一个string格式的乱码字符串
    print(response.content)              #是一个字节码的bytes字节流
    
    #下载文本,图片,或者视频的方法:
    import requests
    response = requests.get("https://avatars1.githubusercontent.com/u/29205487?s=40&v=4")
    with open("1.jpg","wb") as f:
        f.write(response.content)
    f.close()
    #经过上面的验证,此时我们就可以根据以上方法获取文件,图片,或视频的的文件。此时我们需要
    #将文件,图片,或视频链接地址传进去,然后将获取的文件,图片,或视频一字节流的形式写入到
    #文件,此时我们打开文件,就可以获取到我们想要的文本,图片,或视频的的文件
    
    #通过以上我们可以得出结论,如果获取字符串或者是二进制字节流信息,我们字节可以调用text或者
    #content方法,但是如果我们想要获取json格式的字典数据,后面还得加一个括号,因为json不是原生
    #自动转过来的,而是可以看成根据text文件二次转过来的。
    
    
    5. 添加headers
    添加headers是非常重要的,有时候我们在使用爬虫获取数据的时候,如果不添加headers,服务可能会
    直接把我们禁掉,或者是服务器出出现请求或者回复错误等响应,我们以爬取知乎网站为例,如果我们
    不添加headers,那么服务器会返回一个500状态码等一个这样的错误,如:
    import requests
    response = requests.get("https://www.zhihu.com/")
    print(response.text)
    此时会提示500错误。
    
    添加浏览器的headers,其实就是伪装成一个浏览器。
    import requests
    headers = {
              'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
    }
    response = requests.get("https://www.zhihu.com/",headers=headers)
    print(response.text)
    
    关于headers内部的参数,我们可以从一个浏览器里面提取,在浏览器里面的请求参数中的:
    user-agent字段,即代表了我们请求服务器所用的浏览器客户端信息,此时我们将他复制下来,
    添加到headers字典中即可。
    
    二.POST请求
    
    1.基本的post请求:
    post是将数据以form表单的形式传给服务器,此时我们需要以一个data数据字典的形式作为数据传递过去,
    例如:
    import requests
    data = {"name":"germey","age":"22"}
    response = requests.post("http://httpbin.org/post",data=data)
    print(response.text)
    
    
    2. post请求添加headers:
    import requests
    data = {"name":"germey","age":"22"}
    headers = {
              'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
    }
    response = requests.post("http://httpbin.org/post",data=data,headers=headers)
    print(response.text)
    print(response.json())
    
    三.返回的response属性:
    import requests
    response = requests.get("http://www.baidu.com/")
    print(type(response.status_code),response.status_code)            
    print(type(response.headers),response.headers)       
    print(type(response.cookies),response.cookies)             
    print(type(response.url),response.url)     
    print(type(response.history),response.history)
    
    response回复带有很多属性,常用的属性有:
    1. 状态码: response.status_code   int类型
    2. headers:response.headers       字典类型
    3. cookies: response.cookies       cookies类型
    4. url:     response.url           这个url就是我们请求的url          
    5. history: response.history       list元组类型,我们访问的历史记录
    
    1. 状态码的判断,我们的浏览器都有一个状态码的分组,我们可以给根据这个状态码来进行一些
    判断:
    常见的有:
    #请求成功的状态码:
    100  状态码的名字
    200  状态码的名字是ok
    #redirect error:
    300
    #client error:
    400
    #server error:
    500
    另外每一个状态码都有一个自己的名字,我们也可以调用这个状态码的名字来进行判断,而不用记住
    特定的状态码了,例如200的状态码是ok,此时我们就可以通过以下两种方式来验证判断。
    第一种方式,通过状态码来进行验证:
    即验证:if response.status_code == 状态码
    import requests
    response = requests.get("http://www.baidu.com/")
    exit() if not response.status_code == 200 else print("Request Successfully")
    此时打印:
    Request Successfully
    第一种方式,通过状态码的名字来进行验证:
    即验证:if response.status_code == requests.codes.状态码的名字(即请求状态码的名字)。
    import requests
    response = requests.get("http://www.baidu.com/")
    exit() if not response.status_code == requests.codes.ok else print("Request Successfully")
    此时打印:if response.status_code == 状态码
    Request Successfully
    
    四.requests的其他的一些高级操作
    
    1.文件上传
    import requests
    files = {'file':open("1.jpg","rb")}   #在这指定上传后的文件名,我们也可以指定其他名字。
    response = requests.post("http://httpbin.org/post",files=files)
    print(response.text)
    
    2.获取cookies
    我们可以直接通过response.cookies这个属性,就可把cookies获取打印出来了,这个cookies实际上
    是一个列表的形式,因此可以表示成这种形式:response.cookies.items(),这样我们就可以通过
    for循环的形式把这些cookies打印出来,他们都是一个个key-value结构形式的数据。
    import requests
    response = requests.get("https://www.baidu.com/")
    print(response.cookies)
    for key,value in response.cookies.items():
        print(key + 'n' + value)
    
    3.会话维持
    cookies是做会话维持的,有了这个cookies,我们就可以模拟一个用户一直维持在一个登陆状态,相当于
    一个用户在一个浏览器里面一直维持登陆状态的操作。
    import requests 
    requests.get("http://httpbin.org/cookies/set/number/123456789")  #先为这个网站设置一个cookies
    response = requests.get("http://httpbin.org/cookies")            #然后我们就可以把当前的这个网站的cookies拿到
    print(response.text)
    此时我们打印:
    {
      "cookies": {}
    }
    #通过上面可以看到,我们获取的cookies是0,没有,其实根本原因也就是上面我们发起的两次请求
    #分别是两个独立的过程,我们可以理解为,我们用一个浏览器设置了一个cookies,然后再用另外一个
    #浏览器访问,也就是这个两个请求是独立的,此时我们需要模拟在一个浏览器里面操作,模拟一个set
    #和get cookies的操作,此时就得用到如下方法。
    
    requests提供了一个Session的对象,我们可以通过声明一个Session的对象,然后再用这个Session对象
    发起两次get请求,那么这两次请求就相当于在一个浏览器里面操作了。
    import requests 
    s = requests.Session()
    s.get("http://httpbin.org/cookies/set/number/123456789")
    response = s.get("http://httpbin.org/cookies")
    print(response.text)
    此时打印:
    {
      "cookies": {
        "number": "123456789"
      }
    }
    #这个方法非常常用,假如我们再做模拟登录验证的时候,可以创建这么一个session对象,
    #然后用这个session post一下用户名和密码,这样我们就相当于登录了,然后我们再用这个
    #session对象进行操作,此时我们就会维持这么一个登录信息,我们就相当于再登录状态下操作
    #了,此时我们就可以获取一些登录后的页面了,假如我们再做模拟登录的话,我么可以使用
    #requests.Session这个对象来操作。
    
    4.证书验证
    现在的很多网站都是以https格式的网站了,假如入我们查看12306的网站,此时会提示一个ssl证书错误,
    因为我们的爬虫程序没有ssl证书,因此在爬取数据或者与网站交互的时候会提示ssl错误。
    此时,我们假如使用requests模块请求一个https网站的时候,可以使用两种方法来处理:
    第一种方式:如果网站使用了不合法的证书,比如网站自己自己创建了以个证书,此时我们可以使用一个
    参数verify=False来忽略这个证书,如果是合法的证书的话,也可以使用verif=False这个参数来忽略这个
    证书,但是后面也会提示
    例如:直接请求12306网站:
    import requests
    response = requests.get("https://www.12306.cn/")
    print(response.status_code)
    此时会提示ssl证书错误。
    
    我们加一个参数verify=False访问,
    import requests
    response = requests.get("https://www.12306.cn/",verify=False)
    print(response.status_code)
    此时就可以正常访问操作了。
    但是此时会打印信息如下:
    C:Program Files (x86)Pythonlibsite-packagesurllib3connectionpool.py:858: 
    InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification 
    is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
    InsecureRequestWarning)
    200
    
    从上面信息我们可以看到,虽然我们将证书验证设置为False之后,但是在输出结果还是会提示一个警告warnings
    的信息,提示最好加一个证书,此时我们通过requests模块导入一个叫做urllib3的原生的包,然后通过调用这个
    urllib3的一个disable_warning方法来消除这些警告信息,如from requests import urllib3,经过测试,我们也
    可以直接导入这个urllib3的包。
    如下所示:
    import requests
    import urllib3
    urllib3.disable_warnings()
    response = requests.get("https://www.12306.cn/",verify=False)
    print(response.status_code)
    
    
    第二种方式.我们可以手动使用cert参数指定一个证书的验证,此时需要添加一个cert参数,此时我们的请求就会
    自动的通过这个CA证书进行验证了,如下所示:
    import requests
    response = requests.get("https://www.12306.con/",cert=("/path/server.crt","/path/key"))
    print(response.status_code)
    
    5.代理设置
    第一种方式:http代理
    我们只需设置一个proxies代理的字典,然后将这个代理传过去既可以了。
    import requests
    proxies = {
       "http":"http://127.0.0.1:10010",
       "https":"https://127.0.0.1:10011",
    }
    response = requests.get("https://www.taobao.com/",proxies=proxies)
    print(response.status_code)
    此时我们就可以使用我们的代理来访问网站了。
    假如我们的代理需要用户名和密码,此时我们可以在代理前面添加一个用户名和密码,然后加一个
    '@'符,此时我们就可以访问了,如下所示:
    import requests
    proxies = {
       "http":"http://user:password@127.0.0.1:10010",
    }
    response = requests.get("https://www.taobao.com/",proxies=proxies)
    print(response.status_code)
    
    第二种方式:使用socks代理:
    此时我们需要安装一个requests[socks]模块
    pip install requests[socks]
    import requests
    proxies = {
       "http":"socks5://127.0.0.1:10010",
       "https":"socks5://127.0.0.1:10011",
    }
    response = requests.get("https://www.taobao.com/",proxies=proxies)
    print(response.status_code)
    此时我们就可以通过socks代理来进行访问了。
    
    6.超时的设置:
    超时的设置,实际上就是设置一个timeout,假如我们在请求一个网站时,限制一个超时时间的设置,
    此时我们可以设置一个timeout的参数。
    如下:
    import requests
    response = requests.get("https://www.taobao.com/",timeout=1)
    print(response.status_code)
    此时能正常访问。
    如果我们设置个一个较短的时间,比如0.001秒,那么他就会抛出一个
    import requests
    response = requests.get("https://www.taobao.com/",timeout=0.001)
    print(response.status_code)
    此时就会出现浏览器访问超时错误,提示抛出一个如下的ReadTimeout的异常:
    #requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='www.taobao.com', port=443): 
    #Read timed out. (read timeout=0.01)     
    import requests
    from requests.exceptions import ReadTimeout
    try:
         response = requests.get("https://www.taobao.com/",timeout=0.01)
         print(response.status_code)
    except ReadTimeout:
         print("timeout")
    此时就会输出一个:
    #timeout
    
    7.认证设置
    有的网站访问的时候需要输入一个用户名和密码才能登录访问,登录以后我们才能看到网站页面里
    的内容,假如我们遇到这样一个需要登录验证的网站,requests模块提供了一个auth参数,我们就
    可以通过这个auth传入一个HTTPBasicAuth参数把用户名和密码传过来,这样的话我们就可以正常
    登录进去完成一个正常的请求。
    假如我们不传入用户名和密码,直接请求:
    import requests
    response = requests.get("http://www.11111.com")
    print(response.status_code)
    此时就会返回请求被禁止的401状态码:
    输入如下:
    #401
    此时我们可以使用auth将我们的用户名和密码传过去:
    第一种方法,直接传入一个字典:
    import requests
    response = requests.get("http://www.11111.com",auth=('username','password'))
    print(response.status_code)
    
    第二种方法,通过HTTPBasicAuth传入一个字典,这两种方式都可以。
    import requests
    from requests.auth import HTTPBasicAuth
    response = requests.get("http://www.11111.com",auth=HTTPBasicAuth('username','password'))
    print(response.status_code)
    
    此时就可以正常访问了。
    
    8.关于异常处理的部分
    import requests 
    from requests.exceptions import ReadTimeout,HTTPError,ConnectionError,
  • 相关阅读:
    .NET程序运行原理及基本概念详解
    c# 操作Redis的五种基本类型总结
    手写MQ框架(一)-准备启程
    手写MVC框架(二)-代码实现和使用示例
    手写DAO框架(七)-如何保证连接可用
    spring cloud入门
    maven学习整理
    mybatis入门学习
    spring事务使用探究
    微内核OS学习
  • 原文地址:https://www.cnblogs.com/fengjunhua/p/8818075.html
Copyright © 2011-2022 走看看