難度: ★☆☆☆☆ 1星
這個網站的注冊頁面:
https://beijing.tuitui99.com/zhuce.html
有一個神奇的滑塊驗證碼:

看上去是一個滑塊驗證碼,長得跟極驗差不多,令人望而卻步,然而當我們打開控制台觀察其網絡請求的時候,則發現其實是假的...
這是刷新驗證碼圖片的請求:

可以看到圖片大致分為三個部分,最上面是帶缺口的背景圖,中間是滑塊圖片,最下面是不帶缺口的背景圖,這就意味着如果我們把最上面帶缺口的背景圖和最下面不帶缺口的圖片做一個比對,它們第一個不同的像素所在的列就是上面圖片中缺口所在的列。
再看這個刷新驗證碼請求的參數,這是個get請求,只有一個t參數,這個t 參數看上去像是從0到1之間的一個隨機數,在刷新驗證碼的時候一般都會帶上一個隨機數以讓驗證碼圖片的緩存失效,這個參數我們可以先忽略它,如果等下發現不行再回來搞它。
然后就是提交驗證碼請求,我們先故意搞幾個驗證失敗的,看下網絡請求是怎樣的:

請求是個get請求,只有一個tn_r參數,參數的值是一個數字,看上去像是缺口所在的列的x坐標,而響應內容似乎表示驗證不通過的時候就返回“error”:

如果是滑塊驗證成功的:

則請求的響應是這樣的:

OK,接下來就是編碼實現了:
#!/usr/bin/env python3
# encoding: utf-8
"""
@author: CC11001100
"""
import io
import logging
import numpy
import requests
from PIL import Image
LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"
logging.basicConfig(level=logging.INFO, format=LOG_FORMAT)
session = requests.session()
def run():
url = "https://beijing.tuitui99.com/tncode.html"
response = session.get(url)
logging.info(f"獲取驗證碼結果: {response.content}")
image = Image.open(io.BytesIO(response.content))
matrix = numpy.asarray(image)
x = find_lack_location(matrix)
check_code(x)
def find_lack_location(image_matrix):
"""
在驗證碼圖片中尋找
:param image_matrix:
:return:
"""
# 從左往右柵格掃描,尋找第一個不相等的列的x坐標
for x in range(len(image_matrix[0])):
# 高度為450px,存儲了三張等高圖片,則每張圖片的高度為150
for offset in range(0, 150):
image_1_y = 0 + offset
image_2_y = 300 + offset
# 如果發現這一列的像素點有不同的,則認為是滑塊出現了
if ((image_matrix[image_1_y][x] != image_matrix[image_2_y][x]).any()):
logging.info(f"尋找到缺塊所在的列: {x}")
return x
def check_code(x):
url = f"https://beijing.tuitui99.com/checkcode.html?tn_r={x}"
response = session.get(url)
logging.info(f"提交結果: {response.text}")
if __name__ == "__main__":
run()
運行結果:
![6[4] 6[4]](/image/aHR0cHM6Ly9pbWcyMDIwLmNuYmxvZ3MuY29tL2Jsb2cvNzg0OTI0LzIwMjAxMS83ODQ5MjQtMjAyMDExMjUxODEzMTAxMjgtMjA5MDAzOTkwOS5qcGc=.png)
倉庫:
請注意爬蟲文章具有時效性,本文寫於2020-11-4日。
