教你用python擼走《百萬英雄》《衝頂大會》獎金。

莊文達發表於2018-01-11

百萬英雄類答題遊戲的程式設計師開啟方式

最近這類答題app比較火,我的同事wangtonghe為開源社群貢獻了他的python程式碼。以下文章為他的思路,我只做了部分整理髮佈於掘金社群,分享給大家。


  • 起因

看了《程式設計師如何玩轉《衝頂大會》?》大受啟發,不過弱點很多,需要使用付費的OCR介面、再open到百度搜尋答案,我們等待載入並且尋找答案的時候,已經錯失了好的機會,剛好前幾天研究了下微信跳一跳的輔助,正好可以用上。

-初步思路

思路很明確,把答案截圖pull過來,通過PYTHON OCR 庫進行識別成文字後再放到百度搜尋。匹配出現率最頻繁的詞語,記過幾番嘗試後,一些容易搜尋的問題還是是可以搜尋大部分答案的。

  • 嘗試

目前它是手動的,也就是說每次答案出現,手動執行指令碼返回答案。同樣由於個別題目原因(如某個詞有多少筆畫)雖然不是百分之百的成功率,但是一般都能進入決賽+一張復活卡基本妥妥‘吃雞’,下面是吃雞截圖:

教你用python擼走《百萬英雄》《衝頂大會》獎金。
教你用python擼走《百萬英雄》《衝頂大會》獎金。
教你用python擼走《百萬英雄》《衝頂大會》獎金。
教你用python擼走《百萬英雄》《衝頂大會》獎金。

  • 技術棧

實現語言python,用到的類庫如下:

  1. PIL
  2. pytesseract(圖片識別庫)
  3. BeautifulSoup(頁面解析)

文字識別引擎需單獨安裝,參見Python人工智慧之圖片識別,Python3一行程式碼實現圖片文字識別以及mac上文字識別 Tesseract-OCR for mac

主體程式碼如下:

import os
from PIL import Image
import pytesseract
from urllib.request import urlopen
import urllib.request
from bs4 import BeautifulSoup

DEFAULT_WIDTH = 720
DEFAULT_HEIGHT = 1280


def main():
    # 720*1280解析度座標
    left_top_x = 30
    left_top_y = 200
    right_bottom_x = 680
    right_bottom_y = 380

    # 1. 截圖
    os.system('adb shell screencap -p /sdcard/answer.png')
    os.system('adb pull /sdcard/answer.png answer.png')

    # 2. 擷取題目並文字識別
    image = Image.open('answer.png')
    crop_img = image.crop((left_top_x, left_top_y, right_bottom_x, right_bottom_y))
    crop_img.save('crop.png')
    text = pytesseract.image_to_string(crop_img, lang='chi_sim')
    print(text)

    # 3. 去百度知道搜尋
    text = text[2:]  # 把題號去掉
    # text = '一畝地大約是多少平米'
    wd = urllib.request.quote(text)
    url = 'https://zhidao.baidu.com/search?ct=17&pn=0&tn=ikaslist&rn=10&fr=wwwt&word={}'.format(
        wd)
    print(url)
    result = urlopen(url)
    body = BeautifulSoup(result.read(), 'html5lib')
    good_result_div = body.find(class_='list-header').find('dd')
    second_result_div = body.find(class_='list-inner').find(class_='list')
    if good_result_div is not None:
        good_result = good_result_div.get_text()
        print(good_result.strip())

    if second_result_div is not None:
        second_result = second_result_div.find('dl').find('dd').get_text()
        print(second_result.strip())


if __name__ == '__main__':
    main()

複製程式碼

文字識別需經訓練,訓練越多結果越準。

我把程式碼放到github上了,可圍觀hq-answer-assist

  • 結語

要想實現更智慧化,有個思路是不停的截圖(1秒一次),一旦截到答題頁(可以用答題頁的色差來做),做文字識別後百度,將百度後的結果與選項做比較,哪個出現次數最多哪個就是最佳答案,這裡可以加個判斷,如果特別確定直接模擬點選事件選答案,不確定就手工。

有同學提到分析請求,也是個思路,後續可以研究。

歡迎探討其他更好的實現方式。

相關文章