最近在看怎麼繞過圖形驗證碼,雖然有思路,可是有點吃力,估計還要折騰幾天,內心就想吐槽:驗證碼真難搞的;
這不,既然如今還沒搞定驗證碼,那要不看看驗證碼是怎麼生成的?原理是怎麼處理的?
因而乎就有了此篇,寫的不是很好,求各大神指教下;
php
前幾天原本也想本身搞個網站,就去了解下備案是什麼鬼,而後就找到這麼一個網站:
http://icp.alexa.cn/index.phphtml
用來查詢備案的,這裏面也有驗證碼,那就用這個網站先玩玩吧; python
對了,這裏的驗證碼指的是圖形驗證碼;web
正常的流程:
驗證碼於服務器端生成,發送給客戶端,並以圖像格式顯示。
客戶端提交所顯示的驗證碼,客戶端接收並進行比較,若比對失敗則不能實現登陸或註冊,反之成功後跳轉相應界面;
api
若是真這麼簡單,是否是用窮舉的方式就能破解了?
瀏覽器
有web基礎的人可能會知道,每一個瀏覽器都會有cookie,是做爲此次回話的惟一標示;
服務器
防止有同窗不知道,先簡單介紹下cookie:
cookie
1. 什麼是Cookie,它的用途是什麼?
Cookies是一些存儲在用戶電腦上的小文件。
它是被設計用來保存一些站點的用戶數據,這樣可以讓服務器爲這樣的用戶定製內容,後者頁面代碼可以獲取到Cookie值而後發送給服務器。
好比Cookie中存儲了所在地理位置,之後每次進入地圖就默認定位到改地點便可。app
2. Cookie是何時生成的,完整的生成、傳遞和使用過程是怎麼樣的?
寫數據到Cookie中一般是在一個頁面被加載的時候,好比提交按鈕被按下,後臺處理完請求跳轉到相應頁面後會把Cookie值帶回來;
以下是一個例子:dom
大體瞭解下cookie,不至於那麼不清不楚;那就繼續拉;
通常來講,每次訪問網址,瀏覽器都會把cookie發送給服務器,而驗證碼就是和這個cookie綁定在一塊兒的;
舉個例子:
那服務器怎麼區分A和B?那就是用cookie;
cookie是標示惟一身份的,好比有些網站,登陸一次後會自動登陸,可是若是清除了cookie,就沒法自動登陸了,並且這cookie是個別人不同的;
說到這裏,服務器後臺生成驗證碼的流程就很容易理解了:
那,怎麼生成一個圖片驗證碼?
from PIL import Image,ImageDraw,ImageFont
#PIL是python的圖片庫模塊
import random
#隨機函數
width = 80
height = 40
font = ImageFont.truetype('C:\\Windows\\Fonts\\STFANGSO.ttf', 28)
#選擇字體
image = Image.new("RGB",(width,height),(120,10,200))
#新建一個Image,背景色是黑色(000),若是須要別的顏色,本身修改便可;圖片大小就是開始定義的80X40
draw = ImageDraw.Draw(image)
#建立一個能夠在給定圖像上繪圖的對象
for t in range(4):
#4是表明幾位,須要須要4位數字的驗證碼,這裏輸入4,須要10位,就10
draw.text((20*t,10), repr(random.randint(0, 9)), font=font, fill=(255, 255, 255))
#random.randint(0, 9),隨機數,0-9
#第一個參數表明位置,第二個表明內容,第三方表明字體,第四個表明字體顏色
image.show()
#顯示圖片
複製代碼
效果圖:
驗證碼就這樣生成啦~
回到一開始的網站:http://icp.alexa.cn/index.php
打開後發現,網頁自動就顯示驗證碼了,有辦法獲取到這個驗證碼嗎?F12刷新一波試試
有一個這樣的請求,點擊後的確就是驗證碼的圖片了;
連接以下:
http://www.alexa.cn/api/icp/vcode?host=hcainfo&flag=f419510445e39e61cc32a7efd7552ed1&R=0.37766116804135375
從連接分析,有3個參數:
嗯,一臉懵逼,看不懂,先無論,咱們來測試下,看看這3個參數哪一個是必須的;
怎麼測試?簡單,直接copy上面的url,在瀏覽器打開,而後一個個參數刪除,如:
還能夠多試試排列組合,最終得出一個結論:host=gxcainfo是必須的,flag跟R不是必須的,空或者沒有參數,都不影響獲取驗證碼;
可是,能獲取到驗證碼,不表明該驗證碼是可用的,由於若是沒有與某些相似cookie的東西綁定在一塊兒的話,那它自己就只是圖片而已,沒特殊含義,也不具有驗證功能;
那host的值呢?嘗試了一下,把host的值改爲其餘亂七八糟的,也同樣獲取不到驗證碼,這裏面啥狀況;
把網頁刷新,每次刷新,host的值都在變化,好比ahcainfo、gxcainfo、ecainfo,若是不刷新網頁,host的值則一直不變;
經過上面3個host的值,發現一點疑問,都是8個字母,並且後面六位都是cainfo,只有前面兩個在變;ah\gx,給人感受就是安徽跟廣西?可是ec想不出,怎麼感受,有點像省份的意思?
親自試了下,修改爲gd,hn也能獲取到驗證碼,莫非真是省份?那ec是啥??
這裏繼續猜就沒意義了,但可知的是:
1)沒有host這個值就獲取不到驗證碼;
2)及時有host,值不對也是獲取不到驗證碼;
3)那是否是說明,驗證碼是跟這個值綁定的?
url參數就到這裏了,接下來請求頭吧~
沒太特別,直接把整個請求頭copy過來用就好了:
import requests
from PIL import Image
import io
getCode_url = "http://www.alexa.cn/api/icp/vcode?host=hcainfo&flag=f419510445e39e61cc32a7efd7552ed1&R=0.37766116804135375"
header = {
"Referer":"http://icp.alexa.cn/",
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"
}
response = requests.get(getCode_url,headers=header).content
image = Image.open(io.BytesIO(response))
image.show()
複製代碼
這上面的代碼,好像沒什麼特別,應該不須要說明的;
運行的結果就是:
總體的代碼:
import requests
from PIL import Image
import io
def getCode(url):
print("獲取驗證碼")
getCode_url = "http://www.alexa.cn/api/icp/vcode?host=jlcainfo&flag=61684048f21350aa2767b82315a0f487&R=0.5917477648057996"
header = {
"Referer":"http://icp.alexa.cn/",
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"
}
response = requests.get(getCode_url,headers=header).content
image = Image.open(io.BytesIO(response))
print("獲取驗證碼成功")
image.show()
def checkcode(url,code):
print("開始檢查驗證碼")
checkcode_url = "http://www.alexa.cn/home/index/query?token=1a63a83b2xwDdXlEmmIldi-Cx729izemOE54BDjY8jnT-JCvU3Atg0W1gCrBVbMSs-O&flag=61684048f21350aa2767b82315a0f487&host=jlcainfo&flag&domain=qq.com&type=icp&type=icp&vcode="+code
header = {
"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"Accept-Encoding":"gzip, deflate",
"Accept-Language":"zh-CN,zh;q=0.9",
"Connection":"keep-alive",
"Cookie":"SL_GWPT_Show_Hide_tmp=1; SL_wptGlobTipTmp=1; exi_query_history=nseyfqfp4SgNKMagNO-DctlkEDqameDvLLDbwUIuYCiHNkoLJPniHTUs0RIAq5jNEZ8ojjeoe8W8y1Df6vuMiy8r-H37690i99d0LZ3iyTWMVmstIOcGqb5H-DY1k2Gn3FNdj02TwpVtlca1b1lrvrdSfE-HbUGwP3Lfex0D9Hzeu48-N",
"Host":"www.alexa.cn",
"Referer":"http://icp.alexa.cn",
"Upgrade-Insecure-Requests":"1",
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"
}
response = requests.get(checkcode_url,headers=header)
print(response.content)
print(response.status_code)
if __name__ == "__main__":
getCode("qq.com")
code = input("請輸入驗證碼:")
checkcode("qq.com",code)
複製代碼
原本是想弄個,自動拉取驗證碼圖片,手動輸入後自動拉取結果,可是執行的時候,仍是被網站識別出來了,想了好久還沒想明白,算了留下了一個爛攤子吧~
本文主要介紹了驗證碼是怎麼生成的,原本也想結合作個機器識別的,但在調試過程,依然被網站識別出來了,折騰半天,目前無果,先棄療,後面想到緣由再來更新吧~
謝謝你們~