整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          使用 API 代理服務(wù)器隱藏您的 API 密鑰

          文/教程的主要目的是演示如何通過使用 NodeJS 構(gòu)建 API 代理服務(wù)器來隱藏公共 API 密鑰。


          在這篇文章/教程中,我們將使用 NodeJS 創(chuàng)建一個(gè) API 代理服務(wù)器,這背后的主要原因是向您展示如何隱藏公共 API 密鑰,而不是像我過去那樣公開它們。我們所有人都創(chuàng)建了一個(gè)應(yīng)用程序,只是為了了解一個(gè)新的庫或框架,而實(shí)現(xiàn)這一點(diǎn)的最佳方法是使用開放 API(如TMDB)。

          這些開放 API 中的大多數(shù)都需要在發(fā)出請求之前在請求 URL 或標(biāo)頭中添加 API 密鑰。無論哪種方式,API 密鑰都可能被實(shí)際上不擁有此密鑰的人竊取和使用。因此,您最終可能會被暫停帳戶,或者您的應(yīng)用程序無法按預(yù)期運(yùn)行。

          請記住:API 密鑰屬于應(yīng)用程序的服務(wù)器端。

          話不多說,讓我們創(chuàng)建這個(gè) API 代理服務(wù)器。為了這篇文章/教程的緣故,我們將使用Wea?ther API。

          要求

          在開始編碼之前,我們需要具備以下條件:

          • API 密鑰
            打開 OpenWeatherMapAPI 網(wǎng)站,創(chuàng)建一個(gè)免費(fèi)帳戶,轉(zhuǎn)到
            我的 API 密鑰并創(chuàng)建一個(gè)。
          • JavaScript和NodeJS的基礎(chǔ)知識
          • java

          依賴項(xiàng)和腳本

          創(chuàng)建應(yīng)用程序的項(xiàng)目文件夾

          cd ~/Documents/tutorials
          mkdir api-proxy-server && cd api-proxy-server
          npm init -y


          安裝所需的 NPM 包


          npm install -S express cors dotenv axios
          npm install -D nodemon # for faster development


          在 package.json 文件中準(zhǔn)備腳本

          JSON

          {
            "scripts": {
              "start": "node index.js",
              "dev": "nodemon --config nodemon.json"
            }
          }


          讓我們看一下項(xiàng)目的文件夾和文件,以便更清晰地了解結(jié)構(gòu)。

          server/
          ├── src
          │   ├── utils
          │   │   └── env.js
          │   └── routes
          │       └── index.js
          ├── package.json
          ├── nodemon.json
          ├── index.js
          └── .env
          3 directories, 6 files


          在項(xiàng)目的根目錄下創(chuàng)建一個(gè)index.js和一個(gè)文件。nodemon.json

          JSON

          // nodemon.json
          {
            "verbose": true,
            "ignore": ["node_modules/"],
            "watch": ["./**/*"]
          }


          在我們開始編輯 entry ( index.js) 文件之前,我們需要?jiǎng)?chuàng)建另外兩個(gè)有用的文件。第一個(gè)是.env我們所有環(huán)境變量所在的文件。它將有點(diǎn)可重用,以便能夠與除 OpenWeatherMap API 之外的其他公共 API 一起使用。

          API_PORT = 1337
          API_BASE_URL = "https://api.openweathermap.org/data/2.5/weather"
          API_KEY = "1d084c18063128c282ee3b41e91b6740" # not actually api key; use a valid one


          另一個(gè)文件是src/utils/env.js負(fù)責(zé)讀取和導(dǎo)出所有環(huán)境變量的文件。

          JavaScript

          require("dotenv").config();
          
          module.exports = {
            port: Number(process.env.API_PORT) || 3000,
            baseURL: String(process.env.API_BASE_URL) || "",
            apiKey: String(process.env.API_KEY) || "",
          };
          


          現(xiàn)在是時(shí)候編輯主文件并向這個(gè)代理服務(wù)器應(yīng)用程序添加一些邏輯了。

          JavaScript

          // imports
          const express = require("express");
          const cors = require("cors");
          const env = require("./src/utils/env");
          
          // Application
          const app = express();
          
          // Middlewares
          app.use(express.json());
          app.use(express.urlencoded({ extended: true }));
          app.use(cors());
          
          // Routes
          app.use("/api", require("./src/routes")); // Every request that starts with /api will be handled by this handler
          
          // This route will handle all the requests that are not handled by any other route handler
          app.all("*", (request, response, next) => {
            return response.status(404).json({ message: "Endpoint not found!" });
          });
          
          // Bootstrap server
          app.listen(env.port, () => {
            console.log(`Server is up and running at http://localhost:${env.port}`);
          });


          這里的事情很簡單;它是一個(gè)基本的 ExpressJs 服務(wù)器應(yīng)用程序。在頂部,我們有所需的導(dǎo)入。然后我們有一些需要的中間件,例如JSON中間件,它負(fù)責(zé)解析帶有 JSON 有效負(fù)載的傳入請求,并且基于body-parser. 接下來,我們在此處管理端點(diǎn)及其處理程序的路由。最后,我們得到了服務(wù)器的引導(dǎo)。

          讓我們看一下/api路由的處理程序。

          JavaScript

          // server/src/routes/index.js
          const router = require("express").Router();
          const { default: axios } = require("axios");
          const env = require("../utils/env");
          
          // [GET] Current weather data
          router.get("/", async (request, response, next) => {
            try {
              const query = request.query || {}; 
              const params = {
                appid: env.apiKey, // required field
                ...query,
              };
              const { data } = await axios.get(env.baseURL, { params });
          
              return response.status(200).json({
                message: "Current weather data fetched!",
                details: { ...data },
              });
            } catch (error) {
              const {
                response: { data },
              } = error;
              const statusCode = Number(data.cod) || 400;
              return response
                .status(statusCode)
                .json({ message: "Bad Request", details: { ...data } });
            }
          });
          
          module.exports = router;


          請求處理函數(shù)將GET我們在調(diào)用它時(shí)提供的查詢字段作為輸入。

          例如,如果我們沒有這個(gè) API 代理服務(wù)器,我們的請求看起來像這樣https://api.openweathermap.org/data/2.5/weather?q=Thessaloniki,Greece&appid={API key},但是現(xiàn)在我們已經(jīng)有了它,我們的請求看起來像這樣http://localhost/api?q=Thessaloniki,Greece。不需要添加必填字段appid,因?yàn)榇矸?wù)器自己將其添加為請求參數(shù)。當(dāng)我們在 OpenWeatherMap API 上發(fā)出請求時(shí),我們盡量不顯示 API 密鑰。

          概括

          主要概念是將您的公共 API 密鑰隱藏在 API 代理服務(wù)器后面,以防止用戶竊取您的密鑰。為了實(shí)現(xiàn)這一點(diǎn),它是創(chuàng)建端點(diǎn)來包裝實(shí)際開放 API 的端點(diǎn),在需要此密鑰的每個(gè)請求中提供代理服務(wù)器內(nèi)的 API 密鑰作為環(huán)境變量。這種方法的明顯缺點(diǎn)是這是一個(gè)耗時(shí)的過程,在某些情況下甚至不需要。

          您可以在此處獲取此 API 代理服務(wù)器的源代碼。

          下一步是什么

          我正在考慮向這個(gè)代理服務(wù)器添加一些功能。其中之一是添加緩存功能,以便更快地提供最近請求的數(shù)據(jù)。另一種是添加速率限制器,以防止用戶過度使用 API 并導(dǎo)致服務(wù)器崩潰。

          如果您想到了另一種隱藏 API 密鑰的解決方案,或者您有任何提示或技巧要告訴我,請發(fā)表評論。

          效果圖:

          2 html骨架:

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <!--網(wǎng)頁標(biāo)題-->
              <title>detection</title>
              <!--內(nèi)部css部分-->
              <style>
              ......
              </style>
          </head>
          
          <body>
              <!--div部分-->
              <div class="contain">
              ......
              </div>
          
              <!--內(nèi)部js部分-->
              <script>    
                ......
              </script>
          </body>
          </html>

          3 css部分:

           <!--內(nèi)部css部分-->
              <style>
                  /*網(wǎng)頁和body整體設(shè)置*/
                  html,body{
                      margin:0;
                      padding:0;
                      /*網(wǎng)頁背景顏色設(shè)置*/
                      background-color: rgb(96, 94, 212);
                  }
                  
                  /*class='contain'在css的前面有點(diǎn)*/
                  .contain{
                      width:200px;
                      height: 200px;
                      font-size:25px;
                      text-align: center;
                      position: absolute;
                      left:50%;
                      top:50%;
                      transform:translate(-50%,-50%);
                      z-index:30;
                  }
          
                  /*警示label和結(jié)果label*/
                  .alertInfo,.resultInfo{
                      color:rgb(12, 231, 213);
                      font-weight: bold;
                      /*可以寫在這里,注意數(shù)字和px緊緊相鄰*/
                      width: 350px;
                      height: 10px;
          
                  }
                  
                  /*輸入框的設(shè)置*/
                  .text{
                      width:150px;
                      /*文本框默認(rèn)顯示,下面就是不顯示*/
                      /*outline:none;*/ 
                      text-align: center;
                      font-size:25px;
                      color:blue;
                  }
          
                  /*顯示框的設(shè)置*/
                  .show{
                      font-size:25px;
                      color:red;
                  }
              </style>

          4 body的div部分:

              <!--div部分-->
              <div class="contain">
                  <!--注意:style可以嵌套在里面,但不推薦,也可以單獨(dú)寫在上面的css內(nèi)-->
                  <!--p class="alertInfo" style="width: 350px; height: 10px">顯示倒5個(gè)字符串的輸入框:</!--p-->
                  <p class="alertInfo" >顯示倒5個(gè)字符串的輸入框:</p>
                  <!--placeholder是指輸入框默認(rèn)顯示文字-->
                  <input type="text" class="text" placeholder="請輸入內(nèi)容">
                  <!--p class="resultInfo" style="width: 350px; height: 10px">顯示倒4個(gè)字符串的顯示區(qū):</!--p-->
                  <p class="resultInfo" >顯示倒4個(gè)字符串的顯示區(qū):</p>
                  <p class="show"></p>
              </div>

          5 body的js=JavaScript=script部分:

              <!--內(nèi)部js部分-->
              <script>
                  // 被let聲明的變量不會作為全局對象window的屬性,而被var聲明的變量卻可以
                  //text和show均是class,所以前面有一個(gè)點(diǎn)
                  let input=document.querySelector(".text");
                  let show= document.querySelector(".show");
                  input.addEventListener('keyup',debounce(handle,100));
                  // 防抖處理
                  function debounce(func,wait){
                      let timeflag;
                      return function(){
                          clearTimeout(timeflag); //清除100ms之內(nèi)之前觸發(fā)的定時(shí)器。
                          let arg=arguments;
                          let timethis = this;
                          timeflag = setTimeout(func.bind(timethis,arg),wait);
                      }
                  }
                  //回調(diào)函數(shù)
                  function handle(){
                      //輸入框內(nèi)倒取5個(gè)字符串
                      input.value=input.value.slice(-5);
                      //輸入框內(nèi)倒取4個(gè)字符串
                      show.textContent=input.value.slice(-4);
                      
                  }
              </script>

          6 html部分基礎(chǔ)學(xué)習(xí),自己整理并分享出來。

          文將介紹驗(yàn)證碼的歷史與發(fā)展、驗(yàn)證碼破解的歷史與發(fā)展,驗(yàn)證碼破解全流程實(shí)戰(zhàn)。

          驗(yàn)證碼的歷史與發(fā)展

          驗(yàn)證碼,全稱為“Completely Automated Public Turing test to tell Computers and Humans Apart”,即全自動(dòng)區(qū)分計(jì)算機(jī)和人類的圖靈測試,Captcha。早在上個(gè)世紀(jì)90年代,為了防止惡意的網(wǎng)絡(luò)機(jī)器人行為,像郵件轟炸、暴力破解密碼等,驗(yàn)證碼應(yīng)運(yùn)而生。

          最初的驗(yàn)證碼是簡單的文本字符,如用戶只需輸入一組扭曲的字母和數(shù)字。然后驗(yàn)證碼發(fā)展到圖像驗(yàn)證碼,例如,要求用戶識別哪些圖片中包含某個(gè)特定對象(比如貓、狗或汽車等)。隨著技術(shù)的發(fā)展,更為復(fù)雜的驗(yàn)證碼類型出現(xiàn)了,例如邏輯驗(yàn)證碼(例如,3+4=?),音頻驗(yàn)證碼(用戶必須聽音頻然后輸入聽到的字符)和3D驗(yàn)證碼(用戶需要解讀3D對象或者場景)。

          此外,也有一些新的驗(yàn)證碼設(shè)計(jì),為了提高用戶體驗(yàn)同時(shí)維護(hù)網(wǎng)站安全,它們需要用戶進(jìn)行更為人性化的操作。例如,滑動(dòng)驗(yàn)證碼讓用戶通過滑動(dòng)解鎖,點(diǎn)擊驗(yàn)證碼讓用戶點(diǎn)擊特定的圖片或文字,旋轉(zhuǎn)驗(yàn)證碼則要求用戶調(diào)整圖片到正確的方向。

          一些大公司也開發(fā)了自己的驗(yàn)證碼系統(tǒng)。例如,Google的reCAPTCHA v2引入了復(fù)雜的圖像識別任務(wù),需要用戶選擇包含特定物體(如汽車,交通燈)的圖片;而Google的reCAPTCHA v3則摒棄了用戶交互的方式,通過分析用戶的行為模式來確定是人類還是機(jī)器。同樣,第三方驗(yàn)證服務(wù)如GeeTest CAPTCHA和hCaptcha等,也為網(wǎng)站提供了驗(yàn)證服務(wù),使得他們可以更好地防止自動(dòng)化的惡意行為。


          驗(yàn)證碼破解的歷史與發(fā)展

          驗(yàn)證碼破解的歷史,與驗(yàn)證碼的發(fā)展緊密相連。早期的驗(yàn)證碼破解主要依賴于OCR(Optical Character Recognition,光學(xué)字符識別)技術(shù),這是一種將圖像中的文本轉(zhuǎn)換為機(jī)器可讀的字符的技術(shù),用于識別簡單的文本驗(yàn)證碼。

          然而,隨著驗(yàn)證碼的復(fù)雜性的增加,驗(yàn)證碼破解也需要更為復(fù)雜的技術(shù)。例如,對于圖像驗(yàn)證碼,可能需要使用圖像處理技術(shù)來處理噪聲和扭曲。這可能包括灰度化(將圖像轉(zhuǎn)換為黑白),二值化(將圖像進(jìn)一步簡化為只有黑和白兩種顏色),邊緣檢測(識別圖像中的邊緣)等步驟。

          對于更為復(fù)雜的驗(yàn)證碼,例如點(diǎn)擊驗(yàn)證碼和旋轉(zhuǎn)驗(yàn)證碼,可能需要使用更復(fù)雜的機(jī)器視覺技術(shù)。這可能涉及到特征提?。ㄗR別圖像中的重要特征),對象識別(識別特定的對象或形狀),甚至深度學(xué)習(xí)(訓(xùn)練模型來識別復(fù)雜的模式)。

          近年來,隨著人工智能的發(fā)展,機(jī)器學(xué)習(xí)和深度學(xué)習(xí)等技術(shù)也被應(yīng)用于驗(yàn)證碼破解中。例如,卷積神經(jīng)網(wǎng)絡(luò)(CNN)已經(jīng)被用來識別復(fù)雜的圖像驗(yàn)證碼,而遞歸神經(jīng)網(wǎng)絡(luò)(RNN)可以用于識別音頻驗(yàn)證碼。這些模型通過在大量的數(shù)據(jù)上進(jìn)行訓(xùn)練,可以學(xué)習(xí)到識別驗(yàn)證碼的復(fù)雜模式,大大提高了驗(yàn)證碼破解的準(zhǔn)確性和效率。


          新時(shí)代高精準(zhǔn)識別驗(yàn)證碼的人工服務(wù)

          人工驗(yàn)證碼識別服務(wù)是一種基于人工智能或人工勞動(dòng)力的驗(yàn)證碼識別解決方案。當(dāng)機(jī)器無法識別復(fù)雜的驗(yàn)證碼時(shí),這種服務(wù)能夠提供相對高效且準(zhǔn)確的解決方案。

          2Captcha

          2Captcha是一種基于人工勞動(dòng)力的驗(yàn)證碼識別服務(wù)。它提供了一個(gè)API接口,允許開發(fā)者將無法識別的驗(yàn)證碼發(fā)送到2Captcha服務(wù)。然后2Captcha的工人會手動(dòng)識別并返回結(jié)果。這種服務(wù)對處理圖像驗(yàn)證碼、文本驗(yàn)證碼、點(diǎn)擊類驗(yàn)證碼、GeeTest、reCAPTCHA、FunCaptcha等復(fù)雜驗(yàn)證碼有很高的準(zhǔn)確率,并且提供多種編程語言的接口文檔Python、PHP、Java、Go、Ruby、C++、C#。2Captcha的主要優(yōu)點(diǎn)是其優(yōu)異的精確性和靈活的API,使得開發(fā)者可以輕松集成并在不同環(huán)境中使用。

          云碼

          云碼基于圖像識別技術(shù)和人工輔助提供驗(yàn)證碼識別服務(wù),提供在線普通圖片、滑動(dòng)、點(diǎn)選、谷歌、HCaptcha、數(shù)字計(jì)算題驗(yàn)證碼識別服務(wù)。其對于圖像類的驗(yàn)證碼有比較好的效果,尤其是各種不同類型的圖像驗(yàn)證碼。但其對于復(fù)雜的驗(yàn)證碼存在準(zhǔn)確率下降和識別時(shí)間較長的情況、驗(yàn)證碼種類跟進(jìn)相較也會慢一些。

          冰拓

          冰拓可識別各種常見圖片驗(yàn)證碼,AI識別 + 真人識別雙模式,可高效識別坐標(biāo)題、計(jì)算題、字符題、滑塊題、拼圖題等各種圖片。API支持Python、JAVA、PHP、JAVASCRIPT調(diào)用,支持按鍵精靈集成。對于多樣化的滑塊、拼圖、旋轉(zhuǎn)、坐標(biāo)有自己獨(dú)特的處理方法和提供定制服務(wù),不支持谷歌驗(yàn)證碼。

          超級鷹

          超級鷹是專業(yè)的人工打碼平臺,對圖片數(shù)據(jù)進(jìn)行精準(zhǔn)、快速分類處理,并實(shí)時(shí)返還分類結(jié)果。支持英文數(shù)字、中文漢字、坐標(biāo)選擇計(jì)算等多種類型圖片驗(yàn)證碼,并且提供定制化的驗(yàn)證碼識別服務(wù)。對于通用的驗(yàn)證碼、傳統(tǒng)驗(yàn)證碼有較好的識別效果,但對于復(fù)雜驗(yàn)證碼尚未提供更多服務(wù)。


          驗(yàn)證碼破解實(shí)戰(zhàn)

          以2Captcha破解reCAPTCHA v2為例

          1. 注冊2Captcha,https://cn.2captcha.com/ ,支持支付寶充值

          2. 目標(biāo)破解https://www.scrapebay.com/spam 網(wǎng)站reCAPTCHA v2

          3. 拿到2Captcha API_KEY

          4. 拿到google sitekey

          5. 破解驗(yàn)證碼

          安裝2captcha-python

          pip3 install 2captcha-python
          

          破解驗(yàn)證碼

          # 導(dǎo)入BeautifulSoup、TwoCaptcha、requests庫
          from bs4 import BeautifulSoup
          from twocaptcha import TwoCaptcha
          import requests
          
          # TwoCaptcha服務(wù)的API秘鑰,你需要使用自己的
          API_KEY = 'xxxxxxxxxxxxxx'
          # 利用TwoCaptcha庫,使用提供的API秘鑰初始化一個(gè)solver對象,該對象可以解決ReCAPTCHA問題
          solver = TwoCaptcha(API_KEY)
          # 要抓取的網(wǎng)頁的URL
          url = "https://www.scrapebay.com/spam"
          # 這是ReCAPTCHA的site key,可以從網(wǎng)頁源碼中找到。
          site_key='6LfGNEoeAAAAALUsU1OWRJnNsF1xUvoai0tV090n'
          
          # 這個(gè)函數(shù)用來獲取CSRF token和cookies。它首先通過requests.get()獲取頁面內(nèi)容,然后通過BeautifulSoup找到CSRF token。最后返回CSRF token和cookies。
          def get_csrf_cookie(url):
              response = requests.get(url)
              soup = BeautifulSoup(response.text, "lxml")
              csrf_el = soup.select_one('[name=csrfmiddlewaretoken]')
              csrf = csrf_el['value']
              cokkies = response.cookies
              return csrf, cokkies
          
          # 這個(gè)函數(shù)用來解決ReCAPTCHA問題。它使用TwoCaptcha solver對象的recaptcha()方法,如果發(fā)生異常則打印錯(cuò)誤并退出。
          def solve(url,sitekey):
              try:
                  result = solver.recaptcha(sitekey=sitekey, url=url)
              except Exception as e:
                  print(e)
                  exit()
              return result
          
          # 首先通過get_csrf_cookie(url)獲取CSRF token和cookies,然后通過solve(url,site_key)解決ReCAPTCHA問題,獲得ReCAPTCHA的驗(yàn)證碼結(jié)果
          def main():
              csrf,cokkies = get_csrf_cookie(url)
              print("csrf:",csrf)
              print("cokkies:",cokkies)
              result = solve(url,site_key)
              print("captcha:",result)
          
          
          if __name__ == "__main__":
              main()
          

          運(yùn)行結(jié)果:

          6. 獲得驗(yàn)證碼后的頁面數(shù)據(jù)

          包含破解驗(yàn)證碼的全部代碼如下:

          # 導(dǎo)入BeautifulSoup、TwoCaptcha、requests庫
          from bs4 import BeautifulSoup
          from twocaptcha import TwoCaptcha
          import requests
          
          # 2Captcha服務(wù)的API秘鑰,你需要使用自己的
          API_KEY = 'xxxxxxxxxxxxxx'
          # 利用TwoCaptcha庫,使用提供的API秘鑰初始化一個(gè)solver對象,該對象可以解決ReCAPTCHA問題
          solver = TwoCaptcha(API_KEY)
          # 要抓取的網(wǎng)頁的URL
          url = "https://www.scrapebay.com/spam"
          # 這是ReCAPTCHA的site key,可以從網(wǎng)頁源碼中找到。
          site_key='6LfGNEoeAAAAALUsU1OWRJnNsF1xUvoai0tV090n'
          
          # 這個(gè)函數(shù)用來獲取CSRF token和cookies。它首先通過requests.get()獲取頁面內(nèi)容,然后通過BeautifulSoup找到CSRF token。最后返回CSRF token和cookies。
          def get_csrf_cookie(url):
              response = requests.get(url)
              soup = BeautifulSoup(response.text, "lxml")
              csrf_el = soup.select_one('[name=csrfmiddlewaretoken]')
              csrf = csrf_el['value']
              cokkies = response.cookies
              return csrf, cokkies
          
          # 這個(gè)函數(shù)用來解決ReCAPTCHA問題。它使用TwoCaptcha solver對象的recaptcha()方法,如果發(fā)生異常則打印錯(cuò)誤并退出。
          def solve(url,sitekey):
              try:
                  result = solver.recaptcha(sitekey=sitekey, url=url)
              except Exception as e:
                  print(e)
                  exit()
              return result
          
          # 這個(gè)函數(shù)用來提交解決ReCAPTCHA后的頁面。它首先構(gòu)建一個(gè)POST請求的payload,然后通過requests.post()方法發(fā)送請求。最后返回網(wǎng)頁的最后一列的文本。
          def post_page(url, csrf, cookie, result):
              payload = 'csrfmiddlewaretoken={}&g-recaptcha-response={}'
              headers = {
                  'Content-Type': 'application/x-www-form-urlencoded',
                  'Referer': 'https://www.scrapebay.com/spam'
              }
              response = requests.post(url,data=payload.format(csrf,result),headers=headers,cookies=cookie)
              soup = BeautifulSoup(response.text, "lxml")
              el = soup.select_one('td:last-child')
              return el.get_text()
          
          # 先通過get_csrf_cookie(url)獲取CSRF token和cookies,然后通過solve(url,site_key)解決ReCAPTCHA問題,最后通過post_page(url,csrf,cokkies,result)提交頁面并打印出結(jié)果。
          def main():
              csrf,cokkies = get_csrf_cookie(url)
              print("csrf:",csrf)
              print("cokkies:",cokkies)
              result = solve(url,site_key)
              print("captcha:",result)
              data = post_page(url,csrf,cokkies,result)
              print("result:",data)
          
          if __name__ == "__main__":
              main()
          

          網(wǎng)站驗(yàn)證后的頁面:

          運(yùn)行結(jié)果:


          7. 結(jié)束

          至此我們使用2Captcha服務(wù)破解了reCAPTCHA v2,并獲得了需要爬取的內(nèi)容。2Captcha服務(wù)包含多種驗(yàn)證碼格式,均可以使用上述的流程,修改其中不同驗(yàn)證碼的細(xì)節(jié)部分,攻克驗(yàn)證碼的識別難點(diǎn)。


          主站蜘蛛池模板: 精品日产一区二区三区手机| 亚洲AV无码国产精品永久一区| 北岛玲在线一区二区| 精品国产免费观看一区| 国产免费一区二区三区不卡| 中文字幕在线视频一区| 国产福利一区二区三区视频在线| 97se色综合一区二区二区| 亚洲第一区精品日韩在线播放| 国产一区二区视频在线观看| 精品午夜福利无人区乱码一区| 亚洲av无码天堂一区二区三区 | 久久精品动漫一区二区三区| 高清国产AV一区二区三区| 在线观看一区二区精品视频| 久久精品国产一区| 精品一区二区三区在线观看| 国产精品视频免费一区二区| 精品少妇ay一区二区三区| 无码人妻精品一区二区蜜桃百度 | 久久久不卡国产精品一区二区| 亚洲AV无码一区二区乱子伦 | 久久一区二区明星换脸| 无码国产精品久久一区免费| 冲田杏梨AV一区二区三区| 痴汉中文字幕视频一区| 国产高清一区二区三区四区| 日韩精品中文字幕视频一区| 精品一区二区三区波多野结衣| 国产一区二区三区91| 亚洲AV无码一区二区三区在线| 内射女校花一区二区三区| 中文字幕一区二区人妻性色| 久久成人国产精品一区二区| 一区 二区 三区 中文字幕| 日韩少妇无码一区二区三区| 日韩视频在线观看一区二区| 国产99精品一区二区三区免费| 国产精品被窝福利一区 | 久久中文字幕无码一区二区| 91精品一区二区三区久久久久|