Python爬蟲(chóng)教程:200行代碼實(shí)現(xiàn)一個(gè)滑動(dòng)驗(yàn)證碼

Python爬蟲(chóng)教程:教你用200行代碼實(shí)現(xiàn)一個(gè)滑動(dòng)驗(yàn)證碼

為漢中等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及漢中網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都網(wǎng)站建設(shè)、做網(wǎng)站、漢中網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!

做網(wǎng)絡(luò)爬蟲(chóng)的同學(xué)肯定見(jiàn)過(guò)各種各樣的驗(yàn)證碼,比較高級(jí)的有滑動(dòng)、點(diǎn)選等樣式,看起來(lái)好像挺復(fù)雜的,但實(shí)際上它們的核心原理還是還是很清晰的,本文章大致說(shuō)明下這些驗(yàn)證碼的原理以及帶大家實(shí)現(xiàn)一個(gè)滑動(dòng)驗(yàn)證碼。

實(shí)際上這類驗(yàn)證碼的校驗(yàn)是分為兩個(gè)步驟的:

1.第一步就是前端的校驗(yàn)。一般來(lái)說(shuō),登錄注冊(cè)頁(yè)面在點(diǎn)擊提交的時(shí)候都會(huì)伴隨著一個(gè)表單提交,在表單提交的時(shí)候會(huì)有 JavaScript 事件的觸發(fā)。如果加入了驗(yàn)證碼,那么在表單提交的時(shí)候會(huì)多加一個(gè)額外的驗(yàn)證,判斷這個(gè)驗(yàn)證碼是否已經(jīng)成功完成了操作。如果沒(méi)有的話,那就直接取消表單的提交,然后順便提示說(shuō)”您的驗(yàn)證沒(méi)通過(guò),請(qǐng)重新驗(yàn)證“,諸如此類的話。所以這一步就能防范”君子“之為了。

2.第二步就是服務(wù)端的校驗(yàn)。意思就是說(shuō)表單提交之后,會(huì)有請(qǐng)求發(fā)送到服務(wù)器,這個(gè)請(qǐng)求中包含了很多數(shù)據(jù),比如用戶名、密碼,如果對(duì)接了驗(yàn)證碼的話,還會(huì)有額外的驗(yàn)證碼的值,或者更復(fù)雜的加密后的 Token 值,服務(wù)器會(huì)對(duì)發(fā)過(guò)來(lái)的信息進(jìn)行校驗(yàn),如果驗(yàn)證通過(guò),那么整個(gè)請(qǐng)求就成功了,返回正常的響應(yīng),否則返回錯(cuò)誤的響應(yīng)。所以如果想要通過(guò)程序來(lái)直接構(gòu)造表單提交的時(shí)候,服務(wù)端就可以做進(jìn)一步的校驗(yàn),由于提交的驗(yàn)證碼相關(guān)的信息都是和服務(wù)端的 Session 相關(guān)聯(lián)的,另外再加上一些 CSRF 等的校驗(yàn),所以這一步就能防范”小人“之為了。

上面就是驗(yàn)證碼校驗(yàn)的兩個(gè)階段,一般來(lái)說(shuō)為了安全性,在開(kāi)發(fā)一個(gè)網(wǎng)站時(shí)需要客戶端和服務(wù)端都加上校驗(yàn),這樣才能保證安全性。

本文章主要來(lái)介紹一下第一個(gè)階段,也就是前端校驗(yàn)的驗(yàn)證碼的實(shí)現(xiàn),下面來(lái)介紹一下拖動(dòng)驗(yàn)證碼的具體實(shí)現(xiàn)。

需求

那么前端完成一個(gè)合格的驗(yàn)證碼,究竟需要做成什么樣子呢?

1.首先驗(yàn)證碼有個(gè)大體的雛形,既然是拖動(dòng)驗(yàn)證碼,那就要拖動(dòng)塊和目標(biāo)塊,我們需要把拖動(dòng)塊拖動(dòng)到目標(biāo)塊上就算校驗(yàn)成功。

2.驗(yàn)證碼的一個(gè)功能就是來(lái)規(guī)避機(jī)器的自動(dòng)操作,所以我們需要通過(guò)軌跡來(lái)判斷這個(gè)拖動(dòng)過(guò)程是真實(shí)的人還是機(jī)器,因此我們需要記錄拖動(dòng)的路徑,路徑經(jīng)過(guò)計(jì)算之后可以發(fā)送到后端進(jìn)行進(jìn)一步的分類,比如對(duì)接深度學(xué)習(xí)模型來(lái)分類拖動(dòng)軌跡是否是人。

以上就是驗(yàn)證碼的兩個(gè)基本要求,所以我們這里就來(lái)實(shí)現(xiàn)一下看看。

結(jié)果

這里就先給大家看看結(jié)果吧:

Python爬蟲(chóng)教程:200行代碼實(shí)現(xiàn)一個(gè)滑動(dòng)驗(yàn)證碼

拖動(dòng)驗(yàn)證碼示例

可以看到圖中有一個(gè)初始滑塊,有一個(gè)目標(biāo)滑塊,如果把初始滑塊拖動(dòng)到目標(biāo)滑塊上才能校驗(yàn)成功,然后下方再打印拖動(dòng)的軌跡,包含它的 x、y 坐標(biāo)。

有了這些內(nèi)容之后,就可以放到表單里面進(jìn)行提交了,軌跡數(shù)據(jù)可以自行加密處理并校驗(yàn)來(lái)判斷其是否合法。

具體實(shí)現(xiàn)

下面就具體講解下這個(gè)是怎么實(shí)現(xiàn)的,實(shí)際上核心代碼只有 200 行,下面對(duì)整個(gè)核心流程進(jìn)行說(shuō)明。

既然 Vue 這么火,那我這里就用 Vue 來(lái)實(shí)現(xiàn)啦,具體的環(huán)境配置這里就不再贅述了,需要安裝的有:

Node.js:https://nodejs.org/en/

Vue-Cli:https://cli.vuejs.org/zh/

安裝完成之后便可以使用 vue 命令了,新建個(gè)項(xiàng)目:

vue create drag-captcha

然后找一張不錯(cuò)的風(fēng)景圖,放到 public 目錄下,后面我們會(huì)引用它。

另外這里需要一個(gè)核心的包叫做 vue-drag-drop,其 GitHub 地址為:https://github.com/cameronhimself/vue-drag-drop,在目錄下使用此命令安裝:

npm install --save vue-drag-drop

安裝好了之后我們就可以利用它來(lái)實(shí)現(xiàn)驗(yàn)證碼了。

首先 vue-drag-drop 提供了兩個(gè)組件,一個(gè)叫做 Drag,一個(gè)叫做 Drop。前者是被拖動(dòng)對(duì)象,后者是放置目標(biāo),我們利用這兩個(gè)組件構(gòu)建兩個(gè)滑塊,將 Drag 滑塊拖動(dòng)到 Drop 滑塊上就成功了。因此,我們要做的僅僅是把它們兩個(gè)聲明出來(lái)并添加幾個(gè)檢測(cè)方法就好了,至于拖動(dòng)的功能,vue-drag-drop 這個(gè)組件已經(jīng)給我們封裝好了。

這里我們就直接在 App.vue 里面修改內(nèi)容就好了,在 <template> 里面先聲明一下兩個(gè)組件:

<template>
 <div id="app">
 <div id="wrapper" :style="wrapperStyle">
 <drop class="drop" id="target"
 :class="{ 'over': state.over }"
 @dragover="onDragOver"
 @dragleave="onDragLeave"
 :style="targetStyle">
 </drop>
 <drag class="drag" id="source"
 :transfer-data="true"
 @dragstart="onDragStart"
 @dragend="onDragEnd"
 @drag="onDrag" v-if="!state.dragged"
 :style="sourceStyle">
 <div slot="image" id="float" :style="sourceStyle">
 </div>
 </drag>
 </div>
 </div>
</template>

很清晰了,一個(gè) <drop> 和一個(gè) <drag> 組件,里面綁定了一些屬性,下面對(duì)這兩個(gè)組件的常用屬性作一下說(shuō)明。

Drop

對(duì)于 Drop 組件來(lái)說(shuō),它是一個(gè)被放置的對(duì)象,被拖動(dòng)滑塊會(huì)放到這個(gè) Drop 滑塊上,這就代表拖動(dòng)成功了。它有兩個(gè)主要的事件需要監(jiān)聽(tīng),一個(gè)叫做 dragover,一個(gè)叫做 dragleave,分別用來(lái)監(jiān)聽(tīng) Drag 對(duì)象拖上和拖開(kāi)的事件。

在這里,分別對(duì)兩個(gè)事件設(shè)置了 onDragOver 和 onDragLeave 的回調(diào)函數(shù),當(dāng) Drag 對(duì)象放到 Drop 對(duì)象上面的時(shí)候,就會(huì)觸發(fā) onDragOver 對(duì)象,當(dāng)拖開(kāi)的時(shí)候就會(huì)觸發(fā) onDragLeave 事件。

那這樣的話我們只需要一個(gè)全局變量來(lái)記錄是否已經(jīng)將滑塊拖動(dòng)到目標(biāo)位置即可,比如可以定一個(gè)全局變量 state,我們用 over 屬性來(lái)代表是否拖動(dòng)到目標(biāo)位置。

因此 onDragOver 和 onDragLeave 事件可以這么實(shí)現(xiàn):

onDragOver() {
 this.state.over = true
},
onDragLeave() {
 this.state.over = false
}

Drag

對(duì)于 Drag 組件來(lái)說(shuō),它是一個(gè)被拖動(dòng)的對(duì)象,我們需要將這個(gè) Drag 滑塊拖動(dòng)到 Drop 滑塊上,就代表拖動(dòng)成功了。它有三個(gè)主要的時(shí)間需要監(jiān)聽(tīng):dragstart、drag、dragend,分別代表拖動(dòng)開(kāi)始、拖動(dòng)中、拖動(dòng)結(jié)束三個(gè)事件,我們這里也分別設(shè)置了三個(gè)回調(diào)方法 onDragStart、onDrag、onDragEnd。

對(duì)于 onDragStart 方法來(lái)說(shuō),應(yīng)該怎么實(shí)現(xiàn)呢?這里應(yīng)該處理剛拖動(dòng)的一瞬間的動(dòng)作,由于我們需要記錄拖動(dòng)的軌跡,所以聲明一個(gè) trace 全局變量來(lái)保存軌跡信息,onDragStart 要做的就是初始化 trace 對(duì)象為空,另外記錄一下初始的拖動(dòng)位置,以便后續(xù)計(jì)算拖動(dòng)路徑,所以可以實(shí)現(xiàn)如下:

onDragStart(data, event) {
 this.init = {
 x: event.offsetX,
 y: event.offsetY,
 }
 this.trace = []
}

對(duì)于 onDrag 方法來(lái)說(shuō),就是處理拖動(dòng)過(guò)程中的一系列拖動(dòng)動(dòng)作,這里其實(shí)就是計(jì)算當(dāng)前拖動(dòng)的偏移位置,然后把它保存到 trace 變量里面,所以可以實(shí)現(xiàn)如下:

onDrag(data, event) {
 let offsetX = event.offsetX - this.init.x
 let offsetY = event.offsetY - this.init.y
 this.trace.push({
 x: offsetX,
 y: offsetY,
 })
}

對(duì)于 onDragEnd 方法來(lái)說(shuō),其實(shí)就是檢測(cè)最后的結(jié)果了,剛才我們用 state 變量里面的 over 屬性來(lái)代表是否拖動(dòng)到目標(biāo)位置上,這里我們也定義了另外的 dragged 屬性來(lái)代表是否已經(jīng)拖動(dòng)完成,dragging 屬性來(lái)代表是否正在拖動(dòng),所以整個(gè)方法的邏輯上是檢測(cè) over 屬性,然后對(duì) dragging、dragged 屬性做賦值,然后做一些相應(yīng)的提示,實(shí)現(xiàn)如下:

onDragEnd() {
 if (this.state.over) {
 this.state.dragging = false
 this.state.dragged = true
 this.$message.success('拖動(dòng)成功')
 }
 else {
 this.state.dragging = false
 this.state.dragged = false
 this.$message.error('拖動(dòng)失敗')
 }
 this.state.over = false
 }

OK 了,以上便是主要的邏輯實(shí)現(xiàn),這樣我們就可以完成拖動(dòng)滑塊的定義以及拖動(dòng)的監(jiān)聽(tīng)了。

接下來(lái)就是一些樣式上的問(wèn)題了,對(duì)于圖片的呈現(xiàn),這里直接使用 CSS 的 background-image 樣式來(lái)設(shè)置的,如果想顯示圖片的某一個(gè)范圍,那就用 background-position 來(lái)設(shè)置,這是幾個(gè)核心的要點(diǎn)。

好,這里的樣式設(shè)置其實(shí)也可以用 JavaScript 來(lái)實(shí)現(xiàn),我們把它們定義為一些計(jì)算屬性:

wrapperStyle() {
 return {
 width: this.size.width + 'px',
 height: this.size.height + 'px',
 backgroundImage: 'url(' + this.image + ')',
 backgroundSize: 'cover'
 }
},
targetStyle() {
 return {
 left: this.block.x + 'px',
 top: this.block.y + 'px'
 }
},
sourceStyle() {
 return {
 backgroundImage: 'url(' + this.image + ')',
 backgroundSize: this.size.width + 'px ' + this.size.height + 'px',
 backgroundPosition: -this.block.x + 'px ' + -this.block.y + 'px'
 }
}

另外這里還有一個(gè)值得注意的地方,就是 Drag 組件的 slot 部分:

<div slot="image" id="float" :style="sourceStyle"></div>

這部分定義了在拖動(dòng)過(guò)程中隨鼠標(biāo)移動(dòng)的圖片樣式,這里也和 Drag 滑塊一樣定義了一樣的樣式,這樣在拖動(dòng)的過(guò)程中,就會(huì)顯示一個(gè)和 Drag 滑塊一樣的滑塊隨鼠標(biāo)移動(dòng)。

最后,就是拖拽完成之后,將滑動(dòng)軌跡輸出出來(lái),這里我就直接呈現(xiàn)在頁(yè)面上了,<template> 區(qū)域加入如下定義即可:

<div>
 <p v-if="state.dragged" id="trace">
 拖動(dòng)軌跡:{{ trace }}
 </p>
</div>

好,以上就是一些核心代碼的介紹,還有一些細(xì)節(jié)的問(wèn)題可以完善下,比如滑塊隨機(jī)初始化位置,以及拖動(dòng)樣式設(shè)置。

最后再看一遍效果:

Python爬蟲(chóng)教程:200行代碼實(shí)現(xiàn)一個(gè)滑動(dòng)驗(yàn)證碼

拖動(dòng)驗(yàn)證碼示例

可以看到我們首先拖動(dòng)了 Drag 滑塊,當(dāng) Drag 滑塊拖動(dòng)到 Drop 滑塊上時(shí),出現(xiàn)了白色描邊,證明已經(jīng)拖動(dòng)到目標(biāo)位置了。然后松手之后,觸發(fā) onDragEnd 方法,呈現(xiàn)拖動(dòng)軌跡,整個(gè)驗(yàn)證碼就驗(yàn)證成功了。

當(dāng)然這只是前端部分,如果在這個(gè)基礎(chǔ)上添加表單驗(yàn)證,然后再添加后端校驗(yàn),并加上軌跡識(shí)別,那可謂是一個(gè)完整的驗(yàn)證碼系統(tǒng)了,在這里就點(diǎn)到為止啦。

當(dāng)前名稱:Python爬蟲(chóng)教程:200行代碼實(shí)現(xiàn)一個(gè)滑動(dòng)驗(yàn)證碼
分享地址:http://bm7419.com/article40/gigiho.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、、網(wǎng)站導(dǎo)航、全網(wǎng)營(yíng)銷(xiāo)推廣、商城網(wǎng)站、搜索引擎優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)