本文目錄一覽:
- 1、python模擬登錄知乎,captcha是手工輸入,為什麼也提示captcha錯了
- 2、如何利用Python做簡單的驗證碼識別
- 3、django-simple-captcha安裝到了什麼位置
- 4、如何用Python+人工識別處理知乎的倒立漢字驗證碼
python模擬登錄知乎,captcha是手工輸入,為什麼也提示captcha錯了
具體是卡在這裡:
1是為了圖方便,下載圖片用了urllib.urlretrieve, 可是cookie時綁定到urllib2上的,所以獲取cookie失敗
2是發現登錄知乎必須對login/email接口提交兩次,第一次提交即使captcha對了也不行,必須兩次,太坑了
3就算是登錄成功了,再去拉主頁,還是提示沒登錄,原來get 主頁也要設置headers,不然還是說沒登錄上
修改如下:
#!/usr/bin/python
import urllib
import urllib2
import cookielib
import re
import time
hosturl = ”
posturl = ”
captcha_pre = ”
#set cookie
cj = cookielib.CookieJar()
cookie_support = urllib2.HTTPCookieProcessor(cj)
opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler)
urllib2.install_opener(opener)
#get xsrf
h = urllib2.urlopen(hosturl)
html = h.read()
xsrf_str = r’input type=”hidden” name=”_xsrf” value=”(.*?)”/’
xsrf = re.findall(xsrf_str, html)[0]
print xsrf
#get captcha
def get_captcha():
captchaurl = captcha_pre + str(int(time.time() * 1000))
print captchaurl
data = urllib2.urlopen(captchaurl).read()
f = file(‘captcha.jpg’,”wb”)
f.write(data)
f.close()
captcha = raw_input(‘captcha is: ‘)
print captcha
return captcha
#post data
def post_data(captcha,xsrf):
headers = {‘User-Agent’ : ‘Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1’,
‘Referer’ : ‘http:’}
postData = {‘_xsrf’ : xsrf,
‘password’ : ‘yyy’,
‘captcha’ : captcha,
’email’ : ‘xxx’,
‘remember_me’ : ‘true’,
}
#request
postData = urllib.urlencode(postData)
print postData
request = urllib2.Request(posturl, postData, headers)
response = urllib2.urlopen(request)
text = response.read()
return text
#post it
captcha=get_captcha()
print captcha
text=post_data(captcha,xsrf)
print text
#post again
captcha=get_captcha()
text=post_data(captcha,xsrf)
print text
headers = {‘User-Agent’ : ‘Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1’,
‘Referer’ : ‘http:’}
request = urllib2.Request(url=”, headers=headers)
response = urllib2.urlopen(request)
print response.read()
如何利用Python做簡單的驗證碼識別
1 摘要
驗證碼是目前互聯網上非常常見也是非常重要的一個事物,充當著很多系統的 防火牆 功能,但是隨時OCR技術的發展,驗證碼暴露出來的安全問題也越來越嚴峻。本文介紹了一套字符驗證碼識別的完整流程,對於驗證碼安全和OCR識別技術都有一定的借鑒意義。
然後經過了一年的時間,筆者又研究和get到了一種更強大的基於CNN卷積神經網絡的直接端到端的驗證識別技術(文章不是我的,然後我把源碼整理了下,介紹和源碼在這裡面):
基於python語言的tensorflow的‘端到端’的字符型驗證碼識別源碼整理(github源碼分享)
2 關鍵詞
關鍵詞:安全,字符圖片,驗證碼識別,OCR,Python,SVM,PIL
3 免責聲明
本文研究所用素材來自於某舊Web框架的網站 完全對外公開 的公共圖片資源。
本文只做了該網站對外公開的公共圖片資源進行了爬取, 並未越權 做任何多餘操作。
本文在書寫相關報告的時候已經 隱去 漏洞網站的身份信息。
本文作者 已經通知 網站相關人員此系統漏洞,並積極向新系統轉移。
本報告的主要目的也僅是用於 OCR交流學習 和引起大家對 驗證安全的警覺 。
4 引言
關於驗證碼的非技術部分的介紹,可以參考以前寫的一篇科普類的文章:
互聯網安全防火牆(1)–網絡驗證碼的科普
裡面對驗證碼的種類,使用場景,作用,主要的識別技術等等進行了講解,然而並沒有涉及到任何技術內容。本章內容則作為它的 技術補充 來給出相應的識別的解決方案,讓讀者對驗證碼的功能及安全性問題有更深刻的認識。
5 基本工具
要達到本文的目的,只需要簡單的編程知識即可,因為現在的機器學習領域的蓬勃發展,已經有很多封裝好的開源解決方案來進行機器學習。普通程序員已經不需要了解複雜的數學原理,即可以實現對這些工具的應用了。
主要開發環境:
python3.5
python SDK版本
PIL
圖片處理庫
libsvm
開源的svm機器學習庫
關於環境的安裝,不是本文的重點,故略去。
6 基本流程
一般情況下,對於字符型驗證碼的識別流程如下:
準備原始圖片素材
圖片預處理
圖片字符切割
圖片尺寸歸一化
圖片字符標記
字符圖片特徵提取
生成特徵和標記對應的訓練數據集
訓練特徵標記數據生成識別模型
使用識別模型預測新的未知圖片集
達到根據“圖片”就能返回識別正確的字符集的目標
7 素材準備
7.1 素材選擇
由於本文是以初級的學習研究目的為主,要求 “有代表性,但又不會太難” ,所以就直接在網上找個比較有代表性的簡單的字符型驗證碼(感覺像在找漏洞一樣)。
最後在一個比較舊的網站(估計是幾十年前的網站框架)找到了這個驗證碼圖片。
原始圖:
放大清晰圖:
此圖片能滿足要求,仔細觀察其具有如下特點。
有利識別的特點 :
由純阿拉伯數字組成
字數為4位
字符排列有規律
字體是用的統一字體
以上就是本文所說的此驗證碼簡單的重要原因,後續代碼實現中會用到
不利識別的特點 :
圖片背景有干擾噪點
這雖然是不利特點,但是這個干擾門檻太低,只需要簡單的方法就可以除去
7.2 素材獲取
由於在做訓練的時候,需要大量的素材,所以不可能用手工的方式一張張在瀏覽器中保存,故建議寫個自動化下載的程序。
主要步驟如下:
通過瀏覽器的抓包功能獲取隨機圖片驗證碼生成接口
批量請求接口以獲取圖片
將圖片保存到本地磁盤目錄中
這些都是一些IT基本技能,本文就不再詳細展開了。
關於網絡請求和文件保存的代碼,如下:
def downloads_pic(**kwargs):
pic_name = kwargs.get(‘pic_name’, None)
url = ‘httand_code_captcha/’
res = requests.get(url, stream=True)
with open(pic_path + pic_name+’.bmp’, ‘wb’) as f: for chunk in res.iter_content(chunk_size=1024): if chunk: # filter out keep-alive new chunks f.write(chunk)
f.flush()
f.close()
循環執行N次,即可保存N張驗證素材了。
下面是收集的幾十張素材庫保存到本地文件的效果圖:
8 圖片預處理
雖然目前的機器學習算法已經相當先進了,但是為了減少後面訓練時的複雜度,同時增加識別率,很有必要對圖片進行預處理,使其對機器識別更友好。
針對以上原始素材的處理步驟如下:
讀取原始圖片素材
將彩色圖片二值化為黑白圖片
去除背景噪點
8.1 二值化圖片
主要步驟如下:
將RGB彩圖轉為灰度圖
將灰度圖按照設定閾值轉化為二值圖
image = Image.open(img_path)
imgry = image.convert(‘L’) # 轉化為灰度圖table = get_bin_table()
out = imgry.point(table, ‘1’)
上面引用到的二值函數的定義如下:
1234567891011121314 def get_bin_table(threshold=140): “”” 獲取灰度轉二值的映射table :param threshold: :return: “”” table = [] for i in range(256): if i threshold: table.append(0) else: table.append(1) return table
由PIL轉化後變成二值圖片:0表示黑色,1表示白色。二值化後帶噪點的 6937 的像素點輸出後如下圖:
1111000111111000111111100001111100000011
1110111011110111011111011110111100110111
1001110011110111101011011010101101110111
1101111111110110101111110101111111101111
1101000111110111001111110011111111101111
1100111011111000001111111001011111011111
1101110001111111101011010110111111011111
1101111011111111101111011110111111011111
1101111011110111001111011110111111011100
1110000111111000011101100001110111011111
如果你是近視眼,然後離屏幕遠一點,可以隱約看到 6937 的骨架了。
8.2 去除噪點
在轉化為二值圖片後,就需要清除噪點。本文選擇的素材比較簡單,大部分噪點也是最簡單的那種 孤立點,所以可以通過檢測這些孤立點就能移除大量的噪點。
關於如何去除更複雜的噪點甚至干擾線和色塊,有比較成熟的算法: 洪水填充法 Flood Fill ,後面有興趣的時間可以繼續研究一下。
本文為了問題簡單化,乾脆就用一種簡單的自己想的 簡單辦法 來解決掉這個問題:
對某個 黑點 周邊的九宮格裡面的黑色點計數
如果黑色點少於2個則證明此點為孤立點,然後得到所有的孤立點
對所有孤立點一次批量移除。
下面將詳細介紹關於具體的算法原理。
將所有的像素點如下圖分成三大類
頂點A
非頂點的邊界點B
內部點C
種類點示意圖如下:
其中:
A類點計算周邊相鄰的3個點(如上圖紅框所示)
B類點計算周邊相鄰的5個點(如上圖紅框所示)
C類點計算周邊相鄰的8個點(如上圖紅框所示)
當然,由於基準點在計算區域的方向不同,A類點和B類點還會有細分:
A類點繼續細分為:左上,左下,右上,右下
B類點繼續細分為:上,下,左,右
C類點不用細分
然後這些細分點將成為後續坐標獲取的準則。
主要算法的python實現如下:
def sum_9_region(img, x, y): “””
9鄰域框,以當前點為中心的田字框,黑點個數
:param x:
:param y:
:return: “””
# todo 判斷圖片的長寬度下限
cur_pixel = img.getpixel((x, y)) # 當前像素點的值
width = img.width
height = img.height if cur_pixel == 1: # 如果當前點為白色區域,則不統計鄰域值
return 0 if y == 0: # 第一行
if x == 0: # 左上頂點,4鄰域
# 中心點旁邊3個點
sum = cur_pixel \ + img.getpixel((x, y + 1)) \ + img.getpixel((x + 1, y)) \ + img.getpixel((x + 1, y + 1)) return 4 – sum elif x == width – 1: # 右上頂點
sum = cur_pixel \ + img.getpixel((x, y + 1)) \ + img.getpixel((x – 1, y)) \ + img.getpixel((x – 1, y + 1)) return 4 – sum else: # 最上非頂點,6鄰域
sum = img.getpixel((x – 1, y)) \ + img.getpixel((x – 1, y + 1)) \ + cur_pixel \ + img.getpixel((x, y + 1)) \ + img.getpixel((x + 1, y)) \ + img.getpixel((x + 1, y + 1)) return 6 – sum elif y == height – 1: # 最下面一行
if x == 0: # 左下頂點
# 中心點旁邊3個點
sum = cur_pixel \ + img.getpixel((x + 1, y)) \ + img.getpixel((x + 1, y – 1)) \ + img.getpixel((x, y – 1)) return 4 – sum elif x == width – 1: # 右下頂點
sum = cur_pixel \ + img.getpixel((x, y – 1)) \ + img.getpixel((x – 1, y)) \ + img.getpixel((x – 1, y – 1)) return 4 – sum else: # 最下非頂點,6鄰域
sum = cur_pixel \ + img.getpixel((x – 1, y)) \ + img.getpixel((x + 1, y)) \ + img.getpixel((x, y – 1)) \ + img.getpixel((x – 1, y – 1)) \ + img.getpixel((x + 1, y – 1)) return 6 – sum else: # y不在邊界
if x == 0: # 左邊非頂點
sum = img.getpixel((x, y – 1)) \ + cur_pixel \ + img.getpixel((x, y + 1)) \ + img.getpixel((x + 1, y – 1)) \ + img.getpixel((x + 1, y)) \ + img.getpixel((x + 1, y + 1)) return 6 – sum elif x == width – 1: # 右邊非頂點
# print(‘%s,%s’ % (x, y))
sum = img.getpixel((x, y – 1)) \ + cur_pixel \ + img.getpixel((x, y + 1)) \ + img.getpixel((x – 1, y – 1)) \ + img.getpixel((x – 1, y)) \ + img.getpixel((x – 1, y + 1)) return 6 – sum else: # 具備9領域條件的
sum = img.getpixel((x – 1, y – 1)) \ + img.getpixel((x – 1, y)) \ + img.getpixel((x – 1, y + 1)) \ + img.getpixel((x, y – 1)) \ + cur_pixel \ + img.getpixel((x, y + 1)) \ + img.getpixel((x + 1, y – 1)) \ + img.getpixel((x + 1, y)) \ + img.getpixel((x + 1, y + 1)) return 9 – sum
Tips:這個地方是相當考驗人的細心和耐心程度了,這個地方的工作量還是蠻大的,花了半個晚上的時間才完成的。
計算好每個像素點的周邊像素黑點(注意:PIL轉化的圖片黑點的值為0)個數後,只需要篩選出個數為 1或者2 的點的坐標即為 孤立點 。這個判斷方法可能不太準確,但是基本上能夠滿足本文的需求了。
經過預處理後的圖片如下所示:
對比文章開頭的原始圖片,那些 孤立點 都被移除掉,相對比較 乾淨 的驗證碼圖片已經生成。
9 圖片字符切割
由於字符型 驗證碼圖片 本質就可以看着是由一系列的 單個字符圖片 拼接而成,為了簡化研究對象,我們也可以將這些圖片分解到 原子級 ,即: 只包含單個字符的圖片。
於是,我們的研究對象由 “N種字串的組合對象” 變成 “10種阿拉伯數字” 的處理,極大的簡化和減少了處理對象。
9.1 分割算法
現實生活中的字符驗證碼的產生千奇百怪,有各種扭曲和變形。關於字符分割的算法,也沒有很通用的方式。這個算法也是需要開發人員仔細研究所要識別的字符圖片的特點來制定的。
當然,本文所選的研究對象盡量簡化了這個步驟的難度,下文將慢慢進行介紹。
使用圖像編輯軟件(PhoneShop或者其它)打開驗證碼圖片,放大到像素級別,觀察其它一些參數特點:
可以得到如下參數:
整個圖片尺寸是 40*10
單個字符尺寸是 6*10
左右字符和左右邊緣相距2個像素
字符上下緊挨邊緣(即相距0個像素)
這樣就可以很容易就定位到每個字符在整個圖片中佔據的像素區域,然後就可以進行分割了,具體代碼如下:
def get_crop_imgs(img): “””
按照圖片的特點,進行切割,這個要根據具體的驗證碼來進行工作. # 見原理圖
:param img:
:return: “””
child_img_list = [] for i in range(4):
x = 2 + i * (6 + 4) # 見原理圖
y = 0
child_img = img.crop((x, y, x + 6, y + 10))
child_img_list.append(child_img) return child_img_list
然後就能得到被切割的 原子級 的圖片元素了:
9.2 內容小結
基於本部分的內容的討論,相信大家已經了解到了,如果驗證碼的干擾(扭曲,噪點,干擾色塊,干擾線……)做得不夠強的話,可以得到如下兩個結論:
4位字符和40000位字符的驗證碼區別不大
純字母
不區分大小寫。分類數為26
區分大小寫。分類數為52
純數字。分類數為10
數字和區分大小寫的字母組合。分類數為62
純數字 和 數字及字母組合 的驗證碼區別不大
在沒有形成 指數級或者幾何級 的難度增加,而只是 線性有限級 增加計算量時,意義不太大。
10 尺寸歸一
本文所選擇的研究對象本身尺寸就是統一狀態:6*10的規格,所以此部分不需要額外處理。但是一些進行了扭曲和縮放的驗證碼,則此部分也會是一個圖像處理的難點。
11 模型訓練步驟
在前面的環節,已經完成了對單個圖片的處理和分割了。後面就開始進行 識別模型 的訓練了。
整個訓練過程如下:
大量完成預處理並切割到原子級的圖片素材準備
對素材圖片進行人為分類,即:打標籤
定義單張圖片的識別特徵
使用SVM訓練模型對打了標籤的特徵文件進行訓練,得到模型文件
12 素材準備
本文在訓練階段重新下載了同一模式的4數字的驗證圖片總計:3000張。然後對這3000張圖片進行處理和切割,得到12000張原子級圖片。
在這12000張圖片中刪除一些會影響訓練和識別的強幹擾的干擾素材,切割後的效果圖如下:
13 素材標記
由於本文使用的這種識別方法中,機器在最開始是不具備任何 數字的觀念的。所以需要人為的對素材進行標識,告訴 機器什麼樣的圖片的內容是 1……。
這個過程叫做 “標記”。
具體打標籤的方法是:
為0~9每個數字建立一個目錄,目錄名稱為相應數字(相當於標籤)
人為判定 圖片內容,並將圖片拖到指定數字目錄中
每個目錄中存放100張左右的素材
一般情況下,標記的素材越多,那麼訓練出的模型的分辨能力和預測能力越強。例如本文中,標記素材為十多張的時候,對新的測試圖片識別率基本為零,但是到達100張時,則可以達到近乎100%的識別率
14 特徵選擇
對於切割後的單個字符圖片,像素級放大圖如下:
從宏觀上看,不同的數字圖片的本質就是將黑色按照一定規則填充在相應的像素點上,所以這些特徵都是最後圍繞像素點進行。
字符圖片 寬6個像素,高10個像素 ,理論上可以最簡單粗暴地可以定義出60個特徵:60個像素點上面的像素值。但是顯然這樣高維度必然會造成過大的計算量,可以適當的降維。
通過查閱相應的文獻 [2],給出另外一種簡單粗暴的特徵定義:
每行上黑色像素的個數,可以得到10個特徵
每列上黑色像素的個數,可以得到6個特徵
最後得到16維的一組特徵,實現代碼如下:
def get_feature(img): “””
獲取指定圖片的特徵值,
1. 按照每排的像素點,高度為10,則有10個維度,然後為6列,總共16個維度
:param img_path:
:return:一個維度為10(高度)的列表 “””
width, height = img.size
pixel_cnt_list = []
height = 10 for y in range(height):
pix_cnt_x = 0 for x in range(width): if img.getpixel((x, y)) == 0: # 黑色點
pix_cnt_x += 1
pixel_cnt_list.append(pix_cnt_x) for x in range(width):
pix_cnt_y = 0 for y in range(height): if img.getpixel((x, y)) == 0: # 黑色點
pix_cnt_y += 1
pixel_cnt_list.append(pix_cnt_y) return pixel_cnt_list
然後就將圖片素材特徵化,按照 libSVM 指定的格式生成一組帶特徵值和標記值的向量文
django-simple-captcha安裝到了什麼位置
下載後python setup.py install進行安裝
將下載包解壓,將裡面的captcha包複製到項目目錄下,如myblog/captcha
settings.py里添加:
INSTALLED_APPS(‘captcha’,)
urls.py里添加:
url(r’^captcha/’, include(‘captcha.urls’)),
執行python manage.py syncdb生成所需數據庫表
在需要用到captcha的forms.py文件里的合適位置添加下面的代碼,增加驗證碼字段:
from captcha.fields import CaptchaField captcha=CaptchaField()
在處理表單提交的業務邏輯代碼塊里添加:
if form.is_valid(): human =
True三、與django的comments組件結合使用的方法(這裡目前我是沒有加到自己的項目裡面)
如果你的項目里的評論系統直接使用的django內置的comments庫,則comments庫與此驗證碼庫結合使用的方法如下:
執行前面的1至5步
在
Python27\Lib\site-packages\django\contrib\comments\forms.py文件中(windows環境下的路徑),在CommentDetailsForm類裡面添加驗證碼字段:
from captcha.fields import CaptchaField captcha= CaptchaField()
在Python27\Lib\site-packages\django\contrib\comments\views\comments.py文件中,在#
Otherwise create the comment這句下面添加:
human=True
修改表單模板:如果評論表單模板直接用的{{form}}則什麼都不用修改;如果是自己定製的表單模板,則可添加如下:
p label for=”id_captcha”驗證(必填):/label {{form.captcha}} /p
如何用Python+人工識別處理知乎的倒立漢字驗證碼
這給Python爬蟲的模擬登錄帶來了一定的難度,目前網絡上的相關資料針對的都是普通的“英文+數字”驗證碼,針對“倒立漢字”驗證碼的文章較少。而且大家普遍採用的是requests庫。經過幾天的研究,我採用urllib.request實現了模擬登陸知乎,現將代碼分享如下:
[python] view plain copy
# 登錄知乎,通過保存驗證圖片方式
import urllib.request
import urllib.parse
import time
import http.cookiejar
webUrl = “l”#不能寫因為不支持重定向
webheader = {
# ‘Accept’: ‘text/html, application/xhtml+xml, */*’,
# ‘Accept-Language’: ‘zh-CN’,
# ‘User-Agent’: ‘Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko’,
‘User-Agent’: ‘Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36’,
# ‘User-Agent’: ‘Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5’,
# ‘DNT’: ‘1’,
# ‘Connection’: ‘Keep-Alive’
}
postData = {
’email’: ‘在這裡寫你的賬號’,
‘captcha_type’: ‘cn’,
‘password’: ‘在這裡寫你的密碼’,
‘_xsrf’: ”,
‘captcha’: ”
}
localStorePath = “寫你想保存的驗證碼圖片的地址”
if __name__ == ‘__main__’:
#聲明一個CookieJar對象實例來保存cookie
cookie = http.cookiejar.CookieJar()
#創建opener
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)#建立opener對象,並添加頭信息
urllib.request.install_opener(opener)
captcha_url = ‘?r=%dtype=loginlang=cn’ % (time.time() * 1000)
# captcha_url = ‘/captcha.gif?r=%dtype=login’ % (time.time() * 1000)#這樣獲得的是“字母+數字驗證碼”
#這個獲取驗證碼圖片的方法是不行的!
# urllib.request.urlretrieve(captcha_url, localStorePath + ‘myCaptcha.gif’)
#用urlopen函數保存驗證圖片
req = urllib.request.Request(url=captcha_url,headers=webheader)
content = urllib.request.urlopen(req)
# content = opener.open(req)
captcha_name = ‘D:/Python學習/crawler_learning/知乎登錄專題研究/知乎驗證碼圖片/myNewCaptcha.gif’
content = content.read()
with open(captcha_name, ‘wb’) as f:
f.write(content)
postData[‘captcha’] = input(‘請輸入驗證碼’)
# postData[‘_xsrf’] = get_xsrf()
postData[‘_xsrf’] = ‘fa5ae712244bd4287e371801052003fc’
print(postData[‘_xsrf’])
#用urlopen函數傳送數據給服務器實現登錄
postData_encoded = urllib.parse.urlencode(postData).encode(‘utf-8’)
req = urllib.request.Request(url=webUrl,data=postData_encoded,headers=webheader)
webPage = urllib.request.urlopen(req)
# webPage = opener.open(req)
data = webPage.read().decode(‘utf-8’)
print(data)
with open(“D:/知乎服務器反饋的內容.txt”,mode=’w’,encoding=’utf-8′) as dataFile:
dataFile.write(data)
幾點思考:
1、首先需要明確如何獲得驗證碼圖片的地址,利用Fiddler抓包獲得的典型的驗證碼圖片的地址如下:
這個“r”代表的是什麼含義呢?經過查看知乎上的js代碼可以確定,這個r指的是毫秒級的時間戳。
2、以驗證碼圖片地址cn為例,不同時間訪問同一個驗證碼圖片地址,得到的驗證碼圖片是不同的,那麼知乎服務器是如何知道你獲取的是那張驗證碼呢?
我認為是通過sessionID,換句話說,知乎把某個驗證碼圖片給了你,同時知乎記錄下了你的sessionID和這個驗證碼的“正確答案”,這樣將來你輸入驗證碼給知乎後,知乎就能判斷你輸入的驗證碼是否正確了。
由於sessionID保存在cookie之中,所以Python模擬登陸的代碼必須使用cookie。
3、獲取驗證碼圖片的時候,我用的是content =urllib.request.urlopen (req)函數,經過我的驗證,用
urllib.request.urlretrieve函數是不行的,因為urlopen函數可以傳遞headers參數,而這一個參數必須有。
4、獲得了倒立漢字圖片以後,如何確定要傳遞給知乎的captcha是什麼呢?經過Fiddler抓包,
傳遞的參數類似於這樣:
{“img_size”:[200,44],”input_points”:[[43.44,22.44],[115.72,22.44]]}
經過分析和試驗確定:200指的是圖片長度,44指的是圖片高度,後面的input_points指的是打在倒立漢字上的點的坐標。由於每次出現7個漢字,這7個漢字的坐標是固定的,我全部進行捕獲:
{“img_size”:[200,44],”input_points”:[[12.95,14.969999999999998],[36.1,16.009999999999998],[57.16,24.44],[84.52,19.17],[108.72,28.64],[132.95,24.44],[151.89,23.380000000000002]]}
然後,問題就簡單了:將圖片保存在本地之後,打開圖片,確定哪幾個漢字倒立,比如說第2個和第6個,那就在上面選取出2和6的坐標輸入即可,即
{“img_size”:[200,44],”input_points”:[[36.1,16.009999999999998],[132.95,24.44]]}。
5、小竅門:以驗證碼圖片地址
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/248810.html