全網代理公開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);

    }

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM