zoukankan      html  css  js  c++  java
  • 爬虫-urllib3模块的使用

    urllib3是一个功能强大,对SAP健全的 HTTP客户端,许多Python生态系统已经使用了urllib3。

    一、安装

    sudo pips install urllib3

    二、创建PoolManager对象

      通过urllib3访问网页,首先需要构造一个PoolManager实例对象用于处理与线程池的连接以及线程安全的所有细节,然后通过request()方法来发送请求

    • 复制代码
      import urllib3
      
      #创建PoolManager对象,用于处理与线程池的连接以及线程安全的所有细节
      http = urllib3.PoolManager()
      
      #对需要爬取的网页发送请求
      resp = http.request(method,url,...)
      复制代码

      method和url两个参数必选,并且method需要大写

    三、基本GET请求(headers参数和fields参数)

    • 最基本的GET请求

      复制代码
      import urllib3
      
      #创建PoolManager对象,用于处理与线程池的连接以及线程安全的所有细节
      http = urllib3.PoolManager()
      
      #对需要爬取的网页发送请求
      resp = http.request('GET','https://www.baidu.com/')
      
      print(resp.data.decode())#响应数据
      print(resp.headers)#响应头信息
      print(resp.status)#状态码
      resp.release_conn()#释放这个http连接
      复制代码
    • 添加headers和查询参数

       可以传入headers参数(dict类型)来增加请求头中的headers信息。可以利用fields参数传递查询参数(dict类型),并且url后面的'?‘一定不能带上

    • 复制代码
      import urllib3
      
      http = urllib3.PoolManager()
      
      kw = {"wd":"长城"}
      headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
      resp = proxy.request('GET','https://www.baidu.com/s',fields=kw,headers = headers)
      print(resp.data.decode())
      复制代码

    四、基本POST请求(fields参数)

    • 最基本的POST请求需要传入fields参数(dict类型),urllib3会自动将其转换成表单数据类型

      复制代码
      import urllib3
      
      http = urllib3.PoolManager()
      
      #需要提交的数据
      data = {'word':'hello'}
      headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
      response = http.request('POST','http://httpbin.org/post',fields = data,headers = headers)
      print(response.data.decode())
      复制代码
    • url中携带查询参数

      • 需要先通过urlencode()编码,然后附加在url后面,这和GET方式有所不同(示例略)
    • 传递json数据(body参数)

      • 利用body参数进行传递,但是数据需要先序列化成json字符串,然后headers中需要设置'Content-Type':'application/json'
    • 复制代码
      import urllib3
      import json
      
      http = urllib3.PoolManager()
      url = 'https://openapi.vmall.com/mcp/offlineshop/getShopList'
      data = {
      "portal":2,"lang":"zh-CN","country":"CN","brand":1,"province":"山西","city":"太原","pageNo":1,"pageSize":20
      }
      
      # 将字典类型数据序列化成json字符串
      json_data = json.dumps(data)
      
      #headers中设置Conten-Type为application/json
      headers = {
          'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',
          'Content-Type':'application/json'
      }
      resp = http.request('POST',url,body = json_data,headers = headers)
      print(resp.data.decode())
      复制代码

      注意:body参数和fields参数不能同时使用

    五、文件上传

    • 普通文件上传

      • 使用multipart/form-data编码方式上传文件,可以使用和传入Form data数据一样的方法进行,并将文件定义为一个二元元组(文件名,数据)或三元元组(文件名,数据,MIME类型),文件名的定义虽然不是严格要求的,但是推荐使用,以使得表现得更像浏览器
        复制代码
        import urllib3
        
        http = urllib3.PoolManager()
        
        #打开文件test.txt
        with open('test.txt','r') as f:
            file_data = f.read()
        
        headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
        
        #三元元组的方式传入
        resp = http.request('POST','http://httpbin.org/post',fields={'filefield':('test.txt',file_data,'text/plain')},headers=headers)
        #二元元组的方式传入
        #resp = http.request('POST','http://httpbin.org/post',fields={'filefield':('test.txt',file_data)},headers=headers)
        print(resp.data.decode('unicode_escape'))
        复制代码
    • 二进制文件上传

      • 原始二进制数据,只要将其定义为body参数即可。同时,建议对header的Content-Type参数进行设置
        复制代码
        import urllib3
        
        http = urllib3.PoolManager()
        
        with open('test.jpg','rb') as f:
            binary_data = f.read()
        headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",'Content-Type':'image/jpeg'}
        resp = http.request('POST','http://httpbin.org/post',body = binary_data,headers = headers)
        print(resp.data.decode())
        复制代码

    六、超时设置

    • 使用timeout,可以控制请求的总超时时间(连接超时和读取超时时间总和),timeout参数为一个浮点数:

      resp = http.request('GET','http://httpbin.org/delay/3',timeout = 4.0)
    • 也可以分别设置总超时、连接超时和读取超时时间,这时候需要使用Timeout()实例,里面有3个关键字参数total,connect和read:

      #设置总超时时间为3.0秒,连接超时不超过1.5秒,读取超时不超过2.0秒
      resp = http.request('GET','http://httpbin.org/delay/3',timeout = urllib3.Timeout(total=3.0,connect=1.5,read=2.0))
    • 如果想让所有的request都遵循一个timeout,可以将timeout参数定义在PoolManager中,当在具体的request中再次定义timeout时,会覆盖PoolManager层面上的timeout。

      http = urllib3.PoolManager(timeout = urllib3.Timeout(total=3.0,connect=1.5,read=2.0))
      
      #http = urllib3.PoolManager(timeout = 4.0)

    七、重试(retries参数)以及重定向(redirect参数)设置

    • urllib3默认进行3次请求重试,3次重定向

    • 通过retries来自定义请求重试次数

      #设置请求重试次数10次
      resp = http.request('GET','http://httpbin.org/ip',retries = 10)
    • 将参数retries设为False,请求重试和重定向会同时关闭

      #同时关闭请求重试和重定向
      resp = http.request('GET','http://httpbin.org/redirect/1',retries = False)
    • 将参数redirect设为False,仅关闭重定向,保持请求重试

      #仅关闭重定向
      resp = http.request('GET','http://httpbin.org/redirect/1',redirect = False)
    • 通过Retry()实例可以精细控制重试和重定向次数,该实例默认总重试次数为10次,比如我们设置3次重试,2次重定向

      resp = http.request('GET','http://httpbin.org/redirect/3',retries = urllib3.Retry(3,redirect = 2))
    • 如果想让所有的request都遵循一个请求重试和重定向策略,可以在PoolManager中定义retries参数,当在具体的request中再次定义retries时,会覆盖 PoolManager层面上的retries。

      http = urllib3.PoolManager(retries = urllib3.Retry(3,redirect=2))
      #http = urllib3.PoolManager(retries = False)

    八、ProxyManager(代理IP)

    • 如果你需要使用代理来访问某个网站的话, 那么你可以使用 ProxyManager 对象来进行设置
    • ProxyManager和PoolManager的方法基本完全相同,这里举个简单的小例子
      复制代码
      import urllib3
      
      #创建ProxyManager对象
      proxy_http = urllib3.ProxyManager('https://175.42.122.96:9999')
      
      headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
      
      #利用代理对需要爬取的网页发送请求
      resp = proxy_http.request('GET','https://www.baidu.com/',headers=headers)
      
      print(resp.data.decode())#响应数据
      print(resp.headers)#响应头信息
      print(resp.status)#状态码
      resp.release_conn()#释放这个http连接
      复制代码

    九、SSL证书验证

    • urllib3默认不验证HTTPS请求,如果想开启验证,最可靠的方法是使用提供Mozilla根证书包的certifi包

      sudo pip3 install certifi
    • 获得证书后,可以在PoolManager中定义cert_reqs参数和ca_certs参数,来自动处理证书验证

      复制代码
      import urllib3
      import certici
      
      #开启ssl证书自动验证
      http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED',ca_certs=certifi.where())
      
      headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
      resp = http.request('GET','https://www.baidu.com/',headers=headers)
      
      print(resp.data.decode())
      复制代码
    • 如果需要,可以使用OS提供的证书。只需指定证书包的完整路径作为ca_certs参数而不是 certifi.where()。例如,大多数Linux系统都存储证书/etc/ssl/certs/ca-certificates.crt。

      import urllib3
      import certifi
      
      http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED',ca_certs='/etc/ssl/certs/ca-certificates.crt')
  • 相关阅读:
    B. Connecting Universities DFS,无向树
    HDU 5808 Price List Strike Back bitset优化的背包。。水过去了
    uva 6910
    HDU 5778 abs 数学
    Invitation Cards POJ 1511 SPFA || dij + heap
    HDU 2243 考研路茫茫——单词情结 求长度小于等于L的通路总数的方法
    cmd链接mysql
    如何设置远程访问mysql
    ERROR 1045 (28000): Access denied for user'root'@'localhost'(using password:YES)51Testing软件测试网-H*?U)}$h }P6H4H
    String ,StringBuffer,StringBuilder的区别(转)
  • 原文地址:https://www.cnblogs.com/wht123/p/14284115.html
Copyright © 2011-2022 走看看