国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

關(guān)于工作中爬取網(wǎng)站的一些思路記錄

這篇具有很好參考價值的文章主要介紹了關(guān)于工作中爬取網(wǎng)站的一些思路記錄。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

聲明:只是因為工作中需要,且基本不會對別人的網(wǎng)站構(gòu)成什么不好的影響,做個思路記錄?。?!
尊重網(wǎng)站所有者、控制請求頻率、遵守網(wǎng)站規(guī)則、尊重個人隱私

平常工作中難免會遇到需要爬取別人網(wǎng)站的需求,例如爬取兌換之類的流程,把接口爬取下來封裝到項目中,這種一般不會對別人的網(wǎng)站有什么的影響,因為也是正常流程下單,例如下面的活動截圖:
關(guān)于工作中爬取網(wǎng)站的一些思路記錄,JAVA,java,javascript,無頭瀏覽器

  • 1、先理解需求,從需求和界面上看,很容易知道我們基本只需要獲取兩個接口,一個是發(fā)送驗證碼接口,一個是兌換接口。當然也可能存在前置接口,具體情況具體分析
  • 2、先不要急著分析網(wǎng)站源碼,可以先嘗試找個手機號發(fā)送驗證碼,看看請求了哪些接口,接口的參數(shù)是什么,返回的數(shù)據(jù)是什么,例如:
    關(guān)于工作中爬取網(wǎng)站的一些思路記錄,JAVA,java,javascript,無頭瀏覽器
    關(guān)于工作中爬取網(wǎng)站的一些思路記錄,JAVA,java,javascript,無頭瀏覽器
  • 3、從請求接口的參數(shù)的返回分析,這個網(wǎng)站的數(shù)據(jù)部分接口需要加密,部分不需要,如果不需要加密的接口,基本很容易就獲取請求參數(shù),這里可以大膽猜測accessId、reqId可能為uuid,reqMethod為請求的方法,encrypted表示接口請求參數(shù)是否需要加密,但是光這樣看有點難以看出data和dataKey是什么加密算法加密而成,dataKey大概率是解密data的關(guān)鍵密鑰。這里建議一般情況下看一下加密后的數(shù)據(jù)的長度,是不是一些比較特殊的長度,比如36位、512位之類的長度,可以根據(jù)這個長度大膽猜測是否是平常常用的算法。
  • 4、對網(wǎng)站有個大概的數(shù)據(jù)交互認識之后,我們就可以知道難點基本在數(shù)據(jù)加密這一塊,這時候就可以來看源碼了,這里的思路我一般是直接定位到“發(fā)送驗證碼”的按鈕上,然后找到F12控制臺元素的事件監(jiān)聽器的click事件上,直接進入相關(guān)的代碼中,就可以看到這個按鈕的點擊事件的代碼了。
  • 5、網(wǎng)站的代碼都是經(jīng)過編譯的,且一般線上是不會直接開放源代碼的,這種時候如何光看編譯過后的代碼,有時候是比較難以理解,這種時候就需要打斷點,一步步調(diào)試了,看函數(shù)的參數(shù)和返回值,以及大概的處理過程。
  • 6、前面已經(jīng)分析過了,難點就在加密算法上,經(jīng)過代碼分析找到加密部分的代碼,如下圖:
    關(guān)于工作中爬取網(wǎng)站的一些思路記錄,JAVA,java,javascript,無頭瀏覽器
    從這段的代碼中,存在RSA和AES的字眼,且打斷點都走了這些函數(shù),可以看出這個網(wǎng)站是AES+RSA結(jié)合使用進行加密的。

AES+RSA:使用RSA秘鑰生成工具生成一對公鑰(A)和私鑰(B),前端保留A,后端保留B。
前端發(fā)送數(shù)據(jù)時,先生成一串隨機16位字符串作為AES的秘鑰(C),然后使用A使用RSA算法對C進行加密,得到加密后的AES秘鑰(D)。將要發(fā)送的數(shù)據(jù)(E)用C使用AES加密,得到密文(F)。將D和F一同發(fā)給后端進行處理。
后端處理數(shù)據(jù)時,先用B對D使用RSA進行解密得到C,用C對F使用AES進行解密得到E,處理后得到結(jié)果G,再用C對G進行AES加密得到H,將H返回給前端。
前端接收到H后用C進行解密,得到處理的結(jié)果G。

根據(jù)AES和RSA的配合流程來看,這里沒有直接返回RSA公鑰,而是根據(jù)摸和指數(shù)來生成RSA公鑰然后加密AES私鑰,用AES私鑰去加密數(shù)據(jù)進行傳輸,但是從前面請求參數(shù)來看,跟我們平常看到的AES和RSA字符串不一樣,顯然還做了相關(guān)的轉(zhuǎn)換,dataKey字段只有數(shù)字和小寫字母,平??吹降募用軘?shù)據(jù)還有大寫字母、+、/等。

  • 7、這里有一個比較難的地方就是“new no.RSAKeyPair(e,“”,t,2048)”這個對象,這個對象去加密隨機生成的AES密鑰生成dataKey字段,這里我也是看了半天,打斷點半天,也難以理解,因為編譯后很多變量是單個字母,且你需要換算成你自己項目的語言,如JAVA、Python等,有時候是比較難的,這時候你可能會想我能不能反編譯一下js文件,那你可以嘗試一下,比如找一些在線的網(wǎng)站上傳文件看看能不能反編譯,希望你能成功??
  • 8、遇到難點無法繼續(xù)下的時候怎么辦呢?給大家提供一種思路,就是嘗試直接拷貝它的js文件下來,然后在項目去執(zhí)行它的函數(shù),獲取結(jié)果,我這里是使用JAVA、jdk1.8版本,由JavaScript引擎去執(zhí)行js文件中的函數(shù),根據(jù)上面的截圖,我只需要執(zhí)行Fp()函數(shù)即可拿到dataKey,和隨機生成的AES私鑰。
    當然你如果直接執(zhí)行拷貝下來的js文件大概率是失敗,會報各種錯誤,例如jdk1.8不支持ES6語法,你需要先轉(zhuǎn)化成ES5語法格式(es6轉(zhuǎn)es5在線網(wǎng)站:https://babeljs.io/repl,需要勾選左側(cè)下面的"FORCE ALL TRANSFORMS"),其次你需要把不需要用到的代碼都刪掉,只留加密部分的代碼,可以根據(jù)入口函數(shù)一步步找到所有需要的變量和函數(shù)等,可以根據(jù)報錯一步步處理,這也是個小挑戰(zhàn)~
public static void main(String[] args) {
        // 創(chuàng)建JavaScript引擎
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("js");

        try {
            // 加載JavaScript文件
            engine.eval(new FileReader("C:\\Users\\win\\Desktop\\index2.js"));
            // 執(zhí)行JavaScript函數(shù)
            Object result = engine.eval("Fp()");
            
            // 這里是我習慣用serr打印測試日志,因為標紅比較顯眼
            System.err.println("Function Result: " + JSONObject.toJSONString(result));
            // 拿到Fp()函數(shù)返回的dataKey等數(shù)據(jù)
            JSONObject object = JSONObject.parseObject(JSONObject.toJSONString(result));
            // 要加密的數(shù)據(jù)
            String content = "{\"appId\":\"xxxx\"}";
            System.err.println("加密前的數(shù)據(jù):" + content);
            // 加密后的數(shù)據(jù)
            String encryptAES = encryptAES(content, object.getString("key"), object.getString("iv"));
            System.err.println("加密后的數(shù)據(jù):" + encryptAES);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * AES加密
     * @param plaintext 要加密的數(shù)據(jù)
     * @param key
     * @param iv
     */
    public static String encryptAES(String plaintext, String key, String iv) {
        try {
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);

            byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(encryptedBytes).toUpperCase();
        } catch (Exception e) {
            log.error("AES加密異常,{}", e.getMessage());
            return "";
        }
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02X", b));
        }
        return result.toString();
    }
  • 9、終極方案:無頭瀏覽器?。?!如果上面還不能解決你的問題,你可以嘗試使用無頭瀏覽器,模擬人工點擊操作,當然這比接口慢很多,但你不需要考慮網(wǎng)站的加密和接口調(diào)用等等,按照人工操作的流程執(zhí)行即可。注意,無頭瀏覽器你可能需要考慮代理ip和請求頭問題,盡可能模擬真實的操作,一直使用同一個ip和userAgent有可能會被檢測到。
/**
     * 獲取瀏覽器驅(qū)動
     */
    private WebDriver getDriver(Param pm) {
        // 設置隨機的設備 user-agent 和屏幕大小
        Map<String, Object> mobileEmulation = new HashMap<>();
        Map<String, Object> map = new HashMap<>();
        Dimension randomScreenSize = getRandomScreenSize();
        map.put("width", randomScreenSize.getWidth());
        map.put("height", randomScreenSize.getHeight());
        mobileEmulation.put("deviceMetrics", map);
        if (pm != null && Func.isNotBlank(pm.getUserAgent())) {
        	// 設置UA
            mobileEmulation.put("userAgent", pm.getUserAgent());
        }

        //谷歌瀏覽器設置
        ChromeOptions options = new ChromeOptions();
        // 隱藏瀏覽器、無頭瀏覽器
        options.addArguments("-headless");
        options.setExperimentalOption("mobileEmulation", mobileEmulation);
        // 打開F12
//        options.addArguments("--auto-open-devtools-for-tabs");
        // 啟動無沙盒模式運行,以最高權(quán)限運行
        options.addArguments("--no-sandbox");
        // 不加載圖片, 提升速度
        options.addArguments("blink-settings=imagesEnabled=false");
        
        options.addArguments("--disable-dev-shm-usage");
        // 禁用gpu渲染
        options.addArguments("--disable-gpu");
        // 禁用阻止彈出窗口
        options.addArguments("--disable-popup-blocking");
        // 禁用擴展
        options.addArguments("disable-extensions");
        // 禁用默認瀏覽器檢查
        options.addArguments("no-default-browser-check");
        // 忽略不信任證書
        options.addArguments("–ignore-certificate-errors");
        // 禁用自動化控制特性
        options.addArguments("--disable-blink-features=AutomationControlled");
        // 禁用通知
        options.addArguments("--disable-notifications");
        // 禁用信息欄
        options.addArguments("--disable-infobars");
        // 禁用日志記錄
        options.addArguments("--disable-logging");

        LoggingPreferences logPrefs = new LoggingPreferences();
        logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
        options.setCapability("goog:loggingPrefs", logPrefs);

        // 禁用默認應用程序
        options.addArguments("--disable-default-apps");
        // 靜音
        options.addArguments("--mute-audio");
        // 禁用自動化標志
        options.setExperimentalOption("excludeSwitches", new String[]{"enable-automation"});

        // 設置代理ip
        if (pm != null && Func.isNotBlank(pm.getProxyIp())) {
            String proxyAddress = pm.getProxyIp() + ":" + pm.getProxyPort();

            Proxy proxy = new Proxy();
            proxy.setHttpProxy(proxyAddress);
            proxy.setSslProxy(proxyAddress);
            options.setProxy(proxy);
        }
        return new ChromeDriver(options);
    }

谷歌瀏覽器驅(qū)動路徑:https://googlechromelabs.github.io/chrome-for-testing/#stable文章來源地址http://www.zghlxwxcb.cn/news/detail-729028.html

public void handle(Param pm) {
        WebDriver driver = null;
        try {
            if (Func.isBlank(pm.getUserAgent())) {
            	// 這個工具類只是隨機生成userAgent的工具類
                pm.setUserAgent(UserAgentUtil.getUserAgent());
            }
			// 谷歌瀏覽器驅(qū)動路徑,注意驅(qū)動版本問題
            System.setProperty("webdriver.chrome.driver", "F:/chromedriver-win64/chromedriver.exe");
            driver = getDriver(pm);
//            driver.manage().window().maximize();
            // 進入頁面
            driver.get("https://xxx");

            JavascriptExecutor js = (JavascriptExecutor) driver;
            //添加cookie
            if (pm.getCookies() != null && pm.getCookies().size() > 0) {
                setCookie(js, pm.getCookies());
            }
            // 隱式等待
            driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

          	// 其他相關(guān)處理代碼
          	...
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (driver != null) {
                driver.quit();
            }
        }
    }

到了這里,關(guān)于關(guān)于工作中爬取網(wǎng)站的一些思路記錄的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關(guān)文章

  • 關(guān)于信息學奧賽中的一些做題思路

    本文記錄了筆者在刷題或比賽中運用到的一些做題思路 可以 適當 參考 首先顯然有 (mathcal {O}(n^2)) 暴力 枚舉每個子段,然后選擇其中前k大的 那么可以發(fā)現(xiàn)有 貪心 策略: 選擇k次最大值 那么考慮怎樣求最大值 想到可以枚舉每個起始位置,想辦法計算從該位置開始符合要求

    2024年03月13日
    瀏覽(19)
  • 關(guān)于網(wǎng)絡安全運營工作與安全建設工作的一些思考

    關(guān)于網(wǎng)絡安全運營工作與安全建設工作的一些思考

    以下內(nèi)容是個人成長過程中對于網(wǎng)絡安全運營工作的理解和思考,希望通過這篇文章幫助大家更好的去做安全運營體系化建設,開始吧! 安全運營工作并不是通過各類安全設備的疊加增強安全能力,而是通過技術(shù)與管理結(jié)合的形式將企業(yè)現(xiàn)有的安全能力進行最大化展現(xiàn)。為了

    2024年02月04日
    瀏覽(28)
  • 【工作記錄】基于可視化爬蟲spiderflow實戰(zhàn)天氣數(shù)據(jù)爬取@20230618

    【工作記錄】基于可視化爬蟲spiderflow實戰(zhàn)天氣數(shù)據(jù)爬取@20230618

    之前寫過一篇關(guān)于可視化爬蟲spiderflow的文章,介紹了基本語法并實戰(zhàn)了某校園新聞數(shù)據(jù)的爬取。 還有一篇文章介紹了基于docker-compose快速部署spiderflow的過程,需要部署的話可參考該文章。 文章鏈接如下: 可視化爬蟲框架spiderflow入門及實戰(zhàn) 【工作記錄】基于docker-compose快速部

    2024年02月11日
    瀏覽(28)
  • 【復現(xiàn)go語言編寫的區(qū)塊鏈PBFT共識算法中爬坑記錄】

    【復現(xiàn)go語言編寫的區(qū)塊鏈PBFT共識算法中爬坑記錄】

    先附上代碼鏈接:https://github.com/corgi-kx/blockchain_consensus_algorithm/tree/master/pbft 主要是想記錄一下運行代碼過程中遇到的問題,萬一以后用得到,還能抄一下作業(yè) 電腦上沒有g(shù)o語言環(huán)境,按下面步驟進行環(huán)境配置: 1、首先在go官網(wǎng)下載https://golang.org/dl/安裝包,根據(jù)自己電腦選擇

    2024年01月25日
    瀏覽(19)
  • 關(guān)于laravel使用Elastic Search的一些記錄

    關(guān)于laravel使用Elastic Search的一些記錄

    1. 準備工作 因為我本地php版本是7.3.4,不支持太高的es。 所以使用如下環(huán)境: laravel6 + php7.3.4 + elastic search 7.17.2 2. 本地安裝elastic search 注意事項: 如果是8以上版本,初次啟動時會生成密碼。安裝成功以后,訪問 https://localhost:9200/ ,會提示輸入密碼。用戶名為elastic,密碼就是

    2024年02月11日
    瀏覽(21)
  • JAVA刷題之字符串的一些個人思路

    JAVA刷題之字符串的一些個人思路

    感謝您的閱讀! ??????? write in front???????? ?????????大家好,我是xiaoxie.希望你看完之后,有不足之處請多多諒解,讓我們一起共同進步????? . ?? ?xiaoxie?????????—CSDN博客 本文由xiaoxie??????????原創(chuàng) CSDN?如需轉(zhuǎn)載還請通知???? 個人

    2024年02月05日
    瀏覽(19)
  • 關(guān)于Java注解的一些理解 小結(jié)

    關(guān)于Java注解的一些理解 小結(jié)

    目錄 1. 常用注解和理解 2. 自定義注解 2.1 案例背景 2.2 設計思路 3 總結(jié) 注解在我的理解下,就是代碼中的特殊標記,這些標記可以在 編譯、類加載、運行時 被讀取,并執(zhí)行相對應的處理。 可能有些抽象,簡單來說注解其實在開發(fā)中是非常常見的,比如我們在使用各種框架時

    2023年04月23日
    瀏覽(18)
  • 工作三年后, 我作為Java后端開發(fā)的一些心得

    敢于和善于使用package 對于Java后端開發(fā)來講, 在長時間的web開發(fā)中. 大家已經(jīng)熟悉了MVC架構(gòu), 也被這套結(jié)構(gòu)所束縛. 導致創(chuàng)建出來的包也一直都是controller, manager, service, dao. 也將各種各樣的類文件都放入其中. 這并不是一種好的做法. 其實我們可以大膽的創(chuàng)建相關(guān)的package, 只要讓

    2024年02月13日
    瀏覽(17)
  • 請問一下java在線編程的網(wǎng)站有哪一些?

    請問一下java在線編程的網(wǎng)站有哪一些?

    前言 下面為大家整合了一些Java在線編程的的網(wǎng)站,個人認為都是挺好用的,整合不易,希望大家能順手留下點贊和收藏! 廢話少說,我們直接進入正題: 1、菜鳥工具 菜鳥工具的這個在線編程工具頁面很為簡潔,寫代碼的區(qū)域和結(jié)果輸出的區(qū)域很清晰,可以下載當前編輯的

    2024年02月16日
    瀏覽(18)
  • 關(guān)于Java中@Transient主鍵的作用的一些介紹

    @Transient 主下面是關(guān)于 @Transient 主鍵的使用方法、代碼案例以及與 transient 的區(qū)別,以及一些實用場景的詳細介紹。 在實體類中,通常需要將某些字段標記為主鍵,并將其映射到數(shù)據(jù)庫中的主鍵字段。但是,有時候我們可能希望某個字段在實體類中作為主鍵使用,但不

    2024年02月10日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包