ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

从零实现一个高性能网络爬虫(二)应对反爬虫之前端数据混淆

2022-10-08 14:44:51  阅读:230  来源: 互联网

标签:


摘要

目的

  • 之前写项目的时候,需要用到免费的http代理,然后找到了这个 这个网站。现在需要把这个网站上的ip和port爬取下来,有兴趣的朋友也可以尝试自己爬取一下。

开始

  • 打开这个网站首页,然后控制台查看ip和port的对应标签。 如上图(图一),从控制台的标签中可以看出ip加了一些无关不显示的标签来混淆数据,这里混淆的原理其实很简单,通过标签的style=”display:none”属性来达到混淆的目的,也就是包含这个属性的标签是不会显示在页面上的。知道了这一点就比较好处理了,只需要在解析的时候把包含style=”display:none”属性的标签去掉。就可以轻松的拿到ip和port数据了。 代码如下
  • ip地址能够准确的拿到了,却发现port被做了混淆,而且每次返回的port还在动态改变。大家可以通过把浏览器的JavaScrip脚本关闭后,然后刷新这个网页。会发现每次的port都不一样。我们每次看到的正确port都是通过JavaScript脚本处理后的。如果采用普通爬虫的方式拿到的port都是错误的。现在要想拿到正确的port,可以通过分析它JavaScrip脚本还原数据的逻辑。 同样打开控制台->选择Sources->选择一行js代码打断点(点击行编号),如下图 刷新网页—>页面Paused in debugger—>选择Elements->右键td节点->Break on…->subtree modifications。这两个步骤就是在设置断点调试,也就是在td节点发生改变的时候paused。 选择Sources->F8(继续执行),这个时候又会有一次pause,也就是js脚本在还原正确port的时候(如下图) 函数的调用栈有好多层,如何快速定位哪一个函数的技巧就是,看它局部变量表的变量变化,因为这里是port在发生改变,然后找到对应变量和对应逻辑函数。简单分析可以确定到port发生改变的函数是一个匿名函数,如下图 格式化后,代码如下:
var _$ = [x2ex70x6fx72x74, "x65x61x63x68", "x68x74x6dx6c", "x69x6ex64x65x78x4fx66", x2a, "x61x74x74x72", x63x6cx61x73x73, "x73x70x6cx69x74", "x20", "", "x6cx65x6ex67x74x68", "x70x75x73x68", x41x42x43x44x45x46x47x48x49x5a, "x70x61x72x73x65x49x6ex74", "x6ax6fx69x6e", ];
$(function() {
          
   
    $(_$[0])[_$[1]](function() {
           
    
        var a = $(this)[_$[2]]();
        if (a[_$[3]](_$[4]) != -0x1) {
           
    
            return
        }
        ;var b = $(this)[_$[5]](_$[6]);
        try {
          
   
            b = (b[_$[7]](_$[8]))[0x1];
            var c = b[_$[7]](_$[9]);
            var d = c[_$[10]];
            var f = [];
            for (var g = 0x0; g < d; g++) {
           
    
                f[_$[11]](_$[12][_$[3]](c[g]))
            }
            ;$(this)[_$[2]](window[_$[13]](f[_$[14]](_$[15])) >> 0x3)
        } catch (e) {
           
    }
    })
})
  • 还原后如下:
var _$ = [.port, "each", "html", "indexOf", *, "attr", class, "split", " ", "", "length", "push", ABCDEFGHIZ, "parseInt", "join", ];
$(function() {
          
   
    $(.port).each(function() {
          
   
        var a = $(this).html();
        if (a.indexOf(*) != -0x1) {
            return
        }
        ;var b = $(this).attr(class);
        try {
            b = (b.split(" "))[0x1];
            var c = b.split("");
            var d = c.length;
            var f = [];
            for (var g = 0x0; g < d; g++) {
                f.push(ABCDEFGHIZ.indexOf(c[g]))
            }
            ;$(this).html(window.parseInt(f.join()) >> 0x3)
        } catch (e) {}
    })
})
  • 这段代码的逻辑,获取port标签的class属性值,取出属性中后面的几个大写字母,遍历该字符串,找出每次字符在’ABCDEFGHIZ’这个字符串中的索引,然后parseInt转换为整数,然后进行右移3位的操作。 完整代码实现
package com.cnblogs.wycm;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.net.URL;

public class Chapter2 {
          
   
    public static void main(String[] args) throws IOException {
        Document document= Jsoup.parse(new URL("http://www.goubanjia.com/"), 10000);
        setPort(document);
        //获取class=table的table的所有子节点tr
        Elements elements = document.select("table[class=table] tr");
        for (int i = 1; i < elements.size(); i++){
            //获取td节点
            Element td = elements.get(i).select("td").first();
            /**
             * 查找所有style属性包含none字符串的标签(页面上未显示的标签),并移除
             * 包括以下两种
             * style=display: none;
             * style=display:none;
             */
            for(Element none : td.select("[style*=none;]")){
                none.remove();
            }
            //移除空格
            String ipPort = td.text().replaceAll(" ", "");
            //打印
            System.out.println(ipPort);
        }
    }

    /**
     * js代码port还原
     * @param doc
     */
    private static void setPort(Document doc){
        for (Element e : doc.select(".port")){
         
  //$(.port).each(function() {
          
   
            String a = e.text();//var a = $(this).html();
            if(a.indexOf("*") != -0x1){
         
  //if (a.indexOf(*) != -0x1) {
          
   
                return;
            }
            String b = e.attr("class");//var b = $(this).attr(class);
            b = b.split(" ")[0x1];//b = (b.split(" "))[0x1];
            String[] c = b.split("");//var c = b.split("");
            int d = b.length();//var d = c.length;
            StringBuilder f = new StringBuilder();//var f = [];
            for(int g = 0x0; g < d; g++){
         
  //for (var g = 0x0; g < d; g++) {
          
   
                f.append("ABCDEFGHIZ".indexOf(c[g]));//f.push(ABCDEFGHIZ.indexOf(c[g]))
            }
            e.text(String.valueOf(Integer.valueOf(f.toString()) >> 0x3));//$(this).html(window.parseInt(f.join()) >> 0x3)
        }
    }
}
  • maven依赖
<dependency>
        <groupId>org.jsoup</groupId>
        <artifactId>jsoup</artifactId>
        <version>1.10.2</version>
 </dependency>

总结

标签:
来源:

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有