作為一只爬蟲,如何科學有效地處理短信驗證碼?
點擊上方Python知識圈,設(shè)為星標
回復100獲取100題PDF
閱讀文本大概需要 5 分鐘
之前我們了解了一些驗證碼的處理流程,比如圖形驗證碼、滑塊驗證碼、點選驗證碼等等,但是這些驗證碼都有一種共同的特點,那就是這些驗證碼的處理流程通常只需要在 PC 上完成即可,比如圖形驗證碼如果在 PC 上出現(xiàn),那么在 PC 上直接驗證通過就好了,所有的識別、驗證輸入的流程都是在 PC 上完成的。
但還有一種驗證碼和此種情況不同,那就是手機驗證碼,比如 PC 上需要輸入手機號,然后短信驗證碼需要發(fā)到手機上,然后再在 PC 上把收到的驗證碼輸入即可通過驗證。
那遇到這種情況,我們?nèi)绾尾拍軐⑦@個流程給自動化呢?
驗證碼收發(fā)
通常來說,我們的自動化腳本會運行在 PC 上,比如打開一個網(wǎng)頁,然后模擬輸入手機號,然后點擊獲取驗證碼,接下來就需要輸入驗證碼了。打開頁面,輸入手機號、點擊獲取驗證碼等流程我們可以非常容易地實現(xiàn)自動化,但是驗證碼被發(fā)送到手機上了,我們怎么能把它轉(zhuǎn)到 PC 上呢?
為了自動化整個驗證碼收發(fā)的流程,這時候我們想要完成的就是——當手機收到一條短信的時候,它能夠自動將短信轉(zhuǎn)發(fā)到某處,比如一臺遠程服務器上或者直接發(fā)到 PC 上,在 PC 上我們可以通過一些方法再把短信獲取下來并提取驗證碼的內(nèi)容,然后自動化填充驗證碼即可。
那這里關(guān)鍵的部分其實就是怎樣完成這兩個步驟:
如何監(jiān)聽手機收到了短信 如何將手機短信轉(zhuǎn)發(fā)到想要的位置
這兩個步驟缺一不可,而且都需要在手機上完成。
解決思路自然很簡單了,我們以 Android 手機為例,如果有 Android 開發(fā)經(jīng)驗的話,其實這兩個功能實現(xiàn)起來還是蠻簡單的。
“注意:這里我們僅僅簡單介紹基本的思路,不會完全詳細展開介紹具體的代碼實現(xiàn),感興趣的話可以自行嘗試。
”
首先如何監(jiān)聽手機收到了短信呢?
在 Android 開發(fā)中,整體就分為三個必要環(huán)節(jié):
注冊讀取短信的權(quán)限:在一個 Android App 中,讀取短信是需要特定的權(quán)限的,所以我們需要在 Andriod App 的 AndroidManifest.xml 中將讀取短信的權(quán)限配置好,比如接收短信的權(quán)限配置如下:
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>注冊廣播事件:Android 有一個基本組件叫做 BroadcastReceiver,也就是廣播接收者的意思,我們可以用它來監(jiān)聽來自系統(tǒng)的各種事件廣播,比如系統(tǒng)電量不足的廣播、系統(tǒng)來電的廣播,當然系統(tǒng)收到短信的廣播也就不在話下了。所以這就類似我們注冊一個監(jiān)聽器,用來監(jiān)聽系統(tǒng)收到短信的事件。
比如這里我們可以同樣在 AndroidManifest.xml 里面注冊一個 BroadcastReceiver,叫做 SmsReciver:
<receiver android:name=".receive.SmsReciver">
<intent-filter android:priority="999">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>實現(xiàn)短信廣播接收:這里就需要我們真正實現(xiàn)短信接收的邏輯了,這里只需要實現(xiàn)一個 SmsReceiver 類來繼承一個 BroadcastReceiver 然后實現(xiàn)其 onReceive 方法即可,其中 intent 參數(shù)里面便包含了我們想要的短信息內(nèi)容,實現(xiàn)如下:
public class SmsReciver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
SmsMessage msg = null;
if (null != bundle) {
Object[] smsObj = (Object[]) bundle.get("pdus");
for (Object object : smsObj) {
msg = SmsMessage.createFromPdu((byte[]) object);
Log.e("短信號碼", "" + msg.getOriginatingAddress());
Log.e("短信內(nèi)容", "" + msg.getDisplayMessageBody());
Log.e("短信時間", "" + msg.getTimestampMillis());
}
}
}
如此一來,我們便實現(xiàn)了短信的接收。
短信收到之后,發(fā)送自然也就很簡單了,比如服務器提供一個 API,我們通過請求該 API 即可實現(xiàn)數(shù)據(jù)的發(fā)送,這個通過 Android 的一些 HTTP 請求庫就可以實現(xiàn),比如 OkHttp 等構(gòu)造一個 HTTP 請求即可,這里就不再贅述了。
不過總的來說,整個流程下來其實還需要花費一些開發(fā)成本的,對于如此常用的功能,有沒有現(xiàn)成的解決方案呢?自然是有的。我們可以借助于于一些開源實現(xiàn),我們就沒必要重復造輪子了。
這里我們就介紹一個開源軟件,叫做 SmsForwarder,中文翻譯過來叫做短信轉(zhuǎn)發(fā)器,其 GitHub 倉庫地址為:https://github.com/pppscn/SmsForwarder。
它的基本流程架構(gòu)圖如下:
架構(gòu)圖非常清晰,SmsForwarder 可以監(jiān)聽監(jiān)聽收到短信的事件,獲取到短信的來源號碼、接受卡槽、短信內(nèi)容、接收時間等內(nèi)容,然后將其通過一定的規(guī)則轉(zhuǎn)發(fā)出去,支持轉(zhuǎn)發(fā)到郵箱、微信群機器人、企業(yè)微信、Telegram 機器人、Webhook 等。
比如我們可以配置類似這樣的規(guī)則,如圖所示:
比如當手機號符合一定的規(guī)則就轉(zhuǎn)發(fā)到 QQ 郵箱,比如內(nèi)容包含“報警”就轉(zhuǎn)發(fā)到阿里企業(yè)郵箱,比如內(nèi)容開頭是“測試”就發(fā)動給叫做 TSMS 的 Webhook。
其中QQ郵箱、阿里企業(yè)郵箱都是我們已經(jīng)配置好的發(fā)送方,都屬于郵箱類型,TSMS 也是一種發(fā)送方,屬于 Webhook 類型,如圖所示:
我們也可以點擊添加發(fā)送方按鈕來添加對應的發(fā)送方,比如添加郵箱的發(fā)送方,我們可以設(shè)置 SMTP 配置下發(fā)件郵箱、SMTP 服務器、SMTP 端口、授權(quán)密碼等內(nèi)容:
設(shè)置 Webhook 我們可以選擇是 GET 還是 POST 請求,然后填入對應的 URL、密鑰等內(nèi)容:
設(shè)置轉(zhuǎn)發(fā)規(guī)則頁面如圖所示:
比如這里我們可以選擇匹配卡槽、匹配的字段、匹配的模式,還可以配置正則來設(shè)置匹配的值,這里就配置了尾號是 4566 的手機號來執(zhí)行一定的發(fā)送操作,收到的短信會發(fā)送到釘釘這個發(fā)送方。
實戰(zhàn)演示
比如這里我們來嘗試下,這里我們用 Flask 寫一個 API,實現(xiàn)如下:
from flask import Flask, request, jsonify
from loguru import logger
app = Flask(__name__)
@app.route('/sms', methods=['POST'])
def receive():
sms_content = request.form.get('content')
logger.debug(f'received {sms_content}')
# parse content and save to db or mq
return jsonify(status='success')
if __name__ == '__main__':
app.run(debug=True)
代碼很簡單,這里設(shè)置了一個路由,接收 POST 請求,然后讀取了 Request 表單的內(nèi)容,其中 content 就是短信的詳情內(nèi)容,然后將其打印出來。
我們將代碼保存為 server.py,然后將其運行起來:
python3 server.py
運行結(jié)果輸出如下:
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 269-657-055
為了方便測試,我們可以用 Ngrok 將該服務暴露到公網(wǎng):
ngrok http 5000
“注意:Ngrok 可以方便地將任何非公網(wǎng)的服務暴露到公網(wǎng)訪問,并配置特定的臨時二級域名,但一個域名有時長限制,所以通常僅供測試使用。試用前請先安裝 Ngrok,具體可以參考 https://ngrok.com/。
”
運行之后,可以看到輸入結(jié)果如下:
Session Status online
Session Expires 1 hour, 59 minutes
Update update available (version 2.3.40, Ctrl-U to update)
Version 2.3.35
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://1259539cb974.ngrok.io -> http://localhost:5000
Forwarding https://1259539cb974.ngrok.io -> http://localhost:5000
Connections ttl opn rt1 rt5 p50 p90
9 0 0.00 0.00 0.00 0.00
這里我們可以看到 Ngrok 為我們配置了一個公網(wǎng)地址,比如訪問 https://1259539cb974.ngrok.io 即相當于訪問了我們本地的 http://localhost:5000 服務,這樣手機上只需要配置這個地址即可將數(shù)據(jù)發(fā)送到 PC 了。
接下來我們手機上打開 SmsForder,添加一個 Webhook 類型的發(fā)送方,配置如下:
這里 Server 的地址我們就直接設(shè)置了剛才 Ngrok 提供的公網(wǎng)地址了,記得 URL 路徑后面加上 sms。
接著我們添加一個轉(zhuǎn)發(fā)規(guī)則:
這里我們設(shè)置了內(nèi)容匹配規(guī)則,比如匹配到內(nèi)容開頭為測試的時候,那就將短信內(nèi)容轉(zhuǎn)發(fā)到 Webhook 這個發(fā)送方,即發(fā)送到我們剛剛搭建的 Flask 服務器上。
OK,配置完成之后,然后我們給該手機嘗試發(fā)送一個驗證碼,內(nèi)容如下:
測試驗證碼593722,一分鐘有效。
這時候就可以發(fā)現(xiàn)剛才的 Flask 服務器接收結(jié)果是這樣的:
received +8617xxxxxxxx
測試驗證碼593722,一分鐘有效。
SIM2_China Unicom_
2021-03-27 18:47:54
SM-G9860
可以看到剛才驗證碼的內(nèi)容就成功由手機發(fā)送到 PC 了,接著我們便可以對此消息進行解析和處理,然后存入數(shù)據(jù)庫或者消息隊列即可。爬蟲一端監(jiān)聽消息隊列或者數(shù)據(jù)庫改動即可將其填寫并進行一些模擬登錄操作了,該步驟就不再贅述了。
批量收發(fā)
當然以上只針對于一部手機的情況,如果我們有大量的手機和手機卡,我們可以實現(xiàn)手機的群控處理,比如統(tǒng)一安裝短信接收軟件,統(tǒng)一配置相同的轉(zhuǎn)發(fā)規(guī)則,從而實現(xiàn)大量手機號驗證碼的接收和處理。
比如一個群控系統(tǒng)就是這樣的:
卡池
當然還有更專業(yè)的解決方案,比如有專業(yè)的手機卡池,配合以專業(yè)的軟件設(shè)備實現(xiàn)短信的監(jiān)聽。
比如如下的設(shè)備支持插 128 張 SIM 卡,就可以實現(xiàn)同時監(jiān)聽 128 個手機號的驗證碼,如圖所示:
具體的技術(shù)這里不再闡述,詳細可以自行查詢相關(guān)的設(shè)備供應商。
接碼平臺
當然如上的方案成本還是比較高的,而且這些方案其實已經(jīng)不限于簡單接收短信驗證碼了,比如手機群控系統(tǒng)一般都會做手機群控爬蟲,而卡池也可以用來做 4G/5G 蜂窩代理,如果僅僅做短信收發(fā)是可以的,但未免有些浪費了。
如果我們不想耗費過多成本想實現(xiàn)短信驗證碼的自動化,還有一種方案就是接碼平臺,其基本思路是這樣的:
平臺會維護大量的手機號,并可能開放一些 API 或者提供網(wǎng)頁供我們調(diào)用來獲取手機號和查看短信的內(nèi)容。 我們調(diào)用 API 或者爬取網(wǎng)頁獲取手機號,然后在對應的站點輸入該手機號來獲取驗證碼。 通過調(diào)用 API 或者爬取網(wǎng)頁獲取對應手機號短信的內(nèi)容,并交由爬蟲處理。
具體的操作步驟這里就不再詳細闡述了,這里簡單列幾個接碼平臺:
番薯云:https://guanfangdiping.com/ 云際云短信:https://yunjisms.xyz/ 接碼號:https://jiemahao.com/ KaKa 接碼:http://www.kakasms.com/
由于接碼平臺管控比較嚴格,所以可能隨時不可用,請自行搜集對應的平臺進行使用。
往期推薦 01 02 03
↓點擊閱讀原文查看pk哥原創(chuàng)視頻
我就知道你“在看” 










