zzsy

反扒机制:代理操作

代理操作:

  • 在爬虫中,所谓的代理指的是什么?

    • 就是代理服务器
  • 代理服务器的作用:

    • 就是用来转发请求和响应的
  • 在爬虫中为什么需要使用代理服务器:

    • 如果我们的爬虫对服务器短时间内发出高频请求。那么服务器检测到这样一个异常请求,就会将该请求的对应设备IP禁掉,这样就无法给服务器发请求获取数据了!
    • 如果ip被禁,我们就可以使用代理服务器进行请求转发,破解ip被禁的反爬机制。因为使用代理后,服务器端接受到的请求对应的ip地址就是代理服务器而不是我们真正的客户端的。
  • 代理服务器分为不同的匿名度:
    - 透明代理:如果使用了该形式的代理,服务器端知道你使用了代理机制也知道你的真实ip。
    - 匿名代理:知道你使用代理,但是不知道你的真实ip
    - 高匿代理:不知道你使用了代理也不知道你的真实ip
    - 代理的类型
    - https:代理只能转发https协议的请求
    - http:转发http的请求
    - 代理服务器:
    - 快代理
    - 西祠代理
    - goubanjia
    - 代理精灵(推荐):http://http.zhiliandaili.cn/)

    • 封装一个代理池

      from lxml import etree
      #以下这网址就是你用代理。代理给你的
      url = \'http://t.11jsq.com/index.php/api/entry?method=proxyServer.generate_api_url&packid=1&fa=0&fetch_key=&groupid=0&qty=4&time=1&pro=&city=&port=1&format=html&ss=5&css=&dt=1&specialTxt=3&specialJson=&usertype=2\'
      page_text = requests.get(url,headers=headers).text
      tree = etree.HTML(page_text)
      proxy_list = tree.xpath(\'//body//text()\')
      http_proxy = [] #代理池
      for proxy in proxy_list:
          dic = {
              \'http\':proxy
          }
          http_proxy.append(dic)
      http_proxy
      结果;
      [{\'http\': \'58.243.28.218:33503\'},
       {\'http\': \'114.106.151.234:10566\'},
       {\'http\': \'114.252.50.79:11484\'},
       {\'http\': \'106.7.4.131:28803\'}]
      

      对西祠代理发起一个高频的请求,让其将我本机ip禁掉

      url = \'https://www.xicidaili.com/nn/%d\'
      ips = []
      for page in range(1,11):
          new_url = format(url%page)
          page_text = requests.get(url=new_url,headers=headers).text
          tree = etree.HTML(page_text)
          #在xpath表达式中不可以出现tbody标签
          tr_list = tree.xpath(\'//*[@id="ip_list"]//tr\')[1:]
          for tr in tr_list:
              ip = tr.xpath(\'./td[2]/text()\')[0]
              ips.append(ip)
      print(len(ips))
      

      使用代理机制破解ip被封的效果

      #代理池对应的代码
      url = \'http://ip.11jsq.com/index.php/api/entry?method=proxyServer.generate_api_url&packid=1&fa=0&fetch_key=&groupid=0&qty=29&time=1&pro=&city=&port=1&format=html&ss=5&css=&dt=1&specialTxt=3&specialJson=&usertype=2\'
      page_text = requests.get(url,headers=headers).text
      tree = etree.HTML(page_text)
      proxy_list = tree.xpath(\'//body//text()\')
      http_proxy = [] #代理池
      for proxy in proxy_list:
          dic = {
              \'https\':proxy
          }
          http_proxy.append(dic)
      
      #url模板
      url = \'https://www.xicidaili.com/nn/%d\'
      ips = []
      for page in range(1,11):
          new_url = format(url%page)
          #让当次的请求使用代理机制,就可以更换请求的ip地址
          #requests模块有代理参数!!
          page_text = requests.get(url=new_url,headers=headers,proxies=random.choice(http_proxy)).text
          tree = etree.HTML(page_text)
          #在xpath表达式中不可以出现tbody标签
          tr_list = tree.xpath(\'//*[@id="ip_list"]//tr\')[1:]
          for tr in tr_list:
              ip = tr.xpath(\'./td[2]/text()\')[0]
              ips.append(ip)
      print(len(ips))
              
      

验证码的识别

  • 基于线上的打码平台识别验证码

  • 打码平台

    • 1.超级鹰(使用):

      http://www.chaojiying.com/about.html

      • 1.注册【用户中心的身份】
      • 2.登录(用户中心的身份)
        • 1.查询余额,请充值
        • 2.创建一个软件ID(899370)
        • 3.下载示例代码
    • 2.云打码

    • 3.打码兔

    这是超级鹰的示例代码
    import requests
    from hashlib import md5
    
    class Chaojiying_Client(object):
    
        def __init__(self, username, password, soft_id):
            self.username = username
            password =  password.encode(\'utf8\')
            self.password = md5(password).hexdigest()
            self.soft_id = soft_id
            self.base_params = {
                \'user\': self.username,
                \'pass2\': self.password,
                \'softid\': self.soft_id,
            }
            self.headers = {
                \'Connection\': \'Keep-Alive\',
                \'User-Agent\': \'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)\',
            }
    
        def PostPic(self, im, codetype):
            """
            im: 图片字节
            codetype: 题目类型 参考 http://www.chaojiying.com/price.html
            """
            params = {
                \'codetype\': codetype,
            }
            params.update(self.base_params)
            files = {\'userfile\': (\'ccc.jpg\', im)}
            r = requests.post(\'http://upload.chaojiying.net/Upload/Processing.php\', data=params, files=files, headers=self.headers)
            return r.json()
    
        def ReportError(self, im_id):
            """
            im_id:报错题目的图片ID
            """
            params = {
                \'id\': im_id,
            }
            params.update(self.base_params)
            r = requests.post(\'http://upload.chaojiying.net/Upload/ReportError.php\', data=params, headers=self.headers)
            return r.json()
    
    

    然后自己写个函数实例化超级鹰

    def tranformImgCode(imgPath,imgType):
        chaojiying = Chaojiying_Client(\'bobo328410948\', \'bobo328410948\', \'899370\')
        im = open(imgPath, \'rb\').read()
        return chaojiying.PostPic(im,imgType)[\'pic_str\']
    print(tranformImgCode(\'./a.jpg\',1902))
    7261
    

    模拟登录

    • 流程:
      • 对点击登录按钮对应的请求进行发送(post请求)
      • 处理请求参数:
        • 用户名
        • 密码
        • 验证码
        • 其他的防伪参数
    #这里别忘记带上cookie!!!
    session = requests.Session()
    
    #识别验证码
    url = \'https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx\'
    page_text = session.get(url=url,headers=headers).text
    #解析验证码图片的地址
    tree = etree.HTML(page_text)
    img_src = \'https://so.gushiwen.org\'+tree.xpath(\'//*[@id="imgCode"]/@src\')[0]
    #将验证码图片保存到本地
    img_data = session.get(img_src,headers=headers).content
    with open(\'./code.jpg\',\'wb\') as fp:
        fp.write(img_data)
        
    #识别验证码
    code_text = tranformImgCode(\'./code.jpg\',1902)
    print(code_text)
    login_url =\'https://so.gushiwen.org/user/login.aspx?from=http%3a%2f%2fso.gushiwen.org%2fuser%2fcollect.aspx\'
    data = {
        \'__VIEWSTATE\': \'4iQUDYGYp480//d8dSe+k037Ut9ijESlrJJLPgCEsA+C4EAmEQV4h+p/G4sKwsGz2mFdGeIE+TS8T6Gru2w14b4n2qfsxdeB4caV4zXWhLNTbDM9m/heuikk8S4=\',
        \'__VIEWSTATEGENERATOR\': \'C93BE1AE\',
        \'from\': \'http://so.gushiwen.org/user/collect.aspx\',
        \'email\': \'www.zhangbowudi@qq.com\',
        \'pwd\': \'bobo328410948\',
        \'code\': code_text,#动态变化
        \'denglu\': \'登录\',
    }
    #对点击登录按钮发起请求:获取了登录成功后对应的页面源码数据
    page_text_login = session.post(url=login_url,headers=headers,data=data).text
    with open(\'./gushiwen.html\',\'w\',encoding=\'utf-8\') as fp:
        fp.write(page_text_login)
       
    

发现上图参数中有2组乱码参数。

  • 在请求参数中如果看到了一组乱序的请求参数,最好去验证码这组请求参数是否为动态变化。

  • 处理:

    • 方式1:常规来讲一半动态变化的请求参数会被隐藏在前台页面中,那么我们就要去前台页面源码中取找。

- 方式2:如果前台页面没有的话,我们就可以基于抓包工具进行全局搜索。

分类:

技术点:

相关文章:

  • 2021-11-18
  • 2021-08-15
猜你喜欢
  • 2022-01-13
  • 2021-11-06
  • 2021-12-31
  • 2021-11-03
  • 2021-08-22
  • 2022-12-23
  • 2021-09-28
相关资源
相似解决方案