如何編寫(xiě)程序?qū)崿F(xiàn)自動(dòng)進(jìn)行上海汽車牌照拍牌

在上海的人都知道,上海的汽車牌照是多么的難以獲得,現(xiàn)在只能通過(guò)參加網(wǎng)上拍賣的方式獲得,下面來(lái)探討一下如何通過(guò)編寫(xiě)程序的方式進(jìn)行自動(dòng)拍賣,減少人為的失誤因素。當(dāng)然了,由于神奇的驗(yàn)證碼每個(gè)月都會(huì)變化,期望通過(guò)程序確保百分之百能夠拍得,是不太可能的,我們這里僅僅是探討讓程序來(lái)代替人工的方式來(lái)輔助并盡量提高一些拍中率。

需求分析

首先,要研究一下上海車牌網(wǎng)上拍賣的流程和規(guī)則。

拍賣流程規(guī)則:

1.使用事先獲得的賬號(hào)和密碼登陸拍賣網(wǎng)站。

2.10點(diǎn)半到11點(diǎn)之間為第一階段出價(jià),出價(jià)不能超過(guò)警示價(jià),當(dāng)然一般人都是直接輸入警示價(jià),輸入價(jià)格后點(diǎn)擊出價(jià)按鈕,彈出驗(yàn)證碼輸入窗口,根據(jù)驗(yàn)證碼提示信息輸入驗(yàn)證碼,點(diǎn)擊確定按鈕,完成出價(jià)。

3.11點(diǎn)到11點(diǎn)半之間為第二階段出價(jià),第二階段可以出價(jià)2次,每次出價(jià)的價(jià)格范圍不能超過(guò)當(dāng)前價(jià)格的增加300,輸入價(jià)格后點(diǎn)擊出價(jià)按鈕,彈出驗(yàn)證碼輸入窗口,根據(jù)驗(yàn)證碼提示信息輸入驗(yàn)證碼,點(diǎn)擊確定按鈕,完成出價(jià)。

來(lái)看一下競(jìng)拍的網(wǎng)頁(yè)是什么樣子的:


競(jìng)拍規(guī)律:

1.一般來(lái)說(shuō)第一階段出價(jià)沒(méi)有難度,關(guān)鍵在于11點(diǎn)29分40秒之后的出價(jià)。

2.出價(jià)過(guò)早,會(huì)被后面的更高出價(jià)擊敗,出價(jià)過(guò)晚,可能無(wú)法進(jìn)入競(jìng)價(jià)隊(duì)列,從而超時(shí)失敗。

3.一般的方法是伏擊法,也就是在29分40秒的時(shí)候增加700左右,到29分55秒之前,加入價(jià)格已經(jīng)增長(zhǎng)到范圍之內(nèi),則立即出價(jià),如果價(jià)格未能增長(zhǎng)到范圍之內(nèi),則最晚29分56秒必須出價(jià),否則可能超時(shí)。

需求分析:

第一步的網(wǎng)站登錄和第一階段的出價(jià),非常簡(jiǎn)單,也不會(huì)失誤,沒(méi)有必要采用程序。

重點(diǎn)在于第二階段的出價(jià),而且基本上只有一次出價(jià)機(jī)會(huì),所以我們只需要實(shí)現(xiàn)以下功能:

1.時(shí)間到達(dá)11點(diǎn)29分30秒的時(shí)候,通過(guò)程序自動(dòng)識(shí)別【目前最低可成交價(jià)】,例如80600。

2.根據(jù)最低成交價(jià),增加一個(gè)預(yù)估加價(jià)值,例如900,得到出價(jià)價(jià)格81500,填寫(xiě)到價(jià)格輸入框,點(diǎn)擊出價(jià)按鈕。

3.驗(yàn)證碼窗口彈出后,等待3秒鐘,讓驗(yàn)證碼出現(xiàn),截取驗(yàn)證碼部分屏幕形成圖片,將圖片中的驗(yàn)證碼進(jìn)行識(shí)別。

4.在驗(yàn)證碼輸入框中輸入驗(yàn)證碼,等待價(jià)格到達(dá)范圍,或者時(shí)間到達(dá)11點(diǎn)29分56秒,點(diǎn)擊確定按鈕。

其中最關(guān)鍵的是第3步識(shí)別驗(yàn)證碼部分,鑒于每個(gè)月的驗(yàn)證碼的樣式都會(huì)變化,期望完全采用程序來(lái)識(shí)別是有非常大的技術(shù)難度的,這里我們只討論采用變通的方式來(lái)實(shí)現(xiàn)“半自動(dòng)化”的程序識(shí)別。

程序設(shè)計(jì)思路

考慮到需要模擬人工操作,例如輸入數(shù)字,點(diǎn)擊按鈕,截取屏幕圖片,可以采用java類庫(kù) java.awt.Robot 來(lái)實(shí)現(xiàn)。

識(shí)別最低可成交價(jià),需要利用開(kāi)源的ocr工具包tesseract-ocr來(lái)實(shí)現(xiàn)。

識(shí)別驗(yàn)證碼,可以利用網(wǎng)上一些打碼平臺(tái)來(lái)實(shí)現(xiàn),原理是去網(wǎng)上找到這些專門(mén)進(jìn)行驗(yàn)證碼識(shí)別的平臺(tái),注冊(cè)登錄后,進(jìn)行充值,然后下載相應(yīng)的開(kāi)發(fā)工具包,然后利用工具包的類庫(kù)寫(xiě)調(diào)用代碼,將驗(yàn)證碼圖片通過(guò)網(wǎng)絡(luò)傳送到打碼平臺(tái),打碼平臺(tái)通過(guò)人工網(wǎng)絡(luò)識(shí)別之后,傳回驗(yàn)證碼字符串。

程序主流程如下:

程序每秒循環(huán)一次,判斷系統(tǒng)當(dāng)前時(shí)間是否到達(dá)11點(diǎn)29分30秒

如果到達(dá)時(shí)間,則開(kāi)始執(zhí)行以下動(dòng)作:

截取最低可成交價(jià)的數(shù)字區(qū)域范圍圖片,通過(guò)tesseract-ocr識(shí)別出價(jià)格數(shù)字

將價(jià)格數(shù)字增加一個(gè)預(yù)估加價(jià)值,得到出價(jià)價(jià)格數(shù)字

通過(guò)robot.mouseMove(x,y)將鼠標(biāo)移動(dòng)到價(jià)格輸入文本框范圍內(nèi)

通過(guò)robot.mousePress(InputEvent.BUTTON1_MASK)和robot.mouseRelease(InputEvent.BUTTON1_MASK)讓鼠標(biāo)點(diǎn)擊一次,讓輸入光標(biāo)出現(xiàn)在價(jià)格文本輸入框中

將價(jià)格數(shù)字分解為5個(gè)單獨(dú)的數(shù)字鍵,通過(guò)robot.keyPress(keycode)和robot.keyRelease(keycode)讓鍵盤(pán)輸入數(shù)字鍵

通過(guò)robot.mouseMove(x,y)將鼠標(biāo)移動(dòng)到出價(jià)按鈕范圍內(nèi)

通過(guò)robot.mousePress(InputEvent.BUTTON1_MASK)和robot.mouseRelease(InputEvent.BUTTON1_MASK)讓鼠標(biāo)點(diǎn)擊一次,完成出價(jià)動(dòng)作

通過(guò)robot.delay(seconds)等待3秒種,等待驗(yàn)證碼窗口加載完成

截取驗(yàn)證碼窗口顯示范圍圖片,調(diào)用打碼平臺(tái)接口,獲取驗(yàn)證碼字符串,可能需要10秒左右

通過(guò)robot.mouseMove(x,y)將鼠標(biāo)移動(dòng)到驗(yàn)證碼輸入文本框范圍內(nèi)

通過(guò)robot.mousePress(InputEvent.BUTTON1_MASK)和robot.mouseRelease(InputEvent.BUTTON1_MASK)讓鼠標(biāo)點(diǎn)擊一次,讓輸入光標(biāo)出現(xiàn)在驗(yàn)證碼文本輸入框中

將驗(yàn)證碼分解為4個(gè)單獨(dú)的數(shù)字鍵,通過(guò)robot.keyPress(keycode)和robot.keyRelease(keycode)讓鍵盤(pán)輸入驗(yàn)證碼

進(jìn)入一個(gè)循環(huán)程序,每秒循環(huán)一次,循環(huán)內(nèi)部進(jìn)行判斷:

截取最低可成交價(jià)的數(shù)字區(qū)域范圍圖片,通過(guò)tesseract-ocr識(shí)別出價(jià)格數(shù)字

假如該價(jià)格已經(jīng)大于等于前面輸入的出價(jià)價(jià)格,則點(diǎn)擊確定按鈕

或者假如系統(tǒng)當(dāng)前時(shí)間已經(jīng)大于等于11點(diǎn)29分56秒,則點(diǎn)擊確定按鈕

點(diǎn)擊確定按鈕:通過(guò)robot.mouseMove(x,y)將鼠標(biāo)移動(dòng)到確定按鈕范圍內(nèi),然后通過(guò)通過(guò)robot.mousePress(InputEvent.BUTTON1_MASK)和robot.mouseRelease(InputEvent.BUTTON1_MASK)讓鼠標(biāo)點(diǎn)擊一次,完成確定動(dòng)作

程序?qū)崿F(xiàn)

由于程序較長(zhǎng),限于篇幅,下面只列出一些關(guān)鍵性的代碼。

截取最低可成交價(jià)的數(shù)字區(qū)域范圍圖片,通過(guò)tesseract-ocr識(shí)別出價(jià)格數(shù)字:


這是調(diào)用函數(shù),參數(shù)是最低可成交價(jià)的數(shù)字區(qū)域范圍,左上角在屏幕的坐標(biāo),以及區(qū)域的寬度和高度


截取屏幕圖片,采用java.awt.Robot.createScreenCapture方法來(lái)實(shí)現(xiàn)

截取的圖片使用BMPWriter類庫(kù)來(lái)實(shí)現(xiàn),這個(gè)就不貼了,大家可以搜索BufferedImage如何寫(xiě)到文件中

然后調(diào)用tesseract.exe工具包命令行來(lái)識(shí)別圖片中的價(jià)格數(shù)字

至于如何使用tesseract-ocr這個(gè)就不做具體說(shuō)明了,其中的難點(diǎn)在于字庫(kù)訓(xùn)練,也就是讓識(shí)別程序先要進(jìn)行訓(xùn)練,掌握這里的圖片里面文字的特征,從而能夠準(zhǔn)確識(shí)別出圖片里面的數(shù)字文字。

具體訓(xùn)練方法和使用方法,可以參考這個(gè)網(wǎng)頁(yè)教程:http://blog.csdn.net/yasi_xi/article/details/8763385

等待識(shí)別完成之后,從結(jié)果文件中讀取出最低可成交價(jià)的數(shù)字。

移動(dòng)鼠標(biāo)和點(diǎn)擊鼠標(biāo):


輸入價(jià)格:


點(diǎn)擊出價(jià)按鈕:


識(shí)別驗(yàn)證碼:

截取驗(yàn)證碼區(qū)域部分圖片就不做說(shuō)明了,和之前的截取最低可成交價(jià)的范圍圖片的方式一樣,只是區(qū)域范圍不同而已。

下面僅以某打碼平臺(tái)為例說(shuō)明,注意不同的打碼平臺(tái)調(diào)用接口的方式可能不一樣:


其實(shí)還可以同時(shí)調(diào)用多個(gè)打碼平臺(tái),看誰(shuí)先返回驗(yàn)證碼結(jié)果就采用誰(shuí),可以減少獲取驗(yàn)證碼的花費(fèi)時(shí)間。

輸入驗(yàn)證碼:


點(diǎn)擊確定按鈕:


測(cè)試驗(yàn)證

由于正式的拍賣網(wǎng)站只有到每個(gè)月拍賣的那一天才真正開(kāi)放訪問(wèn),所以平時(shí)是無(wú)法進(jìn)行測(cè)試的,不過(guò)我們可以到利用一個(gè)模擬網(wǎng)站進(jìn)行測(cè)試,www.51hupai.com 訪問(wèn)這個(gè)網(wǎng)站,點(diǎn)擊最上方菜單【51《全真模擬》】,可以模擬運(yùn)行,從而可以啟動(dòng)我們編寫(xiě)的程序進(jìn)行測(cè)試。

可以將一些常量參數(shù)做成配置txt文件,讓程序運(yùn)行的時(shí)候讀取這些參數(shù),這樣可以讓程序更靈活,不用頻繁修改編譯代碼。

調(diào)整參數(shù)中的啟動(dòng)時(shí)間,以及坐標(biāo)值,高度寬度值,加價(jià)值等等,來(lái)適應(yīng)模擬網(wǎng)站,從而可以完成測(cè)試。

這樣,到正式拍賣的時(shí)候,只需要調(diào)整參數(shù)就可以完成自動(dòng)化競(jìng)拍了。

發(fā)散探討

由于打碼平臺(tái)背后的實(shí)質(zhì)也是通過(guò)人工網(wǎng)絡(luò)進(jìn)行識(shí)別,因此所需的時(shí)間基本都在十多秒,因此不能算是完全的程序化,也就無(wú)法利用機(jī)器的性能進(jìn)行瞬間識(shí)別,在現(xiàn)有的競(jìng)拍規(guī)則下,沒(méi)有非常高的實(shí)時(shí)性,是不能實(shí)現(xiàn)完全百分之百的拍中率的。

也許,未來(lái)等待圖像識(shí)別技術(shù)發(fā)展到更先進(jìn),或許可以采用其它更快更高識(shí)別率的平臺(tái)來(lái)進(jìn)行驗(yàn)證碼的識(shí)別。

就算可以實(shí)現(xiàn)這一點(diǎn),但基于競(jìng)拍規(guī)則的時(shí)間窗口極短效應(yīng),可能也無(wú)法實(shí)現(xiàn)最終的目標(biāo),但是還可以采用創(chuàng)建多個(gè)虛擬機(jī)的方式,部署多個(gè)賬號(hào)同時(shí)競(jìng)拍,將預(yù)估價(jià)格進(jìn)行區(qū)間分段進(jìn)行伏擊的辦法,也是可以提高拍中率的。

道高一尺,魔高一丈,技術(shù)這條路真的永無(wú)止境。所以,我們還是祈求運(yùn)氣再好一點(diǎn)吧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,881評(píng)論 18 139
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,200評(píng)論 4 61
  • 黃老之學(xué),即黃帝、老子學(xué)說(shuō)之統(tǒng)稱。在1973年以前的兩千年之間,人們確定其中一半指的是《老子》,而另一半“黃帝”具...
    解放者_(dá)知乎閱讀 2,120評(píng)論 0 4
  • 不一樣的我
    尉遲金銘閱讀 147評(píng)論 0 0
  • 「 最近的某個(gè)時(shí)刻,我好像突然明白了那種感受:人生終于可以打破年幼時(shí)生活里表面的相似,開(kāi)始進(jìn)入另一種狀態(tài),這種狀態(tài)...
    山楂阿妹閱讀 573評(píng)論 0 3