zoukankan      html  css  js  c++  java
  • 全网代理公开ip爬取(隐藏元素混淆+端口加密)

    简述

    本次要爬取的网站是全网代理,貌似还是代理ip类网站中比较有名的几个之一,其官网地址: http://www.goubanjia.com/

    对于这个网站的爬取是属于比较悲剧的,因为很久之前就写好了代码了只是没写博客总结,结果刚才看的时候发现人家改版了…之前的代码基本不能用了只好重新写…

    原来是一个列表页有很多项可以看到的,现在改版成只看前20条了,貌似只有不断的检测抓取不然这东西鸡肋没啥用了,不过还是爬取一下主要是了解下它的反爬策略。

    分析过程

    列表大概是这个样子的:

    image  

    还是先ctrl+shift+c选一下可疑元素,先选了一下端口,发现元素的class上还是有可疑元素:

    image

    然后源代码中搜索这个端口对应的ip定位:

    image

    咦?ip呢?ip哪里去了?

    然后ctrl+shift+c选一下页面上的ip:

    image

    这都是什么鬼….

    好的喝口水冷静一下,上面这种就是通过在正常的元素中插入隐藏元素,然后再给隐藏元素设置乱七八糟的值来达到一种混淆的目的,过滤的话也很简单,只要把非有效内容项去掉就可以了。

    这里的混淆元素主要包括下面几种:
    1. 隐藏的span标签: <span style="display: inline-block;"></span>

    2. 隐藏的p标签: <p style="display: none;">22</p>

    3. 空标签span

    需要注意有效内容并不是都是用div显示的,也有用span显示的。

    那么在选择的时候排除掉空标签和具有display:none样式的标识即可(虽然空标签选中也没什么关系…)。

    确定了ip的选取策略端口还没搞定,端口的解密逻辑在这个js中: http://www.goubanjia.com/theme/goubanjia/javascript/pde.js?v=1.0。这种类型的js加密跟无忧代理一模一样,之前已经写过不再赘述。

    根据以上分析写出简单的爬取demo:

    package org.cc11001100.t1;
    
    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;
    import java.util.List;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    import static java.util.stream.Collectors.toList;
    
    /**
     * 全网代理: http://www.goubanjia.com/
     * ip地址和端口均有反爬处理
     *
     * @author CC11001100
     */
    public class QuanWangProxyIpGrab {
    
        public static List<String> downloadAndParse(String url) throws IOException {
            Document document = Jsoup.parse(new URL(url), 3000);
            return document.select(".table-hover td.ip")
                .stream()
                .map(e -> {
                    Elements children = e.children();
                    Element portElement = children.select(".port").first();
                    children.remove(portElement);
                    String ip = children.select(":not(:empty):not([style~=display(\s*):(\s*)none(\s*);])").text().replaceAll("\s+", "");
                    int port = decodePort(portElement.attr("class").split("\s+")[1]);
                    return ip + ":" + port;
                }).collect(toList());
        }
    
        private static int decodePort(String rawContent) {
            String rawNum = Stream.of(rawContent.split(""))
                .map("ABCDEFGHIZ"::indexOf)
                .map(Object::toString)
                .collect(Collectors.joining());
            return Integer.parseInt(rawNum) >> 3;
        }
    
        public static void main(String[] args) throws IOException {
    
            downloadAndParse("http://www.goubanjia.com/").forEach(System.out::println);
    
        }
    
    }
    
  • 相关阅读:
    常见算法之17---二叉树相等判断以及二叉树的复制
    常见算法之16---二维数组中查找元素
    常见算法之15---求N!末尾有多少个0
    常见算法之14---球放入盒问题
    常见算法之13---跳台阶问题
    常见算法之12---求a^n%p
    DB与java的关联
    重拾python
    Codeforces Round 212 Div 2 报告(以前没写完,现在也没心情补了,先就这样吧)
    交换Ctrl和Caps Lock键
  • 原文地址:https://www.cnblogs.com/cc11001100/p/8647080.html
Copyright © 2011-2022 走看看