Upgrade to Pro — share decks privately, control downloads, hide ads and more …

業務改善の面白さ~毎日更新されるビジュアルコンテンツの差分を わかりやすくするためのプロトタイプを作るまで~

業務改善の面白さ~毎日更新されるビジュアルコンテンツの差分を わかりやすくするためのプロトタイプを作るまで~

PyCon JP
2022 2022/10/14

業務改善の面白さ
毎日更新されるビジュアルコンテンツの差分を
わかりやすくするためのプロトタイプを作るまで

Marina Nakagawa

October 13, 2022
Tweet

More Decks by Marina Nakagawa

Other Decks in Technology

Transcript

  1. 5

  2. 26

  3. 31

  4. 32

  5. 54 ͏·͍͔͘ͳ͔ͬͨϙΠϯτ2 ຊ౰ʹ࢖ͬͯ΋Β͑Δ͔࣮༻ੑͷݒ೦ - GitHubʹ͔͠௨஌͕͜ͳ͍ɻ - هऀʹ΋GitHubΞΧ΢ϯτ͕ඞཁ - ࠩ෼ΛݟΔ·Ͱͷ໿4ΫϦοΫͷนΛӽ͑Δ -

    Slack νϟϯωϧ,GitHubͷPR,reg-suit,reg-suitͷத ຊ౰ʹ਺ճΫϦοΫͯ͘͠ΕΔʁʁʁ Θ͟Θ͟ݟΔͷΊΜͲ͘͘͞ͳ͍ʁʁʁ
  6. 55 ͜͏ͳͬͨΒ͍͍ͳͱໝ૝ͯͨ͜͠ͱ Nikkei ———— ———— ———— ———— ௨஌νϟϯωϧ ௨஌bot 1Click

    ͲΜͳ৬छͰ΋ ͚ͩ͜͜ݟ͓͚ͯ͹͍͍ʂ ͱ͍͏ঢ়ଶΛ࡞Γ͍ͨ ———— ———— ————
  7. 56 ͜͏ͳͬͨΒ͍͍ͳͱໝ૝ͯͨ͜͠ͱ Nikkei ———— ———— ———— ———— ௨஌νϟϯωϧ ௨஌bot 1Click

    ͲΜͳ৬छͰ΋ ͚ͩ͜͜ݟ͓͚ͯ͹͍͍ʂ ঢ়ଶΛ࡞Γ͍ͨ ֬ೝ͢Δ΂͖Օॴ͕໌֬ʹʂ ࠷ऴతͳਓؒͷ൑அͷิॿʹͳΔʂ(͸ͣ)
  8. 64 SCREENSHOT_WIDTH_SIZE = 800 SCREENSHOT_HIGHT_SIZE = 12000 TARGET_URL = "https://vdata.nikkei.com/newsgraphics/coronavirus-japan-vaccine-

    status/" WAIT_TIME = 10 # ΢ΣϒυϥΠόʔͱΦϓγϣϯͷઃఆ options = webdriver.ChromeOptions() options.add_argument('--headless') options.add_argument('--incognito') options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') driver = webdriver.Chrome(ChromeDriverManager().install(), options=options) driver.get(TARGET_URL) driver.set_window_size(SCREENSHOT_WIDTH_SIZE, SCREENSHOT_HIGHT_SIZE) time.sleep(WAIT_TIME) driver.save_screenshot("test-reports/current_page_screenshot.png") ※ίʔυ͸Ұ෦ൈਮ
  9. 66 # S3ʹΞοϓϩʔυ import boto3 # S3ͷϑΝΠϧμ΢ϯϩʔυɺΞοϓϩʔυͷઃఆ client = boto3.client(

    's3', aws_access_key_id= {AWS ΞΫηεΩʔID}, aws_secret_access_key= {AWS γʔΫϨοτΩʔ}, ) client.download_file( '{S3໊}', '{S3ͷύε໊}/screenshot.png', 'test-reports/past_page_screenshot.png' ) ※ίʔυ͸Ұ෦ൈਮ
  10. 68 #=============================================== #ɹಉ͡αΠζʹͳΔΑ͏ʹԼʹۭനΛೖΕͯϦαΠζ #=============================================== color = (255, 255, 255) if

    img_current.shape[0] <= img_past.shape[0]: bottom = img_past.shape[0] - img_current.shape[0] img_current = cv2.copyMakeBorder(img_current, 0,bottom, 0, 0, cv2.BORDER_CONSTANT, value=color, ) else: bottom = img_current.shape[0] - img_past.shape[0] img_past = cv2.copyMakeBorder(img_past, 0, bottom, 0, 0, cv2.BORDER_CONSTANT, value=color, ) ※ίʔυ͸Ұ෦ൈਮ
  11. 72 #=============================================== # ը૾Λ҉ͯࠩ͘͠෼ϚεΫΛॏͶɺ # ࠩ෼ͷݕग़ͷ݁Ռ͕෼͔ΔΑ͏ʹग़ྗ͢Δ #=============================================== # ݱࡏͷεΫγϣΛগ͠҉͘͢Δ img_result

    = img_current // 4 # ϚεΫͰࠩ෼ͷ͋Δͱ͜Ζ͚ͩ྘ΛࡌͤΔ img_result[fgmask==255] = (0, 255, 0) cv2.imwrite('test-reports/result.png', img_result) ※ίʔυ͸Ұ෦ൈਮ
  12. 75 #============================= # ը૾ͷ߹੒(Slack౤ߘ༻) #============================= percentage_to_resize = 0.5 img_summary =

    cv2.hconcat([img_current, img_past, img_result]) img_summary = cv2.resize( img_summary , (int(img_summary.shape[1] * percentage_to_resize), int(img_summary.shape[0] * percentage_to_resize)) ) cv2.imwrite('test-reports/summary.png', img_summary) ※ίʔυ͸Ұ෦ൈਮ
  13. 81 #====================================================== # ࠩ෼͕͋Ε͹files uploadAPIͰSlackʹ௨஌ #====================================================== def postMessageWithFiles(message, fileList, channel):

    slack_client = slack_sdk.WebClient(token=SLACK_TOKEN) for file in fileList: upload = slack_client.files_upload(file=file, filename=file) message = message + ”<“ + upload['file']['permalink'] + "| >" outPut = slack_client.chat_postMessage( channel = channel, text = message ) #======================================================= # มߋΛݕ஌ͨ࣌͠ #======================================================= if np.array_equal(img_current, img_past): postMessageWithFiles( message = " `ίϩφ೔ຊϫΫνϯίϯςϯπͷࠩ෼Λݕ஌͠·ͨ͠ʂ”, fileList = ['test-reports/summary.png'], channel = "{௨஌͍ͨ͠νϟϯωϧ໊}", ) ※ίʔυ͸Ұ෦ൈਮ