貓眼爬蟲三-終極篇:破解滑動驗證,動態字體加密

前面兩節我們對貓眼網站進行了爬取,中間,我們會遇到各種反爬蟲,包括滑動驗證和字體加密等等,今天,我們就對這些反爬蟲進行一一破解,實現貓眼網站的全信息爬取!

1、滑動驗證:滑動驗證類似於極驗證(滑塊驗證,電腦的B站登陸要滑動的哪個),但是原理不一樣,目前來說,12306的相關搶票的腳本已經實現了自動加載滑塊滑動,但大多數情況還得手動,在這裏也是。
破解流程:

1、先嚐試着獲取數據,如果遇到爬取鏈接與實際鏈接不一致,如下圖:
在這裏插入圖片描述
即爬取的鏈接和實際鏈接不一致時,尤其是出現了類似於:
https://verify.meituan.com/v2/web/general_page?action=spiderindefence&requestCode=350941fd3ea345bd99f8e17f7f99f2f5&platform=1000&adaptor=auto&succCallbackUrl=https%3A%2F%2Foptimus-mtsi.meituan.com%2Foptimus%2FverifyResult%3ForiginUrl%3Dhttp%253A%252F%252Fmaoyan.com%252Ffilms%252F224973
這樣的鏈接,那麼就是被反爬蟲了,不需要慌,只要點擊該鏈接,

在這裏插入圖片描述

人工拖動該滑塊,使之驗證成功,那麼ip就通過了驗證,後面就可以成功爬取了。如下圖:
在這裏插入圖片描述
下面是出現滑動驗證的操作示意gif
在這裏插入圖片描述上面,我們將滑動驗證說清楚了,下面我們開始對字體加密進行分析:點開貓眼電影的詳情,我們在 檢查 中發現:

在這裏插入圖片描述
他的評分人數,評分,票房等相關信息都是無法顯示的,在源代碼中也是類似,那麼,我們應該怎麼獲取相關的數據呢?百度相關的信息,我們發現:
在這裏插入圖片描述
他採用了一種字體加密方式,且是動態的,每次刷新,都要重新載入一種新的字體,如下圖:
在這裏插入圖片描述
因此,我們不能再採取網上的那種固定的識別文字的方式,必須採取動態識別方式!這裏,我們用到的是OCR本地文字識別,主要通過 tesseract 來識別保存在本地的數字符號。

ocr:光學字符識別)是指電子設備(例如掃描儀或數碼相機)檢查紙上打印的字符,通過檢測暗、亮的模式確定其形狀,然後用字符識別方法將形狀翻譯成計算機文字的過程

ocr識別流程:

1、先配置好tesseract的環境和訓練庫,導入相關的包。

​2、下載網頁的字體文件,保存在本地文件夾。

3、將本地的字體座標進行讀取,並轉化成黑白圖片。

4、進行ocr識別,並將結果進行轉化,將每個座標對應數字識別代碼,​如下圖
在這裏插入圖片描述
5、找到對應的識別代碼之後,我們就可以在源代碼中進行替換操作了:
將識別出來的數字與字體代碼進行轉換。
在這裏插入圖片描述
6、轉換成功後進行數據的獲取就可以了。
在這裏插入圖片描述
OCR識別的缺點:

1、對訓練庫的要求比較高,否則識別很容易出錯,不準確。

2、識別時間較長,時間花費較大。

但就目前來說,我的識別訓練庫的精度和速度都還可以。

知道了爬蟲步驟與方法,我們就可以編寫代碼了,代碼流程與前兩節類似,這裏主要講解一下怎麼把字體文件等轉化成圖片識別。

1、首先,導入下面這些庫:

import pytesseract
from PIL import Image
from fontTools.ttLib import TTFont
from matplotlib import pyplot as plt

在OCR識別之前,記得先下好字體文件,再進行後面操作。

2、導入字體文件,獲取到數字的座標表示區:

font = TTFont(woff_file)
font_name = font.getGlyphOrder()[2:]  #獲取到字符的uni碼

在這裏插入圖片描述

zb = [font['glyf'][i].coordinates for i in font_name

獲取數字的座標等等
獲取到每個字體的座標信息,後面我們就可以根據字體座標進行繪圖,並將字體編碼與具體數字對應上;部分代碼如下:

def deal_font(font):
font_name = font.getGlyphOrder()[2:]
zb = [font['glyf'][i].coordinates for i in font_name]
fig, ax = plt.subplots()
for index, one in enumerate(zb):
    x, y = [i[0] for i in one], [i[1] for i in one]
    plt.plot(x, y)
    x_n = [i + np.max(x) + 100 for i in x]
    plt.plot(x_n, y)
    plt.fill(x, y, 'black')
    plt.fill(x_n, y, 'black')
    # 去邊框
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.spines['bottom'].set_visible(False)
    ax.spines['left'].set_visible(False)
    # 去刻度
    plt.axis('off')
    plt.fill(x, y, 'black')
    plt.savefig('images/%s.png' % index)
    plt.close()
path = 'images/'
num = []
# 灰度、二值化
for one in os.listdir(path):
    img = Image.open(path + one)
    imgry = img.convert("L")
    threshold = 140
    table = []
    for i in range(256):
        if i < threshold:
            table.append(0)
        else:
            table.append(1)
    out = imgry.point(table, '1')
    out.save(path + one)
    text = pytesseract.image_to_string(out, lang="amt")
    num.append(text[0])
# 字名與數字
name_num = {font_name[i]: num[i] for i in range(len(font_name))}
return name_num

全部代碼在我的公衆號裏,回覆 貓眼 就可以獲取到,我的公衆號名字是:
python學習號
在這裏插入圖片描述
當然,也可以在這裏 下載 ,只是要c幣。

歡迎大家關注。一個python學習者,將其學到的分享出來。

發佈了11 篇原創文章 · 獲贊 1 · 訪問量 3346
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章