• 反扒机制代理操作及验证码的识别


    反扒机制:代理操作

    代理操作:

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

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

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

      • 如果我们的爬虫对服务器短时间内发出高频请求。那么服务器检测到这样一个异常请求,就会将该请求的对应设备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:如果前台页面没有的话,我们就可以基于抓包工具进行全局搜索。
  • 相关阅读:
    Java中Properties类的操作
    Java中Properties类的使用
    properties类的基本使用方法
    java.util.ResourceBundle使用详解
    java.util.ResourceBundle 用法小介
    java.util.Date和java.sql.Date的区别和相互转化
    response.setHeader()的用法
    Fiddler (二) Script 用法
    HTTP协议 (七) Cookie
    HTTP协议 (六) 状态码详解
  • 原文地址:https://www.cnblogs.com/zzsy/p/12687652.html
Copyright © 2020-2023  润新知