• Python 基于 urllib 使用 Handler 处理器(代理)


    一、简介

    • 为啥要使用 Handler?

      1、urllib.request.urlopen(url) 不能定制请求头。

      2、urllib.request.Request(url, data, headers) 可以定制请求头。

      3、Handler 定制更高级的请求头(随着业务逻辑的复杂,请求对象的定制已经满足不了需求,比如:动态 cookie和代理不能使用请求对象的定制)。

    • 要爬取的各种各样的网页,有一部填写需要验证码,有的需要 cookie,还有更多许多高级的功能,会阻碍你爬,而对于 openurl 单纯点理解就是打开网页。openurl 打开一个网址,它可以是一个字符串或者是一个 request 对象。而 build_opener 就是多了 handler,处理问题更专,更个性化。

    • 简单使用,通过 Handler 去完成 urlopen 打开网页的操作。

      # 使用 urllib
      import urllib.request
      
      # 定义 header
      headers = {
        # UA 最基本的防爬识别
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36'
      }
      
      # 1、定义一个 https 的 url
      url = 'https://www.baidu.com'
      
      # 2、定义一个 Request 对象,urlopen 方法并不能直接带 header。
      # 细节:为什么这里需要写 url=url 而有的地方不需要?因为 Request 构造方法传参顺序问题 Request(url, data=None, headers={} ...)
      request = urllib.request.Request(url=url, headers=headers)
      
      # 3、获取 Handler 对象
      handler = urllib.request.HTTPHandler()
      
      # 4、获取 opener 对象
      opener = urllib.request.build_opener(handler)
      
      # 5、调用 open 方法
      response = opener.open(request)
      
      # 6、获取内容字符串
      content = response.read().decode('utf-8')
      
      # 7 输出
      print(content)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30

    二、IP代理

    • 使用同一个 IP 去不断地访问爬取数据,容易被对方服务器封 IP,这个时候就需要使用代理,简单点说,就是使用 N 个别人的 IP 去访问爬取数据。

    • 代理配置步骤:(参考上面 简单使用 案例步骤)

      1、创建 Request 对象

      2、创建 ProxyHandler 对象

      3、用 handler 对象创建 opener 对象

      4、使用 opener.open 函数发送请求

    • 使用案例

      # 使用 urllib
      import urllib.request
      # 使用 random
      import random
      
      # 定义 header
      headers = {
        # UA 最基本的防爬识别
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36'
      }
      
      # 方式一:字典形式的IP代理(https://www.kuaidaili.com/free/)
      # proxies = { 'http': '112.14.47.6:52024' }
      
      # 方式二:定义一个代理池,然后随机从代理池中获取一个代理
      proxies_pool = [
        { 'http':'112.14.47.6:52024' },
        { 'http':'61.164.39.68:53281' }
      ]
      proxies = random.choice(proxies_pool)
      
      # 输出当前代理
      print(proxies)
      
      # 1、定义一个 https 的 url
      url = 'https://www.baidu.com/s?wd=ip'
      
      # 2、定义一个 Request 对象,urlopen 方法并不能直接带 header。
      # 细节:为什么这里需要写 url=url 而有的地方不需要?因为 Request 构造方法传参顺序问题 Request(url, data=None, headers={} ...)
      request = urllib.request.Request(url=url, headers=headers)
      
      # 3、获取 Handler 对象
      handler = urllib.request.ProxyHandler(proxies=proxies)
      
      # 4、获取 opener 对象
      opener = urllib.request.build_opener(handler)
      
      # 5、调用 open 方法
      response = opener.open(request)
      
      # 6、获取内容字符串
      content = response.read().decode('utf-8')
      
      # 7 保存,可以方便校验IP是否代理成狗
      with open('ip.html', 'w', encoding='utf-8') as f:
        f.write(content)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
  • 相关阅读:
    微信小程序登录
    操作系统提示这样该怎么处理
    操作系统【OS】线程的分类
    IDEA修改jvm的内存大小!
    第十三届蓝桥杯大赛湖南中医药大学第1场选拔赛总结
    Part2_扩展MATSIM_Subpart10_分析_第37章 基于Matsim的交互式分析与决策支持
    PostGreSQL:时间戳时区问题
    中职网络安全竞赛之应用服务漏洞扫描与利用
    智源发布线虫生命模型,超级人脑有望在未来15-30年实现
    小白学go基础04-命名惯例对标识符进行命名
  • 原文地址:https://blog.csdn.net/zz00008888/article/details/127851911