tag:blogger.com,1999:blog-48774873207817679522024-03-19T16:40:48.637+08:00小狐狸事務所小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.comBlogger5290125tag:blogger.com,1999:blog-4877487320781767952.post-67150058591101301662024-03-18T15:35:00.008+08:002024-03-18T23:46:35.371+08:00Google Apps Script (GAS) 學習筆記 (三) : 使用者介面元件 (上)<div>本篇要來測試 Google Apps 的常用 UI 元件. </div><div><br /></div><div><div>本系列之前的文章參考 :</div><div><br /></div><div># <a href="https://yhhuang1966.blogspot.com/2020/03/google-apps-script.html" target="_blank">好書 : Google Apps Script 雲端自動化與動態網頁系統實戰</a></div><div># <a href="https://yhhuang1966.blogspot.com/2020/04/google-apps-script-gas-google-apps.html" target="_blank">Google Apps Script (GAS) 學習筆記 (一) : Google Apps 簡介</a></div><div># <a href="https://yhhuang1966.blogspot.com/2024/03/google-apps-script-2024-03-06.html" target="_blank">Google Apps Script 共讀筆記 (2024-03-06)</a></div></div><div># <a href="https://yhhuang1966.blogspot.com/2024/03/google-apps-script-2024-03-14.html" target="_blank">Google Apps Script 共讀筆記 (2024-03-14)</a></div><div># <a href="https://yhhuang1966.blogspot.com/2024/03/google-apps-script-2024-03-15.html" target="_blank">Google Apps Script 共讀筆記 (2024-03-15)</a></div><div># <a href="https://yhhuang1966.blogspot.com/2024/03/google-apps-script-gas-loggerlog.html" target="_blank">Google Apps Script (GAS) 學習筆記 (二) : 用 Logger.log() 輸出訊息</a></div><div><br /></div><div>UI 元件是用來與 Google Apps 互動的介面, 本測試主要是以試算表為例, 其實每一種 Google Apps (文件, 試算表, 表單等) 上都可以放 UI 元件. </div><div><br /></div><div><br /></div><div><b><span style="background-color: #fce5cd; color: #990000;">一. 按鈕與訊息盒 : </span></b></div><div><br /></div><div>在 Google Apps 上放置按鈕主要是用來觸發執行一個函式. 首先如前一篇測試所示, 在雲端硬碟的自訂資料夾 GAS 下新增一個試算表, 並更名為 ui_test : </div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7IS2nVw1lsya6c5B7v1bYnWpeuepTEnMAGT9P728hwmUjV5N843aPQncnxRjEFY1V81dz7g2OF1rEFpsugb_w-1HLEa9UAqPjuCxCoB9Ghi1Pz8Xa4mXnhXkJU0bWHwhVDkn2E2eBGRO8xw7NOm5MXTrcAFilNaUBpBideKkBZs-8rIjwobhsz30K48NW/s966/gas_ui_test_button_1.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="589" data-original-width="966" height="195" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7IS2nVw1lsya6c5B7v1bYnWpeuepTEnMAGT9P728hwmUjV5N843aPQncnxRjEFY1V81dz7g2OF1rEFpsugb_w-1HLEa9UAqPjuCxCoB9Ghi1Pz8Xa4mXnhXkJU0bWHwhVDkn2E2eBGRO8xw7NOm5MXTrcAFilNaUBpBideKkBZs-8rIjwobhsz30K48NW/s320/gas_ui_test_button_1.jpg" width="320" /></a></div><br /><div><br /></div><div>然後點選 "擴充功能" 再選 "Apps Script" : </div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTmeJcYPCG_F85-JdqlDNSyl2kk_mK1Max_pRonaizgnQRF2uKXPBUrQv0NG20DWem6HLV5ymeVgFMgrDbrm9BpGemQuNuMdjjvLRLmMGTtSQmn6PWfBT-T_M8U3NyRcgEbbcu61-8JgpKIFl5E7vxoelqnR6me7PmeTQPuezRzpeNVtPbS7dElJeOwBRl/s1267/gas_ui_test_button_2.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="589" data-original-width="1267" height="149" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTmeJcYPCG_F85-JdqlDNSyl2kk_mK1Max_pRonaizgnQRF2uKXPBUrQv0NG20DWem6HLV5ymeVgFMgrDbrm9BpGemQuNuMdjjvLRLmMGTtSQmn6PWfBT-T_M8U3NyRcgEbbcu61-8JgpKIFl5E7vxoelqnR6me7PmeTQPuezRzpeNVtPbS7dElJeOwBRl/s320/gas_ui_test_button_2.jpg" width="320" /></a></div><br /><div><br /></div><div> 將產生的未命名 GAS 專案名稱與預設函式 myFunction() 都改為 hello :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEeO7T-Hs7N1DZjNOyrRsQuxY-TEOzMpbNN52tV83ysQRqhelqOxF1oYqODuWe_sGP27AglG5hPDl_BlQ_3mimohKV1vYc4Xpaqd_dEW2yiI7JYTsD0J7H45_xuivBKzwhO8BSi_6UIsB4vQ1K2qoy_mk8r3e4nR8xuluiLIlCIacAgglY7gMws9NhPsfD/s1336/gas_ui_test_button_3.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="680" data-original-width="1336" height="163" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEeO7T-Hs7N1DZjNOyrRsQuxY-TEOzMpbNN52tV83ysQRqhelqOxF1oYqODuWe_sGP27AglG5hPDl_BlQ_3mimohKV1vYc4Xpaqd_dEW2yiI7JYTsD0J7H45_xuivBKzwhO8BSi_6UIsB4vQ1K2qoy_mk8r3e4nR8xuluiLIlCIacAgglY7gMws9NhPsfD/s320/gas_ui_test_button_3.jpg" width="320" /></a></div><br /><div><br /></div><div>然後在 hello() 函式中輸入下列程式碼 : </div><div><br /></div><div>Browser.MsgBox('Hello World!');</div><div><br /></div><div>此處 Browser 為 GAS 的瀏覽器物件, 可在網頁中顯示按鈕, 訊息框與輸入框等元件. 其實在輸入函式的第一個字元時就會顯示下拉式選單讓我們點選物件或方法名稱, 輸入方法的括號時也會顯示參數說明 :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgExScBIM5tSjCrKao4OJecbtjoBfWZNH45NJysHuDSNKh4hIG_hVKjRLLDfZ-SXqgvRNRGMo7kDWkrlc0L_ZdsLAN1sR6j8LtIQx15KL2B_PHwahkuVeoMbFYMaDazi1r6M0caNAQBScTiPDfn9YBlP60WTDsOYIlETl0s310q6BcrW-XDPqpCOTm7kTXk/s1166/gas_ui_test_button_4.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="398" data-original-width="1166" height="109" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgExScBIM5tSjCrKao4OJecbtjoBfWZNH45NJysHuDSNKh4hIG_hVKjRLLDfZ-SXqgvRNRGMo7kDWkrlc0L_ZdsLAN1sR6j8LtIQx15KL2B_PHwahkuVeoMbFYMaDazi1r6M0caNAQBScTiPDfn9YBlP60WTDsOYIlETl0s310q6BcrW-XDPqpCOTm7kTXk/s320/gas_ui_test_button_4.jpg" width="320" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPe1Y5tGmDunb_Gc9Ajf0OSZKu_85otP37J1sRNXNYz21Cj9WIM4zBd84cwrGW1TpvtRRU7zCcg0PdvE8-8mwoqzgLl5lgIiP0k_1hqvWYngVOfu3SXxXZAHupfWhmoaDav6l6sKHULHnYAFxo5nb8c7bp7OiqHc0kr3o6jonM4Dh9iK01LXoXBdyxiuLj/s1255/gas_ui_test_button_5.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="357" data-original-width="1255" height="91" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPe1Y5tGmDunb_Gc9Ajf0OSZKu_85otP37J1sRNXNYz21Cj9WIM4zBd84cwrGW1TpvtRRU7zCcg0PdvE8-8mwoqzgLl5lgIiP0k_1hqvWYngVOfu3SXxXZAHupfWhmoaDav6l6sKHULHnYAFxo5nb8c7bp7OiqHc0kr3o6jonM4Dh9iK01LXoXBdyxiuLj/s320/gas_ui_test_button_5.jpg" width="320" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcfs6ydj4pA3UFEGGF_d7tkqQaEhlCmO_epGGPVB9OlaRiozjmGihb64zZ2FnfFdvNuHtStrBSFAdAfjjWsShB3GVEjONOR3i09VwrBEo_3svywnm0KFU3OTd_9Hq3iO4WAz-Ku_wH478Mfqzpit6kqc5Xpvkr9u5qiZIGqcL2IzdW61_2WT7g-BQHYWl7/s1383/gas_ui_test_button_6.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="687" data-original-width="1383" height="159" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcfs6ydj4pA3UFEGGF_d7tkqQaEhlCmO_epGGPVB9OlaRiozjmGihb64zZ2FnfFdvNuHtStrBSFAdAfjjWsShB3GVEjONOR3i09VwrBEo_3svywnm0KFU3OTd_9Hq3iO4WAz-Ku_wH478Mfqzpit6kqc5Xpvkr9u5qiZIGqcL2IzdW61_2WT7g-BQHYWl7/s320/gas_ui_test_button_6.jpg" width="320" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0yRmw_3JlAIfxoI_SpChVcpZt7TWBRiOnOhxC25OxvxZvouatq3Jpl_QsSxOp_boSRA5J0_YGp0-8U5d8yy4HAHtY-QymLzGPa24cDL4uS14P_ArMpEKxzJpTC_suu66v4jWPB26p3bk6q_0He1xlpoDgGSUCjAGyXQ9KFTNdW5_6IZLfe_74cZJyWewN/s1326/gas_ui_test_button_7.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="682" data-original-width="1326" height="165" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0yRmw_3JlAIfxoI_SpChVcpZt7TWBRiOnOhxC25OxvxZvouatq3Jpl_QsSxOp_boSRA5J0_YGp0-8U5d8yy4HAHtY-QymLzGPa24cDL4uS14P_ArMpEKxzJpTC_suu66v4jWPB26p3bk6q_0He1xlpoDgGSUCjAGyXQ9KFTNdW5_6IZLfe_74cZJyWewN/s320/gas_ui_test_button_7.jpg" width="320" /></a></div><br /><div><br /></div><div><div>按 "儲存專案" 鈕存檔後, 右邊的 "執行" 鈕才會變成可按 :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitVg4yGEa0k3XYz9nMGmtnVV6cnyxKMFWvWzy1ebESlM7f7szMwbkAy-JeKUPDberHteZrOQwEm8vEe07L-NIVwzY3PqIawumMOiO5hbX9OhzJx6W5OlE90-gD9NhFK2JammAy61Fjoa-FiYxTX0M_MZP7qWfViWc3IiA_oAu3c6eFOqOa7rRLtqbbWpLF/s1327/gas_ui_test_button_14.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="687" data-original-width="1327" height="166" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitVg4yGEa0k3XYz9nMGmtnVV6cnyxKMFWvWzy1ebESlM7f7szMwbkAy-JeKUPDberHteZrOQwEm8vEe07L-NIVwzY3PqIawumMOiO5hbX9OhzJx6W5OlE90-gD9NhFK2JammAy61Fjoa-FiYxTX0M_MZP7qWfViWc3IiA_oAu3c6eFOqOa7rRLtqbbWpLF/s320/gas_ui_test_button_14.jpg" width="320" /></a></div><br /><div><br /></div><div>按 "執行" 鈕先測試程式碼效果, 這時會彈出一個 "需要授權" 視窗, 請按 "審查權限" 鈕 : </div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirO-PZHdsa6uJVUhN6N1K-cQ3ge6jyGFQCcCS4jSsD-pbhg9EsOtpJNWA18qCAfY69cL17zRiQTnyFr4HpGgXCigboTO3ZsFkRjAbB6v_Oh4t7myQnyKcG9fgPzLK0_hyphenhyphen1-xKzMUEE1b-_YSJMFRRIULDnk89ZPr7WYesnS570O5tEVoW77RUEXBhu46u7/s957/gas_ui_test_button_15.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="717" data-original-width="957" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirO-PZHdsa6uJVUhN6N1K-cQ3ge6jyGFQCcCS4jSsD-pbhg9EsOtpJNWA18qCAfY69cL17zRiQTnyFr4HpGgXCigboTO3ZsFkRjAbB6v_Oh4t7myQnyKcG9fgPzLK0_hyphenhyphen1-xKzMUEE1b-_YSJMFRRIULDnk89ZPr7WYesnS570O5tEVoW77RUEXBhu46u7/s320/gas_ui_test_button_15.jpg" width="320" /></a></div><br /><div><br /></div><div>然後會彈出 Google 帳戶選擇視窗, 點選自己的 Google 帳戶 :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjltkN7CM_QD1oLEOUl-jvt-A7qK5QXcp_krd2qA7h7KaerSGvf4XzNh8O9znGN_oVt-YBKbtWQFg5xP8L2RM6iUILIYXMtKmaTa5uP97dfnfff_-Pzv599bvvrerpSXSOAcBFj6WklpyskrYsAbmb3wiggxmnCEUv_SPamI0AZQ1XPj2IJUjzATUOSRF-I/s1431/gas_ui_test_button_16.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="694" data-original-width="1431" height="155" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjltkN7CM_QD1oLEOUl-jvt-A7qK5QXcp_krd2qA7h7KaerSGvf4XzNh8O9znGN_oVt-YBKbtWQFg5xP8L2RM6iUILIYXMtKmaTa5uP97dfnfff_-Pzv599bvvrerpSXSOAcBFj6WklpyskrYsAbmb3wiggxmnCEUv_SPamI0AZQ1XPj2IJUjzATUOSRF-I/s320/gas_ui_test_button_16.jpg" width="320" /></a></div><br /><div><br /></div><div>接著會彈出 "這個應用程式未經 Google 驗證" 的警告, 按左下角的 "進階" :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZWVj1v8cO8HeBud7bwyk2wjXdYBpq2Bwvo70l3FIX47E5lUSyg2TwZr7CZPw7qYqkQtg9UpIYAXubS0spBMW2RwhF1DbxJQa7VkI2zGZsQL0_STJblyQH-CQ8515fL3somkXw-e0bIx1lfmjYdEs8RddTKDJtXqQqumapjasWmhcO3ov1qQa0m_sliuQ2/s1385/gas_ui_test_button_17.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="764" data-original-width="1385" height="177" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZWVj1v8cO8HeBud7bwyk2wjXdYBpq2Bwvo70l3FIX47E5lUSyg2TwZr7CZPw7qYqkQtg9UpIYAXubS0spBMW2RwhF1DbxJQa7VkI2zGZsQL0_STJblyQH-CQ8515fL3somkXw-e0bIx1lfmjYdEs8RddTKDJtXqQqumapjasWmhcO3ov1qQa0m_sliuQ2/s320/gas_ui_test_button_17.jpg" width="320" /></a></div><br /><div>這時底下會出現一段若不信任開發人員 (就是自己啦) 勿繼續操作警語, 請按底下的 "前往 <span face="arial, sans-serif" style="background-color: white; color: #4d5156; font-size: 14px;">「</span>hello<span face="arial, sans-serif" style="background-color: white; color: #4d5156; font-size: 14px;"> 」</span> (不安全)" 超連結進行授權 :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8B3SsjQVlB5Xa1250l3Rmm49O7w_oeLN4rT4CxUadUFZq4M9TMpC6bGrva_nugCkpHLmAhzw3w6UvFLh6dXBOi6TaVGrhB6w66LIJE9ZJrS8eRnz6l_rReAYgfmm8rdHGfs_Jp7504LcbEIxuZNLRKHn4VxDlPsUmyMolY9UJdqaT7hdiM-sJQknzlvjV/s1375/gas_ui_test_button_18.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="937" data-original-width="1375" height="218" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8B3SsjQVlB5Xa1250l3Rmm49O7w_oeLN4rT4CxUadUFZq4M9TMpC6bGrva_nugCkpHLmAhzw3w6UvFLh6dXBOi6TaVGrhB6w66LIJE9ZJrS8eRnz6l_rReAYgfmm8rdHGfs_Jp7504LcbEIxuZNLRKHn4VxDlPsUmyMolY9UJdqaT7hdiM-sJQknzlvjV/s320/gas_ui_test_button_18.jpg" width="320" /></a></div><br /><div>在彈出視窗中按右下角的 "允許" 鈕即完成執行此程式之授權 :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQ3GHKmmJnoOE-Xj_hOQDr9zyqT5AdSqCwIV7QLdNUzqG9L6uy4lbLhfUkIgs2b9gv1kqLJkliVGfEhz85K1dOBMB68PUHbJzn8KB4-BPVcNGLP71pBgt3yH2IO_o6Bpl5LsEfzaZcAETrkheX1nOktOxn6A0I8iambSPHIhO_ULMuaSARsRa8S07OZwr_/s1347/gas_ui_test_button_19.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1332" data-original-width="1347" height="316" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQ3GHKmmJnoOE-Xj_hOQDr9zyqT5AdSqCwIV7QLdNUzqG9L6uy4lbLhfUkIgs2b9gv1kqLJkliVGfEhz85K1dOBMB68PUHbJzn8KB4-BPVcNGLP71pBgt3yH2IO_o6Bpl5LsEfzaZcAETrkheX1nOktOxn6A0I8iambSPHIhO_ULMuaSARsRa8S07OZwr_/s320/gas_ui_test_button_19.jpg" width="320" /></a></div><br /><div class="separator" style="clear: both; text-align: left;"><br /></div>這時再次按下專案視窗中的 "執行" 鈕, 就會在<span style="background-color: #fcff01;">試算表視窗</span>中彈出一個訊息框 (注意, <span style="background-color: #fcff01;">執行結果不是顯示在 GAS 專案視窗</span>, 而是它寄生的試算表視窗) : </div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzid6cmYuQrczg6YloO8LQGDbitJWVLFOuxDPUjsQFTV-oc5d4PIIfOpskJE8DXULLYKxyd0iqdbSob59xfs3nXFcrdVAxaDZ1wZfPZaxXOpRKNhsOLp2hONUXVn19xqg58jxUQ9Hgp7M9bgAsMyyXucKjTYGxlfF2uWHak-0LORWkLGKZUmoRvFh7oBZY/s1196/gas_ui_test_button_20.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="682" data-original-width="1196" height="182" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzid6cmYuQrczg6YloO8LQGDbitJWVLFOuxDPUjsQFTV-oc5d4PIIfOpskJE8DXULLYKxyd0iqdbSob59xfs3nXFcrdVAxaDZ1wZfPZaxXOpRKNhsOLp2hONUXVn19xqg58jxUQ9Hgp7M9bgAsMyyXucKjTYGxlfF2uWHak-0LORWkLGKZUmoRvFh7oBZY/s320/gas_ui_test_button_20.jpg" width="320" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKUOIUnVC6icGPZb3lr2yrYQCkGlyxzCEX-rCSwFxE27qkkrCO2ash6jtnsk9CeMDi2yeNCCR5BXyWCVpdt7e1hu3euke4MrkXK2VT05Dv7uyUHJDB9y96Is7HkmSGwIBpW8rfkgib9Hn64VP5kgnhBX9H6cZ3UsQTZ2OQACuyNAa7NczjcytQrQx-1mqz/s1115/gas_ui_test_button_21.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="833" data-original-width="1115" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKUOIUnVC6icGPZb3lr2yrYQCkGlyxzCEX-rCSwFxE27qkkrCO2ash6jtnsk9CeMDi2yeNCCR5BXyWCVpdt7e1hu3euke4MrkXK2VT05Dv7uyUHJDB9y96Is7HkmSGwIBpW8rfkgib9Hn64VP5kgnhBX9H6cZ3UsQTZ2OQACuyNAa7NczjcytQrQx-1mqz/s320/gas_ui_test_button_21.jpg" width="320" /></a></div><div><br /></div><div><br /></div><div>按下 "確定" 鈕即可關閉訊息框, 此按鈕為 msgBox() 方法第二參數所控制, 如果沒有傳入第二參數, 預設為 Browser.Buttons.OK (確定), 其他可傳入值如下 :</div><div><ul style="text-align: left;"><li>Browser.Buttons.OK_CANCEL</li><li>Browser.Buttons.YES_NO</li><li>Browser.Buttons.YES_NO_CANCEL</li></ul></div><div>以上只是測試此 GAS 專案程式碼是否可順利執行 (並授予該帳戶執行權), 但這次目的不是要在 GAS 專案視窗上直接按執行鈕來執行程式碼, 而是要在試算表 App 上放一個按鈕, 讓使用者按下按鈕時執行 hello(), 所以接下來要在試算表視窗上繪製一個按鈕. </div><div><div><br /></div><div>回到試算表 App 視窗, 點選上方的 "插入" 選單, 再點選 "繪圖" :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgC9I-OGD2JSKok0bSycyZ1GxdCq7___oOa6qiR9v2ix39hhUuTiHORXa9qSAnADF0QD5DBEIdm5xk2lBHMWUjQ8NRr35gDVptlIir4vBaX5GBBXOT0eNXM9e6EvhjdkGd0efnYeLOvrTMhk1wF4x7Ss9ZtcRTwOJWiZnPDaV828En-sXgrVPG_gOOd7xnF/s1390/gas_ui_test_button_8.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1017" data-original-width="1390" height="234" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgC9I-OGD2JSKok0bSycyZ1GxdCq7___oOa6qiR9v2ix39hhUuTiHORXa9qSAnADF0QD5DBEIdm5xk2lBHMWUjQ8NRr35gDVptlIir4vBaX5GBBXOT0eNXM9e6EvhjdkGd0efnYeLOvrTMhk1wF4x7Ss9ZtcRTwOJWiZnPDaV828En-sXgrVPG_gOOd7xnF/s320/gas_ui_test_button_8.jpg" width="320" /></a></div><br /><div><br /></div><div>這樣會彈出一個繪圖板視窗, 點選圖案按鈕, 選擇 "圖案" 第一排適合做按鈕的圖形, 在繪圖板上畫出一個按鈕圖形 : </div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqdaY0BQf7tGsbLjvK88wUidcbGyJ61wZqw_bPayP9_cB6e1GdEpUrtKqv0FUC3d16nA6y4spPdFroDu01oBpTZUEUceTYgBqv7ZH1QL6nkxG04x9eQsbe0UmRC5QSCZYujYZGOqbI2TLAfWSUKD0rxy59qBTbXmZT2k2PlWenxy60Th5YbiMEhswvSf6-/s1563/gas_ui_test_button_9.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="861" data-original-width="1563" height="176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqdaY0BQf7tGsbLjvK88wUidcbGyJ61wZqw_bPayP9_cB6e1GdEpUrtKqv0FUC3d16nA6y4spPdFroDu01oBpTZUEUceTYgBqv7ZH1QL6nkxG04x9eQsbe0UmRC5QSCZYujYZGOqbI2TLAfWSUKD0rxy59qBTbXmZT2k2PlWenxy60Th5YbiMEhswvSf6-/s320/gas_ui_test_button_9.jpg" width="320" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiE120q7Rur8ft5bb551zZdermCaNb3BXDaIdOkogUH1jiLV1JHeS3fC8jtOOtPmfbOxXBk_nyHeLUppzyPlCtOCrEKLTTwHVvJDQrRmWe-3Giz3c77te7Icio2HSUR_FyLePXQJexixSewA4S3BPaohICM404MKDfaUXcH0XIOXsLDvPuLKGrZ8O7oqG97/s1552/gas_ui_test_button_9.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="783" data-original-width="1552" height="161" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiE120q7Rur8ft5bb551zZdermCaNb3BXDaIdOkogUH1jiLV1JHeS3fC8jtOOtPmfbOxXBk_nyHeLUppzyPlCtOCrEKLTTwHVvJDQrRmWe-3Giz3c77te7Icio2HSUR_FyLePXQJexixSewA4S3BPaohICM404MKDfaUXcH0XIOXsLDvPuLKGrZ8O7oqG97/s320/gas_ui_test_button_9.jpg" width="320" /></a></div><br /><div><br /></div><div>點選此按鈕, 按滑鼠右鍵, 點選 "編輯文字", 輸入按鈕上的文字例如 "按我執行" :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5X34ncQKAvLFcfqR5sAByOldZOJindcZUKjpT_-MuAYIqzrVlkxL9KN-EQYqs9I3gQnnJ1_227dM3gMpbWBuWnCNqF7LSJYPa1V1UYTqP3atNkUt9XOUYroXZbkPNhi6FczUvci4bQmct2pbmoXR8jcytbDR6klW3XswcdTDqu6d7BNKZ6hogcjyXmXws/s1559/gas_ui_test_button_11.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="936" data-original-width="1559" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5X34ncQKAvLFcfqR5sAByOldZOJindcZUKjpT_-MuAYIqzrVlkxL9KN-EQYqs9I3gQnnJ1_227dM3gMpbWBuWnCNqF7LSJYPa1V1UYTqP3atNkUt9XOUYroXZbkPNhi6FczUvci4bQmct2pbmoXR8jcytbDR6klW3XswcdTDqu6d7BNKZ6hogcjyXmXws/s320/gas_ui_test_button_11.jpg" width="320" /></a></div><br /><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">按上方的 "儲存並關閉鈕" : 關閉繪圖板視窗 : </div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfIyrw4OG1vFoGDSEbmAYmzv-4aXiIRWwQ4tMEFYNUrrCq-2KEYNuw4yE44SFTbmBdEc3FEBuHYFZwmTirEeaf9gBY1Wz79dTrCsoqe0u46lUPtYxRfZKyF9ulFXLyMroDbf15olED2MpS3M0APET2zSNIMh73fa6221veHP8Y-jv17gplWG_oEXhkGg-y/s1551/gas_ui_test_button_12.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="771" data-original-width="1551" height="159" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfIyrw4OG1vFoGDSEbmAYmzv-4aXiIRWwQ4tMEFYNUrrCq-2KEYNuw4yE44SFTbmBdEc3FEBuHYFZwmTirEeaf9gBY1Wz79dTrCsoqe0u46lUPtYxRfZKyF9ulFXLyMroDbf15olED2MpS3M0APET2zSNIMh73fa6221veHP8Y-jv17gplWG_oEXhkGg-y/s320/gas_ui_test_button_12.jpg" width="320" /></a></div><br /><div class="separator" style="clear: both; text-align: left;"><br /></div></div><div class="separator" style="clear: both; text-align: left;">這時試算表上就會出現一個浮動的按鈕 (可拖曳到任何位置, 不屬於任一儲存格) :</div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGzMlmlmSFizQ5mM_T8oxrGgVt5TGMQzyMlNVuR03CqGnlxfdikyQmWm8W-gNEupOwXk3p-YrLNXw6g_JKkT09AmSciXnysxBMfve8-y2LsA2PlDZLMFs2tF4gi6V9p4CdVTWXggaEqkKYU-wE9aIwte4noElxSRHM-jVLdwwm98BWzTWqz5iqzV-Sk9jI/s1194/gas_ui_test_button_13.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="739" data-original-width="1194" height="198" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGzMlmlmSFizQ5mM_T8oxrGgVt5TGMQzyMlNVuR03CqGnlxfdikyQmWm8W-gNEupOwXk3p-YrLNXw6g_JKkT09AmSciXnysxBMfve8-y2LsA2PlDZLMFs2tF4gi6V9p4CdVTWXggaEqkKYU-wE9aIwte4noElxSRHM-jVLdwwm98BWzTWqz5iqzV-Sk9jI/s320/gas_ui_test_button_13.jpg" width="320" /></a></div><div><br /></div><div><br /></div><div>接下來是要將此按鈕綁定按下動作 (click) 要執行的函式, 重點來了, 先點選此按鈕, 這時按鈕右上發會出現三個垂直小點, 按它會彈出一個選單, 點選其中的 "指派指令碼" :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgM8GZPz2ZojkH3GhrjSVUuqY8IbgE1OjALtXkW6TKUtbt7CQWrd_dAsP3dYBvHKdKvQ_aHXa5z4b0ktzdnnW2T97Ruj4rIzo-bfsUuGdMCyWMs1Vj6PYCezx74N6xBGgiWqH2Ykn8ms914pePBMNdEQ9TxWvd90T97gRTffHWC3pZGpWWeNnlmc36rgOJS/s1396/gas_ui_test_button_22.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="901" data-original-width="1396" height="207" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgM8GZPz2ZojkH3GhrjSVUuqY8IbgE1OjALtXkW6TKUtbt7CQWrd_dAsP3dYBvHKdKvQ_aHXa5z4b0ktzdnnW2T97Ruj4rIzo-bfsUuGdMCyWMs1Vj6PYCezx74N6xBGgiWqH2Ykn8ms914pePBMNdEQ9TxWvd90T97gRTffHWC3pZGpWWeNnlmc36rgOJS/s320/gas_ui_test_button_22.jpg" width="320" /></a></div><br /><div><br /></div><div>這時會彈出一個視窗, 請在輸入框中輸入欲執行的函式名稱 (不要加括號) 即完成指派 : </div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyTfrzhgDh6btfKpMPNC95TVh0qciZD_p_F-gsg1F_-qWjUKfcQ4XyN29ryiXOVEDkSmNPG5ckHcsQHKTzYxU8quzQDzd3fr7wzTZRiueGQG36NFSknzD3DZ8NF6Q__1dSEv1d_BgCaxkLsOOklvYNPzpzcs_dlDzlZLLj7d-p8QTPtR2HhhZDKbwSDaaW/s1349/gas_ui_test_button_23.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="749" data-original-width="1349" height="178" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyTfrzhgDh6btfKpMPNC95TVh0qciZD_p_F-gsg1F_-qWjUKfcQ4XyN29ryiXOVEDkSmNPG5ckHcsQHKTzYxU8quzQDzd3fr7wzTZRiueGQG36NFSknzD3DZ8NF6Q__1dSEv1d_BgCaxkLsOOklvYNPzpzcs_dlDzlZLLj7d-p8QTPtR2HhhZDKbwSDaaW/s320/gas_ui_test_button_23.jpg" width="320" /></a></div><br /><div><br /></div>這時按下試算表上的 "按我執行" 鈕就會直接執行 hello() 了 : <div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizkCO45I7PwocURB3CVJTV5qAy4eiBX4aM_JcBOd7d7_aXLWB6KKCDzbZ58q3PppGDQrAurSs-595GZOCKM8G7aJM8CAIARHBmQVAvtBt49VfhAM7aKzXH_2hsNACoRM1sRanqtf3bf0zey-ZLdGy_JTaZL1MIe9dZjgDYlQT1cI0Z1vdtdcRBmNmxYxJy/s1600/gas_ui_test_button_24.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="834" data-original-width="1600" height="167" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizkCO45I7PwocURB3CVJTV5qAy4eiBX4aM_JcBOd7d7_aXLWB6KKCDzbZ58q3PppGDQrAurSs-595GZOCKM8G7aJM8CAIARHBmQVAvtBt49VfhAM7aKzXH_2hsNACoRM1sRanqtf3bf0zey-ZLdGy_JTaZL1MIe9dZjgDYlQT1cI0Z1vdtdcRBmNmxYxJy/s320/gas_ui_test_button_24.jpg" width="320" /></a></div><br /><div><br /><div>以上雖然只是簡單的功能, 但實際應用時函式可能會很複雜, 但只要按一個按鈕就可以執行此函式, 而不需要開啟 GAS 專案視窗來執行. </div><div><br /></div><div>參考 : </div><div><br /></div><div><div># <a href="https://www.youtube.com/watch?v=T6c_ncWmbUo" target="_blank">【Google教學】如何在試算表中增加一個按鈕可以設定執行指定程式</a></div><div><br /></div><div><br /></div><div><b><span style="background-color: #fce5cd; color: #990000;">二. 輸入框 (InputBox) :</span></b> </div></div></div><div><br /></div><div>GAS 的 UI 除了輸入外也可以用 Browser 物件的 InputBox() 方法來取得使用者輸入, 我們修改上面的 hello 專案, 將 hello() 函式改成如下 :</div><div><br /></div><div>function hello() {</div><div><div> var name=Browser.inputBox('請輸入名字');</div><div> Browser.msgBox('Hello, ' + name);</div><div>}</div></div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOjrNti0gax1DIngO0gsSTAqOGc0D3PxcWdFBM2EvoL0U9GQVv4ubgbNvEozBfOnFSU3PxTxcOo-SDoemYrvf7imDE8sSlj9kGT4hFrO_1FEJnTM0p3fb_oue4h1J8nMT8nOfRRGsvhaeKNGmojZGNpaslJBngyX3-H-plLuqIxAkOo2PMPYREe6mE92lA/s1452/gas_ui_test_inputbox_1.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="700" data-original-width="1452" height="154" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOjrNti0gax1DIngO0gsSTAqOGc0D3PxcWdFBM2EvoL0U9GQVv4ubgbNvEozBfOnFSU3PxTxcOo-SDoemYrvf7imDE8sSlj9kGT4hFrO_1FEJnTM0p3fb_oue4h1J8nMT8nOfRRGsvhaeKNGmojZGNpaslJBngyX3-H-plLuqIxAkOo2PMPYREe6mE92lA/s320/gas_ui_test_inputbox_1.jpg" width="320" /></a></div><br /><div><br /></div><div>此處 Browser.InputBox() 的傳入參數為輸入框的提示語 (prompt) 或標題, 其傳回值為輸入框內的字串, 我們先將其存在 name 變數中, 然後傳入 msgBox() 的組合字串中輸出. 將此專案存檔後, 切回試算表視窗, 按下 "按我執行" 鈕, 這時會彈出一個輸入框, 填入名字按確定, 就會在談出的訊息框李顯示名字了 :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTseu12yJgQcZofWh8X_WCE1TclpOfEsvt3gQEg8vtdVAglN3uJ5x2F-rYcoBPDYH0034k2TyaJOK3TIGECwM783Jy8ojuAOipJ2kf96RSKIgEzG-b2l4FskS7bcb3-YC27kzbZr9vajICSh5rHt4daIi3TC1gTIJllqW_NFEVRXDwP7W7od2UWwZxMyLv/s1593/gas_ui_test_inputbox_2.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="902" data-original-width="1593" height="181" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTseu12yJgQcZofWh8X_WCE1TclpOfEsvt3gQEg8vtdVAglN3uJ5x2F-rYcoBPDYH0034k2TyaJOK3TIGECwM783Jy8ojuAOipJ2kf96RSKIgEzG-b2l4FskS7bcb3-YC27kzbZr9vajICSh5rHt4daIi3TC1gTIJllqW_NFEVRXDwP7W7od2UWwZxMyLv/s320/gas_ui_test_inputbox_2.jpg" width="320" /></a></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3iqEitsV36onSaVjFWtcZlz7E9WcFVquqNdhL24V_0AcBDLDeYsGnzh_mYg8kcXfOXzx3Mrlh5oZERvGqug5lCcuQ263dAzWlsZAZQDKz9jFhtXwbh9XYz0jxtwiAYgkUZzM2cSWiB02PShG4He0ndpb_UhqrZsLJ_I194qg5RVDTgK5_txKZz_grBPOg/s1599/gas_ui_test_inputbox_3.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="822" data-original-width="1599" height="165" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3iqEitsV36onSaVjFWtcZlz7E9WcFVquqNdhL24V_0AcBDLDeYsGnzh_mYg8kcXfOXzx3Mrlh5oZERvGqug5lCcuQ263dAzWlsZAZQDKz9jFhtXwbh9XYz0jxtwiAYgkUZzM2cSWiB02PShG4He0ndpb_UhqrZsLJ_I194qg5RVDTgK5_txKZz_grBPOg/s320/gas_ui_test_inputbox_3.jpg" width="320" /></a></div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-91491498776210635132024-03-18T14:38:00.002+08:002024-03-18T14:38:18.144+08:00市圖還書 1 本 (特洛伊木馬病毒程式設計)<div>本周市圖還書 1 本 (被預約) : </div><div><ol style="text-align: left;"><li><h2 style="background-color: white; color: #333333; font-family: Lato, "PingFang TC", "Helvetica Neue", Helvetica, 微軟正黑體, 新細明體, Arial, sans-serif; font-size: 1.25em; font-weight: normal; line-height: 1.3em; margin: 0px 0px 10px; padding: 0px;"><a href="https://webpacx.ksml.edu.tw/bookDetail/1579883" style="background-color: transparent; color: #774e2b; transition: all 0.5s ease 0s;">特洛伊木馬病毒程式設計 :使用Python</a></h2></li></ol></div>此書有出加強版 (電子書), 參考 :<div><br /></div><div># <a href="https://www.books.com.tw/products/E050073173" target="_blank">特洛伊木馬病毒程式設計(加強版):使用Python (電子書)</a></div><div><br /></div><div><div>另外, 我在 Medium 找到一篇此書的評論, 很值得參考 :<br /><div><br /></div><div># <a href="https://pinglunliao.medium.com/%E7%89%B9%E6%B4%9B%E4%BC%8A%E6%9C%A8%E9%A6%AC%E7%97%85%E6%AF%92%E7%A8%8B%E5%BC%8F%E8%A8%AD%E8%A8%88-%E4%BD%BF%E7%94%A8python-%E8%AE%80%E5%BE%8C%E6%84%9F-40a08b4a6e01" target="_blank">「特洛伊木馬病毒程式設計 — 使用Python」讀後感</a></div></div><div><br /></div></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-45460103148545113052024-03-17T23:08:00.005+08:002024-03-17T23:08:28.698+08:002024 年第 11 周記事 (掃墓)本周周日為家族掃墓日, 早上是衙門對面山上的家祠, 下午則是田中央的來台祖, 早上貼紅紙時, 嬸嬸看見我拿的是五福臨門, 她說應該買祖德流芳才對, 跟金香店講即可. 這要列入掃墓 SOP, 明年要改買這種. 其次是張數, 家祠要帶 12 張 (內門不用貼), 來台祖是 6 張. 另外防風蠟燭, 家祠帶 3 對, 來台祖帶 4 對. <div><br /></div><div>本想放個鋁梯在家祠門內, 週三去振宇五金看三尺鋁梯是 780, 小北與上元都賣 990, 週六本想去買載回鄉下, 但時間不夠沒買, 但幸好沒買, 因為今天看到堂兄用的是五尺的, 覺得這個要貼紅紙高度才夠, 下周要去振宇買一個五尺的. </div><div><br /></div><div>今年有新生代參加掃墓, 堂姪們帶了小朋友來, 讓我晉身為叔公級, 我是既高興又感到畏懼, 每日作學問不知老之將至也. 另彥倫堂妹的女兒讀雄女資工班, 非常優秀, 難得掃墓還有人能與我談 C++, Python 與 AI. </div><div><br /></div><div>下午來台祖掃墓, 大家兩點半已擺好祭品, 但堂弟卻弄錯時間以為是 3 點, 惹得堂哥似乎有些不快, 說家族群組要做個表格, 提醒大家掃墓時間. 有空我來做個機器人自動提醒大家唄. </div><div><br /></div><div>停了一個多月後, 本周恢復 Hahow 企業版課程學習, 上完兩堂 AI 人人學與一堂韓語基礎發音, 發現韓語拼音確實很符合語言學的規則耶! 有打算帶爸去韓國玩 (自由行), 想先學點韓語.</div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-91798421874437715872024-03-16T17:46:00.004+08:002024-03-16T17:46:59.298+08:00Google Apps Script (GAS) 學習筆記 (二) : 用 Logger.log() 輸出訊息<div><div>這篇筆記是我在 2020-01-31 寫的, 寫了一半卻停下來. 3/4 日在臉書看到 Line 群組謝昌勳老師要講 GAS 的課, 所以又把之前買的 "<a href="https://yhhuang1966.blogspot.com/2020/03/google-apps-script.html" target="_blank">Google Apps Script 雲端自動化與動態網頁系統實戰</a>" 這本書拿出來啃 (此書已出第二版), 順便把這篇筆記寫完. </div><div><br /></div><div>本系列之前的文章參考 :</div><div><br /></div><div># <a href="https://yhhuang1966.blogspot.com/2020/03/google-apps-script.html" target="_blank">好書 : Google Apps Script 雲端自動化與動態網頁系統實戰</a></div><div># <a href="https://yhhuang1966.blogspot.com/2020/04/google-apps-script-gas-google-apps.html" target="_blank">Google Apps Script (GAS) 學習筆記 (一) : Google Apps 簡介</a></div><div># <a href="https://yhhuang1966.blogspot.com/2024/03/google-apps-script-2024-03-06.html" target="_blank">Google Apps Script 共讀筆記 (2024-03-06)</a></div><div><br /></div>Google 雲端硬碟的試算表 (SpreadsheetApp) 除了可以取代 Excel 外, 最強的功能是有免費額度可用來製作網路爬蟲, 然後將結果儲存在試算表中; 而且還能透過觸發器來達成自動化 (類似 Linux 的 Crontab 功能). 但與 Excel 不同的是, SpreadsheetApp 使用的程式語言是源自 Javascript 的 GAS, 它相當於是 Javascript + Google 自訂物件.</div><div><div><br /></div><div>在程式開發時經常需要輸出變數值以便能進行偵錯, 最常用來輸出資訊的的 UI 元件是訊息盒 (Message Box), 在網頁開發時通常使用 Javascript 的 window.alert() 將變數輸出到彈出視窗中, 或者用 document.write() 將變數輸出到網頁. 雖然都是 Javascript 執行環境, 但在 GAS 中這兩種方法都無法使用, 而是要改用 Logger.log() 方法. </div><div><br /></div><div><br /></div><div><b><span style="background-color: #fce5cd; color: #990000;">一. 建立資料夾與試算表 : </span></b> </div><div><br /></div><div>首先在 Google 雲端硬碟下建立一個資料夾 GAS 來存放測試檔案與資料, 避免雜亂無章, 先按左上角的 "+ 新增" 按鈕 :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrRqyiMO3ZRtwd7fyNXQn0ub3mr-NCpRINsDqgLwHCvX398EQP_5V0u2lUHtHlXxdTGRCcpkIS2rV6sl1NoPf3jgZurAuVh0NRmK5d1SPI4X9l8333HKFnmFsKX7Sh0KClb1IE-2pJnapZ6sz816bGF7FQjmMEWObhKLlUc9Wg5DMuA8RdNXMDuXUchpOh/s1035/gas_create_folder_1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="606" data-original-width="1035" height="187" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrRqyiMO3ZRtwd7fyNXQn0ub3mr-NCpRINsDqgLwHCvX398EQP_5V0u2lUHtHlXxdTGRCcpkIS2rV6sl1NoPf3jgZurAuVh0NRmK5d1SPI4X9l8333HKFnmFsKX7Sh0KClb1IE-2pJnapZ6sz816bGF7FQjmMEWObhKLlUc9Wg5DMuA8RdNXMDuXUchpOh/s320/gas_create_folder_1.jpg" width="320" /></a></div><br /><div><br /></div><div>選擇 "新資料夾" : </div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhja3pKuMQiWIGLjSVV7ZSF7BivLDgQJWjsd7oNityUrozLOhKAUvbjq6pX3UP0EQbQ5j6_sXw4taOVXhFEjMhCWYK9oXRcpMjLxIUsyauCxoWc97IfSuigUXqSDjzi92NP9vD8UtYML018J_tv5U8_ZLvz4vUyTm8S-trfVD2a3y_DWvvQ_rSKWPteQbmw/s992/gas_create_folder_2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="851" data-original-width="992" height="275" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhja3pKuMQiWIGLjSVV7ZSF7BivLDgQJWjsd7oNityUrozLOhKAUvbjq6pX3UP0EQbQ5j6_sXw4taOVXhFEjMhCWYK9oXRcpMjLxIUsyauCxoWc97IfSuigUXqSDjzi92NP9vD8UtYML018J_tv5U8_ZLvz4vUyTm8S-trfVD2a3y_DWvvQ_rSKWPteQbmw/s320/gas_create_folder_2.jpg" width="320" /></a></div><div><br /></div><div><br /></div>於彈出視窗中輸入資料夾名稱, 例如 GAS, 然後按 "建立" : </div><div><br /><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHlL9poN9iYQBPeTeUoG-1-Efstdiuou9kKZ0-hJpBbegdDLvmYNRZRvXa2NOj3qWEBB8im2AKFYfwub9LdcifjM0u7Kb8fm-0AnMoH-E11k9aJ_zR7q4N4kBIIfB4V1m7lJ1GOxVYIhn8aBGd8mMd6_bvkwE5ahW6lCv1znHwk5KAq8JHZcZ7CDQQaHue/s1085/gas_create_folder_3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="738" data-original-width="1085" height="218" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHlL9poN9iYQBPeTeUoG-1-Efstdiuou9kKZ0-hJpBbegdDLvmYNRZRvXa2NOj3qWEBB8im2AKFYfwub9LdcifjM0u7Kb8fm-0AnMoH-E11k9aJ_zR7q4N4kBIIfB4V1m7lJ1GOxVYIhn8aBGd8mMd6_bvkwE5ahW6lCv1znHwk5KAq8JHZcZ7CDQQaHue/s320/gas_create_folder_3.jpg" width="320" /></a></div><div><br /></div><div><br /></div>這樣雲端硬碟根目錄下就產生了一個名為 GAS 的空資料夾 : </div><div><br /><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh53kwstj8Ok4pd7bQbkWyzHGKg71Lr_syU3jvH_JXZG_jStS2oOkn2WE_Dxl1VUCHRVBipNtjK-JTzKO5JLNxfMxtGO0ouhi5zGoXaxdsOJPKDGMKJ2aMEROaAm3JpqM7LmdzXxnLBsHpKnmkVNu3VjTATPFDY6uXbCd4jPGYeJK2PkLY9B5Gyxn7SG-bw/s1541/gas_create_folder_4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="773" data-original-width="1541" height="161" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh53kwstj8Ok4pd7bQbkWyzHGKg71Lr_syU3jvH_JXZG_jStS2oOkn2WE_Dxl1VUCHRVBipNtjK-JTzKO5JLNxfMxtGO0ouhi5zGoXaxdsOJPKDGMKJ2aMEROaAm3JpqM7LmdzXxnLBsHpKnmkVNu3VjTATPFDY6uXbCd4jPGYeJK2PkLY9B5Gyxn7SG-bw/s320/gas_create_folder_4.jpg" width="320" /></a></div><br /><div><br /></div><div>點此 GAS 空資料夾進去 : </div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEBHcCp5iwPk5itIuO3titbu6Q4PRXctHkyWZykYvBhFXeik__rXVHBYe5OyfCR8WhuAtFhk-tsnWGckv1JfR6J4jKagn8f2POuaAH437QSIyv3xcCx_m-I2aHlp392KuBrMuxA0JE7kpwb4HOyo1F4p093nDJNH-gvEub8vVRHCIk2JWkAH2vXkE4S3Jn/s1547/gas_create_folder_5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="935" data-original-width="1547" height="193" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEBHcCp5iwPk5itIuO3titbu6Q4PRXctHkyWZykYvBhFXeik__rXVHBYe5OyfCR8WhuAtFhk-tsnWGckv1JfR6J4jKagn8f2POuaAH437QSIyv3xcCx_m-I2aHlp392KuBrMuxA0JE7kpwb4HOyo1F4p093nDJNH-gvEub8vVRHCIk2JWkAH2vXkE4S3Jn/s320/gas_create_folder_5.jpg" width="320" /></a></div><br /><div><br /></div><div>再次按左上角的 "+ 新增" 按鈕, 這回點選 "" :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRJkgbrTnEKD3-Kciv-BJVl2LihKuw1GIlpL7hZshCsPlkLRSrAaGKMJ9zbnDcifHSAuITOMKn-PlFLfh7nQtZgfLJBmHdzbGWAZH34qJ45uTZvZWwJI9FAhz_CoaCK6Dyib2U9KhARIzGoFev_g5oDpJezCTM0hyphenhyphen6dkHxDJy_MuHAFkS-QooFOyCsh3gQ/s873/gas_create_spreadsheet_1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="859" data-original-width="873" height="315" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRJkgbrTnEKD3-Kciv-BJVl2LihKuw1GIlpL7hZshCsPlkLRSrAaGKMJ9zbnDcifHSAuITOMKn-PlFLfh7nQtZgfLJBmHdzbGWAZH34qJ45uTZvZWwJI9FAhz_CoaCK6Dyib2U9KhARIzGoFev_g5oDpJezCTM0hyphenhyphen6dkHxDJy_MuHAFkS-QooFOyCsh3gQ/s320/gas_create_spreadsheet_1.jpg" width="320" /></a></div><br /><div><br /></div><div>這時會彈出一個類似 Excel 介面的未命名試算表新視窗 :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEie6cC4SLYXNOvj6dlBthNGD3WDD7EtU-0qDNLmmX4H35_O3QQPcAltYwb0QZhlSlza1dQaw5FboHTGV1cR8yafOGwxtzHjtO08Bdh3tsV_1CU4FPVX5WfHP9eANJdvJ6DVukxpVCPblmvfRERUdG5SGMUQyJD9bNdBhsi2y0kMcbeOas3KhJrQ4Mi-Sg0k/s1222/gas_create_spreadsheet_2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="685" data-original-width="1222" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEie6cC4SLYXNOvj6dlBthNGD3WDD7EtU-0qDNLmmX4H35_O3QQPcAltYwb0QZhlSlza1dQaw5FboHTGV1cR8yafOGwxtzHjtO08Bdh3tsV_1CU4FPVX5WfHP9eANJdvJ6DVukxpVCPblmvfRERUdG5SGMUQyJD9bNdBhsi2y0kMcbeOas3KhJrQ4Mi-Sg0k/s320/gas_create_spreadsheet_2.jpg" width="320" /></a></div><br /><div><br /></div><div>點選左上角的 "未命名的試算表", 在輸入框中輸入試算表的新名稱, 例如 output_test :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhngOQ4-bIqPEhDsCSrqvlt4Ps2dlTuMXBJ-3B5kWut4EUUbjexYTdRU708nqAWh5dZp8LhRWbZK9pqem4RcuLp2lUkWn-2bl4jEwd2972UFFGIeKzoad-vjmhZK5hKhPVQyGBHcgDNdeqQwk9lAV0ghZQTeu78jNUNoogZLWVt2ZV1l0RyJR1b79yFM02q/s1195/gas_create_spreadsheet_3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="632" data-original-width="1195" height="169" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhngOQ4-bIqPEhDsCSrqvlt4Ps2dlTuMXBJ-3B5kWut4EUUbjexYTdRU708nqAWh5dZp8LhRWbZK9pqem4RcuLp2lUkWn-2bl4jEwd2972UFFGIeKzoad-vjmhZK5hKhPVQyGBHcgDNdeqQwk9lAV0ghZQTeu78jNUNoogZLWVt2ZV1l0RyJR1b79yFM02q/s320/gas_create_spreadsheet_3.jpg" width="320" /></a></div><div><br /></div><div><br /></div>此時切回雲端硬碟視窗就會看到此試算表檔案 :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYLl0AaQQwGIM9ZnCpAzO2rtWBcVAuOwHr9jzKanKREF7QXWp-53hFFI7fhH4Wmkf1ewC0adbka-bvq55kOHwkaDq728HV5mDriQ1y_8WXW2JNDZZemxAhQD2RcTSrb50WrdkR5NS96Z5V_nEYuvJQY0Qq5_CRExi_wmpS3E1eJoaGpS5PC8Jc1FlscogQ/s1548/gas_create_spreadsheet_4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="764" data-original-width="1548" height="158" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYLl0AaQQwGIM9ZnCpAzO2rtWBcVAuOwHr9jzKanKREF7QXWp-53hFFI7fhH4Wmkf1ewC0adbka-bvq55kOHwkaDq728HV5mDriQ1y_8WXW2JNDZZemxAhQD2RcTSrb50WrdkR5NS96Z5V_nEYuvJQY0Qq5_CRExi_wmpS3E1eJoaGpS5PC8Jc1FlscogQ/s320/gas_create_spreadsheet_4.jpg" width="320" /></a></div><br /><div><br /><div>這樣便將 GAS 要寄生的運算平台搭建好了. </div><div><br /></div><div><br /></div><div><b><span style="background-color: #fce5cd; color: #990000;">二. 使用 Logger.log() 輸出訊息 : </span></b> </div><div><br /></div><div>GAS 程式可以單獨存在於雲端硬碟中 (副檔名為 .gs) 或者寄生於 Google Apps 例如文件, 試算表, 或表單之中, 下面是 GAS 寄生在試算表的範例 :</div><div><br /></div><div>在上面所建立的試算表 output_test 中, 點選 "擴充功能/Apps Script" :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCuqmiqnYCwK_-DkK05ZIvLnxV9qdAYxPUwoWupnhJgW3n7QVob5ep9oq-3hZlZWQA545ZZkn-Jg8oOgCokTaRL2teiMr020PYISOzxgc2fuJeamH7r4Rr53SuF3bjYRBr6HhmnQqADbstHMJ6upOJdc1LIiH9223xMAHJxyCFs0NQUrL_qfHlg4vWaQct/s1513/gas_create_script_1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="717" data-original-width="1513" height="152" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCuqmiqnYCwK_-DkK05ZIvLnxV9qdAYxPUwoWupnhJgW3n7QVob5ep9oq-3hZlZWQA545ZZkn-Jg8oOgCokTaRL2teiMr020PYISOzxgc2fuJeamH7r4Rr53SuF3bjYRBr6HhmnQqADbstHMJ6upOJdc1LIiH9223xMAHJxyCFs0NQUrL_qfHlg4vWaQct/s320/gas_create_script_1.jpg" width="320" /></a></div><br /><div><br /></div><div>這樣會彈出一個未命名的 Apps Script 專案新視窗, 裡面已經預設好一個空的函式 myFunction() : </div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8NcyIq5u5lFCCMeTNTcIAV8G-aWrMkqSD161tVxHorI1TTZKrLxafwKEcujywm6LcoY5k_H34yaLqJtxGTa13uBwu2JFmWID-nL5rnclfDDhXYfgfiDCNNxEI03Nr5aNuWjN-DrGtQzITS0vA-v2ZCbdLRN3PM0DGfAMV3WwGzjcAoukMUOu8sFcMDz_L/s1425/gas_create_script_2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="698" data-original-width="1425" height="157" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8NcyIq5u5lFCCMeTNTcIAV8G-aWrMkqSD161tVxHorI1TTZKrLxafwKEcujywm6LcoY5k_H34yaLqJtxGTa13uBwu2JFmWID-nL5rnclfDDhXYfgfiDCNNxEI03Nr5aNuWjN-DrGtQzITS0vA-v2ZCbdLRN3PM0DGfAMV3WwGzjcAoukMUOu8sFcMDz_L/s320/gas_create_script_2.jpg" width="320" /></a></div><br /><div><br /></div><div>點選上方的 "未命名專案", 給它取個新名稱, 例如 output_test, 按 "重新命名" 鈕 :</div><div><br /></div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOmo1wJ5OxNBbZ4c1VxbftGKkp_Ii4LrlWB_PX6zD2zgaZ6gOZOGZu6QXdrsxaXu5rYdvVW98INxCLJaqnqw-O4FqAhm4tIWXZellG_Jg7-tquR5RE2PMqn9Rcm4Y0hS1AEaF3y5g6HLe5eVG3TGGnkPZLj2qTeQEoFqP5Z0O2h6Bie2EzKsiVOg4N-mq_/s931/gas_create_script_3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="649" data-original-width="931" height="223" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOmo1wJ5OxNBbZ4c1VxbftGKkp_Ii4LrlWB_PX6zD2zgaZ6gOZOGZu6QXdrsxaXu5rYdvVW98INxCLJaqnqw-O4FqAhm4tIWXZellG_Jg7-tquR5RE2PMqn9Rcm4Y0hS1AEaF3y5g6HLe5eVG3TGGnkPZLj2qTeQEoFqP5Z0O2h6Bie2EzKsiVOg4N-mq_/s320/gas_create_script_3.jpg" width="320" /></a></div><br /> </div><div>這樣上方的 Apps Script 專案名稱就變成 output_test 了, 接著在 myFunction() 中輸入程式碼, 這裡使用 Logger 物件的 log() 方法輸出 "Hello World!" 字串, 然後按上方的 "儲存專案" 鈕 : </div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_JZB6YiCV_NamCj_sFgvHqdzMPl63kEbgd5tMy3LRis-OX901h7Rtywa7BCKCejOHHb_l5MbqH8j6kAO8PJMx_glWLZgtPrLAF7-cr2xohxBepum77iTCBM1qoKZteAYuTWuVBtS9CjIYyDyOXvTDSk4ooUbb7eYYT8uTsxuXBsrE9oUMLp4siFrB7qpE/s1364/gas_create_script_4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="698" data-original-width="1364" height="164" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_JZB6YiCV_NamCj_sFgvHqdzMPl63kEbgd5tMy3LRis-OX901h7Rtywa7BCKCejOHHb_l5MbqH8j6kAO8PJMx_glWLZgtPrLAF7-cr2xohxBepum77iTCBM1qoKZteAYuTWuVBtS9CjIYyDyOXvTDSk4ooUbb7eYYT8uTsxuXBsrE9oUMLp4siFrB7qpE/s320/gas_create_script_4.jpg" width="320" /></a></div><br /><div class="separator" style="clear: both; text-align: left;"><br /></div><div>儲存完畢後上方的 "執行" 鍵才會變成可按, 按此按鈕即可執行程式碼, 結果會顯示於下方的 "執行記錄" 窗格內 : </div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhn-QCHHD1nVwK6qnDtbgPJtRrKDOjBdluIhZkIa2_SmUuX1lmYuwJ2IS8Bl4OZi8BKuqp3jGm2BLciHOokboys0XCwF2jySu3S86Udr5kdODZrrxb5KXYbzM3Z_r1vCskWYlSQZPzuBVvqIBsHVusbyyw_E7Qij59ftnbBlWObVaZY4VEIKJLWNfgChdhx/s1617/gas_create_script_5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="726" data-original-width="1617" height="144" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhn-QCHHD1nVwK6qnDtbgPJtRrKDOjBdluIhZkIa2_SmUuX1lmYuwJ2IS8Bl4OZi8BKuqp3jGm2BLciHOokboys0XCwF2jySu3S86Udr5kdODZrrxb5KXYbzM3Z_r1vCskWYlSQZPzuBVvqIBsHVusbyyw_E7Qij59ftnbBlWObVaZY4VEIKJLWNfgChdhx/s320/gas_create_script_5.jpg" width="320" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpVf0tOCsEKs2QoCA9AG0t2PKgJzWOTh01GyYMgjNUqDisI4GYlZLHSDAZyQZlAicMBGYJH5L4tyRBKM9G6PNs_vmGEzTF5zZgostFT604VTkZJ5Q9qcNYpqcQ1rVfWaSMpPfcZyNx6FhmHFZiVtt1maFJJiyzDbmeQnyZRyHfUBIhJVq20OQzpfn8HA13/s1644/gas_create_script_6.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="872" data-original-width="1644" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpVf0tOCsEKs2QoCA9AG0t2PKgJzWOTh01GyYMgjNUqDisI4GYlZLHSDAZyQZlAicMBGYJH5L4tyRBKM9G6PNs_vmGEzTF5zZgostFT604VTkZJ5Q9qcNYpqcQ1rVfWaSMpPfcZyNx6FhmHFZiVtt1maFJJiyzDbmeQnyZRyHfUBIhJVq20OQzpfn8HA13/s320/gas_create_script_6.jpg" width="320" /></a></div><br /><div><br /></div><div>如果將要輸出檢視的變數傳給 Logger.log() 便能看到變數值, 可協助程式偵錯. </div><div><br /></div><div>注意, 如果切回雲端硬碟底下的 GAS 資料夾, 會發現根本不存在這個 "程式碼.gs" 檔案, 因為此 Script 專案是寄生在試算表 "output_test" 裡面. </div><div><br /></div><div>我們也可以建立獨立 (standalone) 於 App 外的 GAS 程式檔, 按雲端硬碟左上角的 "+ 新增" 按鈕, 然後點選選單底下的 "更多", 再點選 "Google Apps Script" :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzQ_AguC79Yl_sAU3Nj1KqHyo8mVXCSV04rKfr5sQaLTZwTdWPuCFUni0XhEGOSwfFdLuF5vmGeu6_rXl6wcchsrO1Ynr8929I6H8TJt0fX-6UyeEYGcqaQLxT5wlX1CG8iu4VGk474Kktkeuzmsr7MPrvrziVg_7DBSJ_BfMiqSCUviQAgIAnuWL30Snl/s1404/gas_create_standalone_script_1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="930" data-original-width="1404" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzQ_AguC79Yl_sAU3Nj1KqHyo8mVXCSV04rKfr5sQaLTZwTdWPuCFUni0XhEGOSwfFdLuF5vmGeu6_rXl6wcchsrO1Ynr8929I6H8TJt0fX-6UyeEYGcqaQLxT5wlX1CG8iu4VGk474Kktkeuzmsr7MPrvrziVg_7DBSJ_BfMiqSCUviQAgIAnuWL30Snl/s320/gas_create_standalone_script_1.jpg" width="320" /></a></div><br /><div><br /></div><div>這時會彈出一個視窗, 提醒用這方式建立的程式碼所有協作者均可執行, 按 "建立指令碼" :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBC7e-mvzYQu93w9lWsyPtnQ1us-ssGQHNp_A0ovIF0iXnqV8BLQlzmHPtR99PjaACSwFCfd4Jzz1WyEv0SOa9PzPnZ48LzFRFB3Z2zYqmdJwjP97fZWQg1PVpB3oSNU5XynQSPdUiAr_ZvwCWG7z-ctuwxbT6e6lhFf6-zzR5MTDMNR5jmTodNA81z0T1/s1202/gas_create_standalone_script_2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="444" data-original-width="1202" height="118" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBC7e-mvzYQu93w9lWsyPtnQ1us-ssGQHNp_A0ovIF0iXnqV8BLQlzmHPtR99PjaACSwFCfd4Jzz1WyEv0SOa9PzPnZ48LzFRFB3Z2zYqmdJwjP97fZWQg1PVpB3oSNU5XynQSPdUiAr_ZvwCWG7z-ctuwxbT6e6lhFf6-zzR5MTDMNR5jmTodNA81z0T1/s320/gas_create_standalone_script_2.jpg" width="320" /></a></div><br /><div><br /></div><div>這時會產生一個未命名的 Apps Script 專案新視窗 : </div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0LMkNLUhexrqOzw7hZ7anUNEsTXsMeJpnRu5WqIkOlm-k3CycZXzuNw__OAlPM_H5rzJct3EMV7aYJkXN-EJ-vGk5PPkP7fPodv7GJ3Gbt9znVK5vpe9NfjEc7aUZg-Dh4K-R0weoaDNpp4tN5Id0wIj94yA6JgSm_syk92hwauIN4fClyInUFWbrEhDd/s1612/gas_create_standalone_script_3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="736" data-original-width="1612" height="146" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0LMkNLUhexrqOzw7hZ7anUNEsTXsMeJpnRu5WqIkOlm-k3CycZXzuNw__OAlPM_H5rzJct3EMV7aYJkXN-EJ-vGk5PPkP7fPodv7GJ3Gbt9znVK5vpe9NfjEc7aUZg-Dh4K-R0weoaDNpp4tN5Id0wIj94yA6JgSm_syk92hwauIN4fClyInUFWbrEhDd/s320/gas_create_standalone_script_3.jpg" width="320" /></a></div><br /><div><br /></div><div>雖然與上面試算表中建立的 Script 專案介面一模一樣, 但不同之處是此處所建立的專案會在雲端硬碟底下建立一個 .gs 檔案 (未命名的專案) : </div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggBBx15GQRLHB96IjWrW_cm7e4o01F7xYf-TJHxgyznALCNgq4raWW16xaGiA5v9rKb6DyQJc6s06ABXcqnWs0IDWY6sXYThwRX7n3qmnu6113igmXNkmz1uLIvngPe_p0w8v1xkO9pl7itV-1e8oPeBPWSWuVEeoyBjW920PrRi6P0hcNfyhvt8PxrZdn/s1521/gas_create_standalone_script_4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="789" data-original-width="1521" height="166" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggBBx15GQRLHB96IjWrW_cm7e4o01F7xYf-TJHxgyznALCNgq4raWW16xaGiA5v9rKb6DyQJc6s06ABXcqnWs0IDWY6sXYThwRX7n3qmnu6113igmXNkmz1uLIvngPe_p0w8v1xkO9pl7itV-1e8oPeBPWSWuVEeoyBjW920PrRi6P0hcNfyhvt8PxrZdn/s320/gas_create_standalone_script_4.jpg" width="320" /></a></div><br /><div><br /></div><div>回到此獨立的專案視窗, 按左上角的 "未命名專案" 更改名稱為 output_test_standalone : </div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTrqBRTCbYfW_3Yy-5GvEszDbzk6-uYwsuaWeVsWrrvh4jC5KrN0qvsXDAmeYPZpg5-uenpt7jld1Z95IQwh5cEY23T_tHSKAQyO_tIfNnQ3GQv9g04xL7JuqPbp87s_L7wGm-kl7FBJQ44iFCSYa0rRJk_qD-O3zw7wr35PIagIc7wGQYEwXYhWEBkJyV/s848/gas_create_standalone_script_5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="637" data-original-width="848" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTrqBRTCbYfW_3Yy-5GvEszDbzk6-uYwsuaWeVsWrrvh4jC5KrN0qvsXDAmeYPZpg5-uenpt7jld1Z95IQwh5cEY23T_tHSKAQyO_tIfNnQ3GQv9g04xL7JuqPbp87s_L7wGm-kl7FBJQ44iFCSYa0rRJk_qD-O3zw7wr35PIagIc7wGQYEwXYhWEBkJyV/s320/gas_create_standalone_script_5.jpg" width="320" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDhCaTcJzCyGiUvlZLCcPpPGnXLn_MGnZgQEjNu_qG_r9DBrOxgtf5o4M9FChBeW9iPX9VsIEy8ci-4QNNFdmyCP8ZY2WpFQdUZgoQNO8OclJMMN0gI2EftE639z-xYaXlc8uT7g5_GGIxlZ9Yu0XvR8nSyLnth4PhceHnrvDsevtIl0irG2_GqX8VDh_A/s1601/gas_create_standalone_script_6.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="741" data-original-width="1601" height="148" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDhCaTcJzCyGiUvlZLCcPpPGnXLn_MGnZgQEjNu_qG_r9DBrOxgtf5o4M9FChBeW9iPX9VsIEy8ci-4QNNFdmyCP8ZY2WpFQdUZgoQNO8OclJMMN0gI2EftE639z-xYaXlc8uT7g5_GGIxlZ9Yu0XvR8nSyLnth4PhceHnrvDsevtIl0irG2_GqX8VDh_A/s320/gas_create_standalone_script_6.jpg" width="320" /></a></div><br /><div>這時再回到雲端硬碟視窗, 就會看到專案名稱已經改成 output_test_standalone.gs 了 :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXg-DR81BT60dUO-dBd8SMMIZ9X5OxN1lpPW4vv5m1fyHhDMYr-SFEjLICeMOPmYjITpuvA3dlx35gVWCSNWmnmLDCoX2H4F3ZVO33WhuAUgivcp9Jz4OOrL88vhfrRmysLyf0d4L5DbJ4i_6M5j9Jyynbe7CjJDLYk5nJ32KvvDUzCY6vSSLQtSMVyP2I/s1544/gas_create_standalone_script_7.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="757" data-original-width="1544" height="157" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXg-DR81BT60dUO-dBd8SMMIZ9X5OxN1lpPW4vv5m1fyHhDMYr-SFEjLICeMOPmYjITpuvA3dlx35gVWCSNWmnmLDCoX2H4F3ZVO33WhuAUgivcp9Jz4OOrL88vhfrRmysLyf0d4L5DbJ4i_6M5j9Jyynbe7CjJDLYk5nJ32KvvDUzCY6vSSLQtSMVyP2I/s320/gas_create_standalone_script_7.jpg" width="320" /></a></div><br /><div><br /></div><div>回到專案視窗, 於 myFunction() 中同樣輸入與上面相同的程式碼 Logger.log('Hello World!'), 按上方 "儲存檔案" 後, 再按 "執行" 鈕 : </div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrpPk8p3Pn3nTLwLKHgjn06ikE9XPGvyfQRNiHLi2x5j6clRE2m2OHI8ZcaGvsDmdKw1Ct73mSN5AAm4c6d7H2Scc1DGqvsbJDPLBnTZfGr4gv7YR9GnEP5HR4pTR2oIuldf_NqoZs-QbMN5zeIUdq1rC-JGJgvtBxE8NfF4-6rrqbJv8i3WnmoKMJxRD3/s1610/gas_create_standalone_script_8.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="742" data-original-width="1610" height="147" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrpPk8p3Pn3nTLwLKHgjn06ikE9XPGvyfQRNiHLi2x5j6clRE2m2OHI8ZcaGvsDmdKw1Ct73mSN5AAm4c6d7H2Scc1DGqvsbJDPLBnTZfGr4gv7YR9GnEP5HR4pTR2oIuldf_NqoZs-QbMN5zeIUdq1rC-JGJgvtBxE8NfF4-6rrqbJv8i3WnmoKMJxRD3/s320/gas_create_standalone_script_8.jpg" width="320" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTQHOTcUHil_Al_i9mUGka7xJRMJNocsFc2DDUS3IOPv0Oh0T4ilEjmA9G1ka4XtkwCtyY393iKoEIA5z3vt9w0rNxHttbokM_jWPNk5l3-etzqhJXpDz8Bv_Ma3_oXXfEwcTljbIez9ijs6HQG2wtWvbM6MhfATcIyKr702J2aPn1n0ARcNumC2Pzpq51/s1645/gas_create_standalone_script_9.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="890" data-original-width="1645" height="173" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTQHOTcUHil_Al_i9mUGka7xJRMJNocsFc2DDUS3IOPv0Oh0T4ilEjmA9G1ka4XtkwCtyY393iKoEIA5z3vt9w0rNxHttbokM_jWPNk5l3-etzqhJXpDz8Bv_Ma3_oXXfEwcTljbIez9ijs6HQG2wtWvbM6MhfATcIyKr702J2aPn1n0ARcNumC2Pzpq51/s320/gas_create_standalone_script_9.jpg" width="320" /></a></div><div><br /></div><br /><div>可見結果與上面寄生於試算表 App 的程式是一樣的. </div><div><br /></div></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-25991834804573828252024-03-15T23:08:00.001+08:002024-03-15T23:10:03.402+08:00Google Apps Script 共讀筆記 (2024-03-15)今天共讀由陳文舟與謝老師講授, 主題是利用 Coze 的 AI 協作功能撰寫 Google 試算表爬蟲程式 (Excel 的 VBA 語言) 擷取自選股行情再串接 Line Notify, 課程簡報如下 (這是用 Canva 寫的, 按右上角 "分享" 可下載 PDF 檔) :<div><br /></div><div># <a href="https://www.canva.com/design/DAF_gOww-0g/nacrJ7j8jyliUbrKpxGgYw/view" target="_blank">https://www.canva.com/design/DAF_gOww-0g/nacrJ7j8jyliUbrKpxGgYw/view</a></div><div><br /></div><div>我因要去圖書館還書只聽了一半. 殘念. 但其實我 VBA 不熟, 雖然利用 AI 就能幫忙 Coding, 但看不懂程式碼總是會感到不踏實啊!</div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-52595132756448400142024-03-15T07:31:00.007+08:002024-03-15T10:26:32.531+08:00Google Apps Script 共讀筆記 (2024-03-14)<div>昨天 GAS 共讀是由高手 K 先生講解如何利用 ChatGPT 協作寫出抓取證交所公開資料 (例如成交量最大的前 20 支股票), 簡報資料如下 :</div><div><br /></div><div># <a href="https://gamma.app/docs/GAS01-zycdsa2lzzb0kvi?mode=doc" target="_blank">https://gamma.app/docs/GAS01-zycdsa2lzzb0kvi?mode=doc</a></div><div><br /></div><div>轉錄如下 : </div><div><br /></div><div><div>天氣轉股票 : <a href="https://chat.openai.com/share/fd1ab90e-dd49-44fb-ae04-1c3d974ba37e" target="_blank">https://chat.openai.com/share/fd1ab90e-dd49-44fb-ae04-1c3d974ba37e</a></div><div>設定目標價 : <a href="https://chat.openai.com/share/83cb2923-d5d9-44d0-a7ec-c64cdb60b2bd" target="_blank">https://chat.openai.com/share/83cb2923-d5d9-44d0-a7ec-c64cdb60b2bd</a></div></div><div><div>每日成交量 : <br /><a href="https://openapi.twse.com.tw/" target="_blank">https://openapi.twse.com.tw/</a></div><div><a href="https://openapi.twse.com.tw/v1/exchangeReport/MI_INDEX20" target="_blank">https://openapi.twse.com.tw/v1/exchangeReport/MI_INDEX20</a> </div><div>集中市場每日成交量前二十名證券 (按Model可以看變數資訊)</div></div><div><div>Line Notify : <a href="https://chat.openai.com/share/e78a3373-5f80-4c81-897f-48d76670aa93" target="_blank">https://chat.openai.com/share/e78a3373-5f80-4c81-897f-48d76670aa93</a></div></div><div><div>Line Bot : <a href="https://chat.openai.com/share/f3dc20f5-71d0-436e-af0a-117e27a537a9" target="_blank">https://chat.openai.com/share/f3dc20f5-71d0-436e-af0a-117e27a537a9</a></div></div><div><div>Notify : <a href="https://docs.google.com/spreadsheets/d/1F281hoKhCrW6K_tGS1RyifFCD1dU0frwiFseuTqQ54o/edit?usp=sharing" target="_blank">https://docs.google.com/spreadsheets/d/1F281hoKhCrW6K_tGS1RyifFCD1dU0frwiFseuTqQ54o/edit?usp=sharing</a></div><div>Bot :</div><div><a href="https://docs.google.com/spreadsheets/d/13JmFjVrxWwTgfS0smMvkFu53XAWOUBRJLzKyRx1WJ4I/edit?usp=sharing" target="_blank">https://docs.google.com/spreadsheets/d/13JmFjVrxWwTgfS0smMvkFu53XAWOUBRJLzKyRx1WJ4I/edit?usp=sharing</a></div></div><div><br /></div><div>雖然網路爬蟲用 Python 最方便, 但 24 小時執行環境是個問題 (可惜 Heroku 已經取消免費帳戶了) , GAS 倒是一個不錯的免費方案. </div><div><br /></div><div>PS : 因為我有兩台 Pi 3 與一台 Mapleboard 主機, 都是 24 小時運轉, 所以其實我都用 Python 搞定爬蟲, GAS 只是我的替代方案. </div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-75684767177768579842024-03-14T23:56:00.008+08:002024-03-14T23:57:43.209+08:00購買 Hahow 互動藝術程式設計入門課程<div>經過兩三回考慮, 今天終於手刀直下購買了 Hahow 的互動藝術程式設計入門 :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVq0ERK31ao2SKbnc424K70c2Vd0WS-MBPWtmVhzyuUnDw6Vk0A9oNpMvcg-UjzIj63hYVzDH5V7KNzUcSGjt-L-_WfEQ7JpgxZFs9RuUZT2AzYkpXJNkdD-Z21Io-gsjUaDuFoys_BiYDiSxTBTQ-fiwfHLHjhgZ_dUrl1aC7UNawcyxB0OJGSCNdnOdm/s2074/%E8%B3%BC%E8%B2%B7Hahow%E5%89%B5%E6%84%8F%E4%BA%92%E5%8B%95%E7%A8%8B%E5%BC%8F%E8%A8%AD%E8%A8%88%E8%AA%B2%E7%A8%8B.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="996" data-original-width="2074" height="154" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVq0ERK31ao2SKbnc424K70c2Vd0WS-MBPWtmVhzyuUnDw6Vk0A9oNpMvcg-UjzIj63hYVzDH5V7KNzUcSGjt-L-_WfEQ7JpgxZFs9RuUZT2AzYkpXJNkdD-Z21Io-gsjUaDuFoys_BiYDiSxTBTQ-fiwfHLHjhgZ_dUrl1aC7UNawcyxB0OJGSCNdnOdm/s320/%E8%B3%BC%E8%B2%B7Hahow%E5%89%B5%E6%84%8F%E4%BA%92%E5%8B%95%E7%A8%8B%E5%BC%8F%E8%A8%AD%E8%A8%88%E8%AA%B2%E7%A8%8B.jpg" width="320" /></a></div><br /><div><br /></div><div>原價 2400 元, 折扣後實付 2007 元. </div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-33217569763050175162024-03-14T23:43:00.004+08:002024-03-15T10:24:06.505+08:00OpenAI API 學習筆記 : 使用 openai 套件串接 GPT 語言模型 (一)<div>昨天維元老師的 ChatGPT 實戰內訓課程講到 OpenAI API 串接實作, 我因在前一篇測試中已經註冊 OpenAI 帳戶並建立了存取 GPT 模型的金鑰, 所以就能在課堂上邊聽邊在 Colab 上測試, 本篇記錄利用 openai 這個 Python 套件與模型的串接與對話.</div><div><br /></div><div>本系列之前的文章參考 :</div><div><br /></div><div># <a href="https://yhhuang1966.blogspot.com/2024/02/openai-api-openai-api.html" target="_blank">OpenAI API 學習筆記 : 註冊 OpenAI 帳戶與建立 API 金鑰</a></div><div><br /></div><div>要串接 OpenAI API 必須先取得金鑰才能進行本篇測試. </div><div><br /></div><div><br /></div><div><b><span style="background-color: #fce5cd; color: #990000;">一. 安裝 openai 套件 : </span></b></div><div><br /></div><div>串接 OpenAI API 必須先安裝 openai 套件 : </div><div><br /></div><div><b><span style="color: #2b00fe;">pip install openai</span></b> </div><div><br /></div><div>如果是在 Colab 則指令前面要冠驚嘆號 :</div><div><br /></div><div><b><span style="color: #2b00fe;">!pip install openai</span></b> </div><div><br /></div><div><div>D:\python\test><b><span style="color: #2b00fe;">pip install openai</span></b> </div><div>Collecting openai</div><div> Downloading openai-1.14.0-py3-none-any.whl.metadata (18 kB)</div><div>Requirement already satisfied: anyio<5,>=3.5.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from openai) (3.7.1)</div><div>Collecting distro<2,>=1.7.0 (from openai)</div><div> Downloading distro-1.9.0-py3-none-any.whl.metadata (6.8 kB)</div><div>Requirement already satisfied: httpx<1,>=0.23.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from openai) (0.24.1)</div><div>Requirement already satisfied: pydantic<3,>=1.9.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from openai) (2.5.3)</div><div>Requirement already satisfied: sniffio in c:\users\tony1\appdata\roaming\python\python310\site-packages (from openai) (1.3.0)</div><div>Requirement already satisfied: tqdm>4 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from openai) (4.66.1)</div><div>Requirement already satisfied: typing-extensions<5,>=4.7 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from openai) (4.9.0)</div><div>Requirement already satisfied: idna>=2.8 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from anyio<5,>=3.5.0->openai) (3.4)</div><div>Requirement already satisfied: exceptiongroup in c:\users\tony1\appdata\roaming\python\python310\site-packages (from anyio<5,>=3.5.0->openai) (1.1.3)</div><div>Requirement already satisfied: certifi in c:\users\tony1\appdata\roaming\python\python310\site-packages (from httpx<1,>=0.23.0->openai) (2023.7.22)</div><div>Requirement already satisfied: httpcore<0.18.0,>=0.15.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from httpx<1,>=0.23.0->openai) (0.17.3)</div><div>Requirement already satisfied: annotated-types>=0.4.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from pydantic<3,>=1.9.0->openai) (0.5.0)</div><div>Requirement already satisfied: pydantic-core==2.14.6 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from pydantic<3,>=1.9.0->openai) (2.14.6)</div><div>Requirement already satisfied: colorama in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from tqdm>4->openai) (0.4.6)</div><div>Requirement already satisfied: h11<0.15,>=0.13 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from httpcore<0.18.0,>=0.15.0->httpx<1,>=0.23.0->openai) (0.14.0)</div><div>Downloading openai-1.14.0-py3-none-any.whl (257 kB)</div><div> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 257.5/257.5 kB 933.1 kB/s eta 0:00:00</div><div>Downloading distro-1.9.0-py3-none-any.whl (20 kB)</div><div>Installing collected packages: distro, openai</div><div>Successfully installed distro-1.9.0 openai-1.14.0</div></div><div><br /></div><div>先用 import openai 匯入套件, 然後用 dir() 檢視套件內容 : </div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">import openai</span></b> </div><div><div>>>> <b><span style="color: #2b00fe;">print(openai.__version__)</span></b> </div><div>1.14.0</div></div><div>>>> <b><span style="color: #2b00fe;">dir(openai)</span></b> </div></div><div>['APIConnectionError', 'APIError', 'APIResponse', 'APIResponseValidationError', 'APIStatusError', 'APITimeoutError', 'AssistantEventHandler', 'AsyncAPIResponse', 'AsyncAssistantEventHandler', 'AsyncAzureOpenAI', 'AsyncClient', 'AsyncOpenAI', 'AsyncStream', 'Audio', 'AuthenticationError', 'AzureOpenAI', 'BadRequestError', 'BaseModel', 'ChatCompletion', 'Client', 'Completion', 'ConflictError', 'Customer', 'DEFAULT_MAX_RETRIES', 'DEFAULT_TIMEOUT', 'Deployment', 'Edit', 'Embedding', 'Engine', 'ErrorObject', 'File', 'FineTune', 'FineTuningJob', 'Image', 'InternalServerError', 'Model', 'Moderation', 'NOT_GIVEN', 'NoneType', 'NotFoundError', 'NotGiven', 'OpenAI', 'OpenAIError', 'PermissionDeniedError', 'ProxiesTypes', 'RateLimitError', 'RequestOptions', 'Stream', 'Timeout', 'Transport', 'UnprocessableEntityError', 'VERSION', '_AmbiguousModuleClientUsageError', '_ApiType', '_AzureModuleClient', '_ModuleClient', '__all__', '__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__locals', '__name', '__name__', '__package__', '__path__', '__spec__', '__title__', '__version__', '_azure', '_base_client', '_client', '_compat', '_constants', '_exceptions', '_extras', '_files', '_has_azure_ad_credentials', '_has_azure_credentials', '_has_openai_credentials', '_httpx', '_legacy_response', '_load_client', '_models', '_module_client', '_os', '_qs', '_reset_client', '_resource', '_response', '_setup_logging', '_streaming', '_t', '_te', '_types', '_utils', '_version', 'annotations', 'api_key', 'api_type', 'api_version', 'audio', 'azure_ad_token', 'azure_ad_token_provider', 'azure_endpoint', 'base_url', 'beta', 'chat', 'completions', 'default_headers', 'default_query', 'embeddings', 'file_from_path', 'files', 'fine_tuning', 'http_client', 'images', 'lib', 'max_retries', 'models', 'moderations', 'organization', 'override', 'pagination', 'resources', 'timeout', 'types', 'version']</div><div><br /></div><div>用 dir() 看不出哪些是類別, 函式, 與模組, 這可用下列自訂模組 members 來達成 :</div><div><br /></div><div><div><div>def list_members(parent_obj):</div><div> members=dir(parent_obj)</div><div> parent_obj_name=????? </div><div> for mbr in members:</div><div> child_obj=eval(parent_obj_name + '.' + mbr) </div><div> if not mbr.startswith('_'):</div><div> print(mbr, type(child_obj)) </div></div><div><br /></div><div><div>參考 :</div><div><br /></div><div># <a href="https://yhhuang1966.blogspot.com/2022/03/python.html" target="_blank">Python 學習筆記 : 檢視物件成員與取得變數名稱字串的方法</a></div></div><div><br /></div><div>將此函式存成 members.py 模組, 放在目前供作目錄下, 然後匯入其 list_members() 函式來檢視 openai 套件 : </div></div><div><br /></div><div>>>> <b><span style="color: #2b00fe;">from members import list_members</span></b> </div><div><div>>>> <b><span style="color: #2b00fe;">list_members(openai)</span></b> </div><div>APIConnectionError <class 'type'></div><div>APIError <class 'type'></div><div>APIResponse <class 'type'></div><div>APIResponseValidationError <class 'type'></div><div>APIStatusError <class 'type'></div><div>APITimeoutError <class 'type'></div><div>AssistantEventHandler <class 'type'></div><div>AsyncAPIResponse <class 'type'></div><div>AsyncAssistantEventHandler <class 'type'></div><div>AsyncAzureOpenAI <class 'type'></div><div>AsyncClient <class 'type'></div><div>AsyncOpenAI <class 'type'></div><div>AsyncStream <class 'type'></div><div>Audio <class 'openai.lib._old_api.APIRemovedInV1Proxy'></div><div>AuthenticationError <class 'type'></div><div>AzureOpenAI <class 'type'></div><div>BadRequestError <class 'type'></div><div>BaseModel <class 'pydantic._internal._model_construction.ModelMetaclass'></div><div>ChatCompletion <class 'openai.lib._old_api.APIRemovedInV1Proxy'></div><div>Client <class 'type'></div><div>Completion <class 'openai.lib._old_api.APIRemovedInV1Proxy'></div><div>ConflictError <class 'type'></div><div>Customer <class 'openai.lib._old_api.APIRemovedInV1Proxy'></div><div>DEFAULT_MAX_RETRIES <class 'int'></div><div>DEFAULT_TIMEOUT <class 'openai.Timeout'></div><div>Deployment <class 'openai.lib._old_api.APIRemovedInV1Proxy'></div><div>Edit <class 'openai.lib._old_api.APIRemovedInV1Proxy'></div><div>Embedding <class 'openai.lib._old_api.APIRemovedInV1Proxy'></div><div>Engine <class 'openai.lib._old_api.APIRemovedInV1Proxy'></div><div>ErrorObject <class 'openai.lib._old_api.APIRemovedInV1Proxy'></div><div>File <class 'openai.lib._old_api.APIRemovedInV1Proxy'></div><div>FineTune <class 'openai.lib._old_api.APIRemovedInV1Proxy'></div><div>FineTuningJob <class 'openai.lib._old_api.APIRemovedInV1Proxy'></div><div>Image <class 'openai.lib._old_api.APIRemovedInV1Proxy'></div><div>InternalServerError <class 'type'></div><div>Model <class 'openai.lib._old_api.APIRemovedInV1Proxy'></div><div>Moderation <class 'openai.lib._old_api.APIRemovedInV1Proxy'></div><div>NOT_GIVEN <class 'openai.NotGiven'></div><div>NoneType <class 'type'></div><div>NotFoundError <class 'type'></div><div>NotGiven <class 'type'></div><div><span style="background-color: #fcff01;">OpenAI</span> <class 'type'></div><div>OpenAIError <class 'type'></div><div>PermissionDeniedError <class 'type'></div><div>ProxiesTypes <class 'typing._UnionGenericAlias'></div><div>RateLimitError <class 'type'></div><div>RequestOptions <class 'typing_extensions._TypedDictMeta'></div><div>Stream <class 'type'></div><div>Timeout <class 'type'></div><div>Transport <class 'type'></div><div>UnprocessableEntityError <class 'type'></div><div>VERSION <class 'str'></div><div>annotations <class '__future__._Feature'></div><div>api_key <class 'NoneType'></div><div>api_type <class 'NoneType'></div><div>api_version <class 'NoneType'></div><div>audio <class 'openai._module_client.AudioProxy'></div><div>azure_ad_token <class 'NoneType'></div><div>azure_ad_token_provider <class 'NoneType'></div><div>azure_endpoint <class 'NoneType'></div><div>base_url <class 'NoneType'></div><div>beta <class 'openai._module_client.BetaProxy'></div><div>chat <class 'openai._module_client.ChatProxy'></div><div>completions <class 'openai._module_client.CompletionsProxy'></div><div>default_headers <class 'NoneType'></div><div>default_query <class 'NoneType'></div><div>embeddings <class 'openai._module_client.EmbeddingsProxy'></div><div>file_from_path <class 'function'></div><div>files <class 'openai._module_client.FilesProxy'></div><div>fine_tuning <class 'openai._module_client.FineTuningProxy'></div><div>http_client <class 'NoneType'></div><div>images <class 'openai._module_client.ImagesProxy'></div><div>lib <class 'module'></div><div>max_retries <class 'int'></div><div>models <class 'openai._module_client.ModelsProxy'></div><div>moderations <class 'openai._module_client.ModerationsProxy'></div><div>organization <class 'NoneType'></div><div>override <class 'function'></div><div>pagination <class 'module'></div><div>resources <class 'module'></div><div>timeout <class 'openai.Timeout'></div><div>types <class 'module'></div><div>version <class 'module'></div></div><div><br /></div><div>可見 openai 套件有非常多成員, 但串接 GPT 大模型只會用到 OpenAI 這個類別. </div><div><br /></div><div><br /></div><div><b><span style="background-color: #fce5cd; color: #990000;">二. 串接 OpenAI API : </span></b></div><div><br /></div><div>串接 API 的程式語法是很制式的, 首先從 openai 套件中匯入 OpenAI 類別 :</div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">from openai import OpenAI</span></b> </div><div><br /></div><div>接著定義一個字串變數儲存金鑰, 例如下列範例 (非真實金鑰) : </div><div><br /></div><div>>>> <b><span style="color: #2b00fe;">api_key='sk-tonyIqevbZyyp3eWNr1966BlbkFJpo5ls6CxBcwvSyHslay2'</span></b> </div><div><br /></div><div>然後呼叫 OpenAI 類別的建構函式 OpenAI() 並將金鑰傳給 api_key 參數, 它會傳回一個 OpenAI 物件 : </div><div><br /></div><div>>>> <b><span style="color: #2b00fe;">client=OpenAI(api_key=api_key)</span></b> </div><div>>>> <b><span style="color: #2b00fe;">type(client)</span></b> </div><div><class 'openai.<span style="background-color: #fcff01;">OpenAI</span>'> </div></div><div><br /></div><div>最後呼叫此 OpenAI 物件的 chat.completions.create() 方法, 並傳入 messages (詢問訊息) 與 model (語言模型) 這兩個參數, 它會傳回一個 ChatCompletion 物件 (即 GPT 生成之回應) :</div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">chat_completion=client.chat.completions.create(</span></b></div><div><b><span style="color: #2b00fe;"> messages=[</span></b></div><div><b><span style="color: #2b00fe;"> {"role": "user",</span></b></div><div><b><span style="color: #2b00fe;"> "content": "請說一個好笑的笑話",</span></b></div><div><b><span style="color: #2b00fe;"> }],</span></b></div><div><b><span style="color: #2b00fe;"> model="gpt-3.5-turbo",</span></b></div><div><b><span style="color: #2b00fe;"> )</span></b></div><div>>>> <b><span style="color: #2b00fe;">type(chat_completion)</span></b> </div><div><class 'openai.types.chat.chat_completion.<span style="background-color: #fcff01;">ChatCompletion</span>'></div></div><div><br /></div><div>參數 message 是一個字典串列, 其中 content 屬性就是我們提出的詢問, 因為我使用的是新註冊者的免費帳戶, 所以只能使用 GTP 3.5 模型, 無法使用 GPT 4. </div><div><br /></div><div>回應物件 ChatCompletion 的內容如下 :</div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">print(chat_completion) </span></b> </div><div>ChatCompletion(id='chatcmpl-92b7YN2M39rI6XvX8eyKlxuTU2SzK', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='為什麼警察不玩撲克牌?因為他們怕抓到一隻大老鼠!哈哈哈哈哈!', role='assistant', function_call=None, tool_calls=None))], created=1710406376, model='gpt-3.5-turbo-0125', object='chat.completion', system_fingerprint='fp_4f2ebda25a', usage=CompletionUsage(completion_tokens=49, prompt_tokens=20, total_tokens=69))</div></div><div><br /></div><div>print() 的輸出是擠成一團的字串, 可讀性差, 可以用第三方套件 rich 的 print() 來輸出可讀性高的物件內容, 關於 rich 參考 :</div><div><br /></div><div># <a href="https://yhhuang1966.blogspot.com/2024/03/python-rich.html" target="_blank">Python 學習筆記 : 豐富終端機視覺效果的 rich 套件</a></div><div><br /></div><div>>>> <b><span style="color: #2b00fe;">import rich</span></b> </div><div>>>> <b><span style="color: #2b00fe;">rich.print(chat_completion)</span></b> </div><div>ChatCompletion(</div><div> id='chatcmpl-92b7YN2M39rI6XvX8eyKlxuTU2SzK',</div><div> <span style="background-color: #fcff01;">choices</span>=[</div><div> Choice(</div><div> finish_reason='stop',</div><div> index=0,</div><div> logprobs=None,</div><div> <span style="background-color: #fcff01;">message</span>=ChatCompletionMessage(</div><div> <span style="background-color: #fcff01;">content</span>='為什麼警察不玩撲克牌?因為他們怕抓到一隻大老鼠!</div><div>哈哈哈哈哈!',</div><div> role='assistant',</div><div> function_call=None,</div><div> tool_calls=None</div><div> )</div><div> )</div><div> ],</div><div> created=1710406376,</div><div> model='gpt-3.5-turbo-0125',</div><div> object='chat.completion',</div><div> system_fingerprint='fp_4f2ebda25a',</div><div> usage=CompletionUsage(</div><div> completion_tokens=49,</div><div> prompt_tokens=20,</div><div> total_tokens=69</div><div> )</div><div>) </div><div><br /></div><div>觀察 ChatCompletion 物件結構, 可知 GPT 的回應內容放在 choices[0].message.content 屬性裡 :</div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">response_message=chat_completion.choices[0].message.content</span></b> </div><div>>>> <b><span style="color: #2b00fe;">print(response_message)</span></b> </div><div>為什麼警察不玩撲克牌?因為他們怕抓到一隻大老鼠!哈哈哈哈哈!</div></div><div><br /></div><div>完整程式碼如下 :</div><div><br /></div><div><div>from openai import OpenAI</div><div><br /></div><div>api_key='sk-tonyIqevbZyyp3eWNr1966BlbkFJpo5ls6CxBcwvSyHslay2'</div><div>client=OpenAI(api_key=api_key)</div><div>chat_completion=client.chat.completions.create(</div><div> messages=[</div><div> {"role": "user",</div><div> "content": "請說一個好笑的笑話",</div><div> }],</div><div> model="gpt-3.5-turbo",</div><div> )</div><div>print(chat_completion)</div><div>response_message=chat_completion.choices[0].message.content</div><div>print(response_message)</div></div><div><br /></div><div><br /></div><div><b><span style="background-color: #fce5cd; color: #990000;">三. 將金鑰儲存在環境變數中 : </span></b></div><div><br /></div><div><div>上面直接將金鑰寫在程式中的作法並不妥當, 因為可能在分享時不經意地洩漏出去, 比較好的做法是將金鑰存在環境變數中, 參考 :</div><div><br /></div><div># <a href="https://yhhuang1966.blogspot.com/2024/01/api.html" target="_blank">Python 學習筆記 : 如何隱藏 API 金鑰或權杖</a></div><div><br /></div><div>首先在目前工作目錄下建立一個檔名為 .env 的純文字隱藏檔, 用 = 把金鑰賦予一個變數名稱, 例如 OPENAI_KEY (注意, 金鑰不可用括號括起來) :</div><div><br /></div><div>OPENAI_KEY=sk-tonyIqevbZyyp3eWNr1966BlbkFJpo5ls6CxBcwvSyHslay2 </div><div><br /></div><div>然後安裝第三方套件 python-decouple 或 python-dotenv, 此處以 python-dotenv 為例 :</div><div><br /></div><div><b><span style="color: #2b00fe;">pip install python-dotenv</span></b> </div><div><br /></div><div>這樣就可以匯入 dotenv 模組的 load_dotenv() 函式來載入環境變數檔 .env, 並配合使用 os.getenv() 來取得環境變數中的指定金鑰了 : </div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">from dotenv import load_dotenv</span></b> </div><div>>>> <b><span style="color: #2b00fe;">import os</span></b> </div><div>>>> <b><span style="color: #2b00fe;">load_dotenv()</span></b> </div><div>True</div><div><div>>>> <b><span style="color: #2b00fe;">api_key=os.environ.get('OPENAI_API')</span></b> </div><div>>>> <b><span style="color: #2b00fe;">print(api_key)</span></b> </div></div><div>sk-tonyIqevbZyyp3eWNr1966BlbkFJpo5ls6CxBcwvSyHslay2 </div></div><div><br /></div><div>>>> <b><span style="color: #2b00fe;">client=OpenAI(api_key=api_key)</span></b> </div><div><div>>>> <b><span style="color: #2b00fe;">chat_completion=client.chat.completions.create(</span></b></div><div><b><span style="color: #2b00fe;"> messages=[</span></b></div><div><b><span style="color: #2b00fe;"> {"role": "user",</span></b></div><div><b><span style="color: #2b00fe;"> "content": "請說一個好笑的笑話",</span></b></div><div><b><span style="color: #2b00fe;"> }],</span></b></div><div><b><span style="color: #2b00fe;"> model="gpt-3.5-turbo",</span></b></div><div><b><span style="color: #2b00fe;"> )</span></b></div></div><div><div>>>> <b><span style="color: #2b00fe;">response_message=chat_completion.choices[0].message.content</span></b> </div><div>>>> <b><span style="color: #2b00fe;">print(response_message)</span></b> </div><div>為什麼警察不玩撲克牌?因為他們怕抓到一隻大老鼠!哈哈哈哈哈!</div></div><div><br /></div></div><div>完整程式碼如下 : </div><div><br /></div><div><div>import os</div><div>from dotenv import load_dotenv</div><div>from openai import OpenAI</div><div><br /></div><div>load_dotenv()</div><div>api_key=os.environ.get('OPENAI_API')</div><div>client=OpenAI(api_key=api_key)</div><div>chat_completion=client.chat.completions.create(</div><div> messages=[</div><div> {"role": "user",</div><div> "content": "請說一個好笑的笑話",</div><div> }],</div><div> model="gpt-3.5-turbo",</div><div> )</div><div>print(chat_completion)</div><div>response_message=chat_completion.choices[0].message.content</div><div>print(response_message)</div></div><div><br /></div><div>這樣就可避免在程式中直接揭露金鑰的問題了. </div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-47184381249297295692024-03-14T11:48:00.007+08:002024-03-14T11:50:38.955+08:00Python 學習筆記 : 豐富終端機視覺效果的 rich 套件昨天終於把 Hahow 企業版的 "AI 一把抓" 的兩門課程看完, 其中學到一個好用的套件 rich, 它可以將字典物件以整齊易讀方式列印出來, 而不是像 print() 那樣將鍵值對全部串在一起印出來, 看起來是一坨亂亂的資料. 不過這只是 rich 的一個功能而已, 如其名所示, rich 主要的目的是讓 Python 命令列的顯示功能更豐富, 參考官網介紹 :<div><div><br /></div><div># <a href="https://rich.readthedocs.io/en/stable/index.html" target="_blank">https://rich.readthedocs.io/en/stable/index.html</a> </div><div><br /></div><div><br /></div><div><b><span style="background-color: #fce5cd; color: #990000;">一. 安裝 rich 套件 : </span></b> </div><div><br /></div><div>Rich 是第三方套件, 必須用 pip install 先安裝才能使用 :</div><div><br /></div><div><b><span style="color: #2b00fe;">pip install rich</span></b></div><div><br /></div><div><div>D:\python\test><b><span style="color: #2b00fe;">pip install rich</span></b> </div><div>Collecting rich</div><div> Downloading rich-13.7.1-py3-none-any.whl.metadata (18 kB)</div><div>Collecting markdown-it-py>=2.2.0 (from rich)</div><div> Downloading markdown_it_py-3.0.0-py3-none-any.whl.metadata (6.9 kB)</div><div>Collecting pygments<3.0.0,>=2.13.0 (from rich)</div><div> Downloading pygments-2.17.2-py3-none-any.whl.metadata (2.6 kB)</div><div>Collecting mdurl~=0.1 (from markdown-it-py>=2.2.0->rich)</div><div> Downloading mdurl-0.1.2-py3-none-any.whl.metadata (1.6 kB)</div><div>Downloading rich-13.7.1-py3-none-any.whl (240 kB)</div><div> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 240.7/240.7 kB 866.3 kB/s eta 0:00:00</div><div>Downloading markdown_it_py-3.0.0-py3-none-any.whl (87 kB)</div><div> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 87.5/87.5 kB 1.6 MB/s eta 0:00:00</div><div>Downloading pygments-2.17.2-py3-none-any.whl (1.2 MB)</div><div> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 2.0 MB/s eta 0:00:00</div><div>Downloading mdurl-0.1.2-py3-none-any.whl (10.0 kB)</div><div>Installing collected packages: pygments, mdurl, markdown-it-py, rich</div><div>Successfully installed markdown-it-py-3.0.0 mdurl-0.1.2 pygments-2.17.2 rich-13.7.1</div></div></div><div><br /></div><div>用 dir() 檢視模組內容 :</div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">dir(rich)</span></b> </div><div>['Any', 'Callable', 'IO', 'Optional', 'TYPE_CHECKING', 'Union', '_IMPORT_CWD', '__all__', '__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '_cell_widths', '_console', '_emoji_codes', '_emoji_replace', '_export_format', '_extension', '_fileno', '_log_render', '_loop', '_null_file', '_palettes', '_pick', '_ratio', '_win32_console', '_windows', '_windows_renderer', '_wrap', 'abc', 'align', 'ansi', 'box', 'cells', 'color', 'color_triplet', 'console', 'constrain', 'containers', 'control', 'default_styles', 'emoji', 'errors', 'get_console', 'highlighter', 'inspect', 'jupyter', 'load_ipython_extension', 'markup', 'measure', 'os', 'padding', 'pager', 'palette', 'panel', 'pretty', 'print', 'print_json', 'protocol', 'reconfigure', 'region', 'repr', 'scope', 'screen', 'segment', 'style', 'styled', 'table', 'terminal_theme', 'text', 'theme', 'themes']</div></div><div><br /></div><div>用下列自訂模組來檢視其類別與函式等成員 : </div><div><br /></div><div><div><div>def list_members(parent_obj):</div><div> members=dir(parent_obj)</div><div> parent_obj_name=????? </div><div> for mbr in members:</div><div> child_obj=eval(parent_obj_name + '.' + mbr) </div><div> if not mbr.startswith('_'):</div><div> print(mbr, type(child_obj)) </div></div><div><br /></div><div>將此函式存成 members.py 模組, 放在目前供作目錄下, 然後匯入其 list_members() 函式來檢視 technews 套件 : </div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">from members import list_members</span></b> </div><div>>>> <b><span style="color: #2b00fe;">list_members(rich)</span></b> </div></div></div><div><div>Any <class 'typing._SpecialForm'></div><div>Callable <class 'typing._CallableType'></div><div>IO <class 'type'></div><div>Optional <class 'typing._SpecialForm'></div><div>TYPE_CHECKING <class 'bool'></div><div>Union <class 'typing._SpecialForm'></div><div>abc <class 'module'></div><div>align <class 'module'></div><div>ansi <class 'module'></div><div>box <class 'module'></div><div>cells <class 'module'></div><div>color <class 'module'></div><div>color_triplet <class 'module'></div><div><span style="background-color: #fcff01;">console</span> <class 'module'></div><div>constrain <class 'module'></div><div>containers <class 'module'></div><div>control <class 'module'></div><div>default_styles <class 'module'></div><div>emoji <class 'module'></div><div>errors <class 'module'></div><div>get_console <class 'function'></div><div>highlighter <class 'module'></div><div>inspect <class 'function'></div><div>jupyter <class 'module'></div><div>load_ipython_extension <class 'function'></div><div>markup <class 'module'></div><div>measure <class 'module'></div><div>os <class 'module'></div><div>padding <class 'module'></div><div>pager <class 'module'></div><div>palette <class 'module'></div><div>panel <class 'module'></div><div>pretty <class 'module'></div><div><span style="background-color: #fcff01;">print</span> <class 'function'></div><div><span style="background-color: #fcff01;">print_json</span> <class 'function'></div><div>protocol <class 'module'></div><div>reconfigure <class 'function'></div><div>region <class 'module'></div><div>repr <class 'module'></div><div>scope <class 'module'></div><div>screen <class 'module'></div><div>segment <class 'module'></div><div>style <class 'module'></div><div>styled <class 'module'></div><div>table <class 'module'></div><div>terminal_theme <class 'module'></div><div>text <class 'module'></div><div>theme <class 'module'></div><div>themes <class 'module'></div></div><div><br /></div><div>可見 rich 套件提供了豐富的功能, 其中 print() 函式最常被用來輸出結構化資料. </div><div><br /></div><div>參考 :</div><div><br /></div><div># <a href="https://yhhuang1966.blogspot.com/2022/03/python.html" target="_blank">Python 學習筆記 : 檢視物件成員與取得變數名稱字串的方法</a></div><div><br /></div><div><br /></div><div><b><span style="background-color: #fce5cd; color: #990000;">二. 列印結構化資料 : </span></b> </div><div><br /></div><div>Python 的資料結構例如字典, 集合, 與串列等, 如果使用內建的 print() 列印會以字元串方式顯示, 這樣就不容易看出其結構, 例如下面這個較複雜的字典物件 : </div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">campaign={ </span></b></div><div><b><span style="color: #2b00fe;"> "發起人": "小昭",</span></b></div><div><b><span style="color: #2b00fe;"> "名稱": "喵星人大集合",</span></b></div><div><b><span style="color: #2b00fe;"> "日期": "2024-03-20",</span></b></div><div><b><span style="color: #2b00fe;"> "時間": "08:00:00",</span></b></div><div><b><span style="color: #2b00fe;"> "地點": "夢想公園",</span></b></div><div><b><span style="color: #2b00fe;"> "粉絲團": ["@愛貓圈", "@鏟屎官俱樂部"]</span></b></div><div><b><span style="color: #2b00fe;"> }</span></b> </div><div><br /></div><div>用 print() 列印時會輸出一個長字串, 可讀性較差 :</div><div><br /></div><div>>>> <b><span style="color: #2b00fe;">print(campaign)</span></b> </div><div>{'發起人': '小昭', '名稱': '喵星人大集合', '日期': '2024-03-20', '時間': '08:00:00', '地點': '夢想公園', '粉絲團': ['@愛貓圈', '@鏟屎官俱樂部']}</div><div><br /></div><div>如果使用 rich.print() 則會以鍵值結構顯示, 可讀性變高 : </div><div><br /></div><div>>>> <b><span style="color: #2b00fe;">import rich</span></b> </div><div>>>> <b><span style="color: #2b00fe;">rich.print(campaign)</span></b> </div><div>{</div><div> '發起人': '小昭',</div><div> '名稱': '喵星人大集合',</div><div> '日期': '2024-03-20',</div><div> '時間': '08:00:00',</div><div> '地點': '夢想公園',</div><div> '粉絲團': ['@愛貓圈', '@鏟屎官俱樂部']</div><div>}</div></div><div><br /></div><div>官網教學文件建議也可以先建立 Console 物件, 然後呼叫其 print() 方法輸出 :</div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">from rich.console import Console</span></b> </div><div>>>> <b><span style="color: #2b00fe;">console=Console()</span></b> </div></div><div><div>>>> <b><span style="color: #2b00fe;">console.print(campaign)</span></b> </div><div>{</div><div> '發起人': '小昭',</div><div> '名稱': '喵星人大集合',</div><div> '日期': '2024-03-20',</div><div> '時間': '08:00:00',</div><div> '地點': '夢想公園',</div><div> '粉絲團': ['@愛貓圈', '@鏟屎官俱樂部']</div><div>}</div></div><div><br /></div><div><br /></div><div><b><span style="background-color: #fce5cd; color: #990000;">三. 在命令提示字元視窗列印彩色文字 :</span></b> </div><div><br /></div><div>Rich 套件還可以在命令列顯示彩色文字, 參考下面這篇網路教學文件 :</div><div><br /></div><div># <a href="https://sdwh.dev/posts/2020/07/Python-Rich/" target="_blank">Python Rich Library - 豐富 Terminal 視覺化效果的函式庫</a></div><div><br /></div><div>>>> <b><span style="color: #2b00fe;">from rich.console import Console</span></b> </div><div><div>>>> <b><span style="color: #2b00fe;">console=Console()</span></b> </div><div>>>> <b><span style="color: #2b00fe;">for color in ['red', 'blue', 'green', 'yellow', 'white', 'black', 'magenta', 'cyan']:</span></b> </div><div>... <b><span style="color: #2b00fe;">console.print(f"Hello World! <span style="background-color: #fcff01;">{color}</span> bold", <span style="background-color: #fcff01;">style=f"{color} bold"</span>)</span></b> </div><div>... <b><span style="color: #2b00fe;">console.print(f"Hello World! <span style="background-color: #fcff01;">{color}</span>", <span style="background-color: #fcff01;">style=f"{color}"</span>)</span></b> </div><div>... </div></div><div><br /></div><div>結果如下 :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJQjxDixHNJ1QKQL3zj2S8PyQ0Wyp57YhfZ8_GUN98BqNCbHHDG-v1O6qvFf6dVvVmHs1TuoTPHYMYgnbc24rlFV84CIH_utKUJvyiB6ZUywtxSTRxNMREGdhrucjtEo_XEReqgJoRaPbrDxsVe0ooGHOfAATx8TPR1EjThbEvMheqZNU99kP6SOcA52WM/s1730/python_rich_colorful.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="911" data-original-width="1730" height="169" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJQjxDixHNJ1QKQL3zj2S8PyQ0Wyp57YhfZ8_GUN98BqNCbHHDG-v1O6qvFf6dVvVmHs1TuoTPHYMYgnbc24rlFV84CIH_utKUJvyiB6ZUywtxSTRxNMREGdhrucjtEo_XEReqgJoRaPbrDxsVe0ooGHOfAATx8TPR1EjThbEvMheqZNU99kP6SOcA52WM/s320/python_rich_colorful.jpg" width="320" /></a></div><br /><div class="separator" style="clear: both; text-align: left;"><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-25128717029919895502024-03-13T23:17:00.002+08:002024-03-13T23:17:38.335+08:00淋雨一直走<div>今天在 YT 看到張韶涵的這首 "淋雨一直走", 雖然年代有點久了, 但那輕快的節奏與激勵人心的歌詞仍然令人驚艷 : </div><div><br /></div><div># <a href="https://www.youtube.com/watch?v=WTcodZDH-Oc" target="_blank">https://www.youtube.com/watch?v=WTcodZDH-Oc</a></div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen="" class="BLOG_video_class" height="266" src="https://www.youtube.com/embed/WTcodZDH-Oc" width="320" youtube-src-id="WTcodZDH-Oc"></iframe></div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-21067209593262786512024-03-13T15:00:00.007+08:002024-03-13T21:17:41.044+08:00金石堂買書 5 本<div>昨天傍晚去楠梓載菁菁回家 (從泰國回來的晚上載姐姐去搭高鐵順路載菁菁去工作室, 機車放在家裡), 回程去高鐵二樓環球商場的金石堂書店取書, 其實上周櫃台小姐通知所訂 5 本書已全到貨, 但配合菁菁要花掉她的文化幣約定 3/12 日取貨. </div><div><br /></div><div>因高鐵附近停車不易, 我乾脆從台鐵左營新站這邊開進高鐵停車場, 停好車穿過高鐵站區到另一側台鐵站區環球商場二樓的金石堂, 因滿額有優惠分兩次將 2400 元文化幣用完後剩下 624 元刷卡, 菁菁說原來電腦書不便宜耶! 這五本書定價合起來 3420 元 :</div><div><ol style="text-align: left;"><li><a href="https://www.kingstone.com.tw/basic/2013120691247" style="background-color: white;" target="_blank">ChatGPT 開發手冊 Turbo×Vision 進化版—用 OpenAI Chat/Assistants API.Function calling 設計 GPTs action.LINE/Discord bot.股市分析/自動助理</a> $820</li><li><a href="https://www.kingstone.com.tw/basic/2013120687882" target="_blank">ChatGPT 4 Turbo 萬用手冊 2024 春季號:提示工程、超強外掛、My GPTs、OpenAI API、Midjourney、Copilot、Bard、Claude 2</a> $680</li><li><a href="https://www.kingstone.com.tw/basic/2013120668010" target="_blank">ChatGPT 4 萬用手冊 2023 秋季號:超強外掛、Prompt、LineBot、OpenAI API、Midjourney、Stable</a> $680</li><li><a href="https://www.kingstone.com.tw/basic/2013120691797" style="background-color: white;" target="_blank">跟 NVIDIA 學深度學習!從基本神經網路到 CNN.RNN.LSTM.seq2seq.Transformer.GPT.BERT...,紮穩機器視覺與大型語言模型 (LLM) 的建模基礎</a> $748</li><li><a href="https://www.kingstone.com.tw/basic/2014713665669" target="_blank">最新LINE官方帳號|邁向百萬星級店家</a> $500</li></ol></div><div>實付 1740+1284=3024 元 (約 88 折), 扣掉文化幣刷卡 624 元 3024-2400=624. 這 5 本書夠我讀一整年了, 基本上旗標去年到今年出版的重磅 ChatGPT 開發書籍盡入囊中矣, 既然是菁菁有心'送給我的, 那要更用心來練功了, 哈哈! </div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-72021213815983045522024-03-13T10:26:00.006+08:002024-03-13T11:36:52.513+08:00大寮民權街倉庫快捷走法<div style="text-align: left;">昨天午休時到大寮民權街倉庫幫菁菁取貨 (在蝦皮買的方形飲料瓶), 雖然上回去過一次, 但沒有導航還是沒把握, 前幾天買的冷氣孔手機架到貨, 所以這次除了用車上的 Garmin 導航外, 也把 S24U 放在手機架用 Google 導航, 但主要還是以 Garmin 為主. 不意外地, Garmin 走法仍然是穿越大智橋下走鳳仁路轉神農路, 而 Google 則是在神農路前一個路口叫我右轉, 我這回聽 Google 的 (比 Garmin 準). </div><div style="text-align: left;"><br /></div><div style="text-align: left;">雖然順利取貨 (但訂五箱卻只剩 3 箱), 但回到公司已 13:20 (因為裝好貨還跟老闆娘閒聊了一下), 快速吃完午餐就上班了. 回來時走民權街 > 民智街 > 鳳屏路, 覺得這樣是最近的路徑啊! 就直接上大智橋接鳳屏路, 看到中油加油站就向左轉入民智街直走即可接民權街, Garmin 幹嘛導航到神農路繞一大圈啊! 傻眼. </div><div style="text-align: left;"><br /></div><div style="text-align: left;">我把走法抓圖記錄如下 :</div><div style="text-align: left;"><br /></div><div style="text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6a9xMM7PnmWd8_w6c4z8KBAat7b_x1bV1fyT5FyXpe6s3TjovjBz21QtinO7YLp564GqYBayx8kwH4og-UI_gxtqHLdQmNT_QB3eL4Ko1sQexc36XIODkwcGuG7zbQy6skdLaTADWvLbtAT2Z6_QE9Fm1SSGAbxgtyL8-Pm1g49HafkdXXTVIzzeddjOz/s1992/%E8%8F%81%E8%8F%81%E9%A3%B2%E6%96%99%E7%93%B6%E5%A4%A7%E5%AF%AE%E5%8F%96%E8%B2%A8%E5%80%89%E5%BA%AB-1.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1225" data-original-width="1992" height="197" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6a9xMM7PnmWd8_w6c4z8KBAat7b_x1bV1fyT5FyXpe6s3TjovjBz21QtinO7YLp564GqYBayx8kwH4og-UI_gxtqHLdQmNT_QB3eL4Ko1sQexc36XIODkwcGuG7zbQy6skdLaTADWvLbtAT2Z6_QE9Fm1SSGAbxgtyL8-Pm1g49HafkdXXTVIzzeddjOz/s320/%E8%8F%81%E8%8F%81%E9%A3%B2%E6%96%99%E7%93%B6%E5%A4%A7%E5%AF%AE%E5%8F%96%E8%B2%A8%E5%80%89%E5%BA%AB-1.jpg" width="320" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqFu1kSRgYAIJ1tuWK0Wtq9Umdq_KZ1s383-VwIZawzUD7pe3rBCzGwGc6JATYHFbX9wlNG59R4Qda5PmZA87vMEPJeQAulZlYZnoUbY73ZVAwCXLPNZd6s3vzAyckRbBpeJ5famQMi6SipnrzUjsXZW5Gbux-v8SeAr-ZZnMtHRviLGFtjVVU0rFStB0m/s1981/%E8%8F%81%E8%8F%81%E9%A3%B2%E6%96%99%E7%93%B6%E5%A4%A7%E5%AF%AE%E5%8F%96%E8%B2%A8%E5%80%89%E5%BA%AB-2.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1215" data-original-width="1981" height="196" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqFu1kSRgYAIJ1tuWK0Wtq9Umdq_KZ1s383-VwIZawzUD7pe3rBCzGwGc6JATYHFbX9wlNG59R4Qda5PmZA87vMEPJeQAulZlYZnoUbY73ZVAwCXLPNZd6s3vzAyckRbBpeJ5famQMi6SipnrzUjsXZW5Gbux-v8SeAr-ZZnMtHRviLGFtjVVU0rFStB0m/s320/%E8%8F%81%E8%8F%81%E9%A3%B2%E6%96%99%E7%93%B6%E5%A4%A7%E5%AF%AE%E5%8F%96%E8%B2%A8%E5%80%89%E5%BA%AB-2.jpg" width="320" /></a></div><div><br /></div><div><br /></div><div>以後這樣走來回大約 50 分鐘就搞定了. </div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-48697901682528992772024-03-13T09:03:00.007+08:002024-03-13T11:36:24.546+08:00光輝歲月<div>昨天偶然聽到這首歌, 旋律似曾相識, 原來是香港搖滾樂團 <a href="https://zh.wikipedia.org/zh-tw/Beyond" target="_blank">Beyond</a> 的經典名曲, 此曲為主唱<a href="https://zh.wikipedia.org/wiki/%E9%BB%83%E5%AE%B6%E9%A7%92" target="_blank">黃家駒</a>為了向南非人權鬥士曼德拉致敬所寫, 1990 年榮獲十大中文金曲獎.</div><div><br /></div><div># <a href="https://www.youtube.com/watch?v=moyTKdIiKwU" target="_blank">https://www.youtube.com/watch?v=moyTKdIiKwU</a></div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen="" class="BLOG_video_class" height="266" src="https://www.youtube.com/embed/moyTKdIiKwU" width="320" youtube-src-id="moyTKdIiKwU"></iframe></div><br /><div><br /></div><div>"<span style="background-color: #fcff01;">風雨中抱緊自由</span>", 這是咱台灣人在群魔亂舞時代的心情. </div><div><br /></div><div>孫露也翻唱過這首歌 :</div><div><br /></div><div># <a href="https://www.youtube.com/watch?v=r93fKKeJBxA" target="_blank">https://www.youtube.com/watch?v=r93fKKeJBxA</a></div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen="" class="BLOG_video_class" height="266" src="https://www.youtube.com/embed/r93fKKeJBxA" width="320" youtube-src-id="r93fKKeJBxA"></iframe></div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-71777419221123203382024-03-12T10:23:00.004+08:002024-03-13T08:30:06.012+08:00Python 學習筆記 : 用 technews-tw 爬台灣科技新聞網站 (一)我在 "<a href="https://www.books.com.tw/products/0010906039" target="_blank">Python Bible 實戰聖經</a>" (碁峰, 2021) 這本書第二章讀到使用 technews-tw 套件爬取台灣四大科技新聞網站 (<a href="https://www.ithome.com.tw/" target="_blank">ithome 電腦報</a>, <a href="https://buzzorange.com/techorange/" target="_blank">orange 科技報橘</a>, <a href="https://www.bnext.com.tw/" target="_blank">business 數位時代</a>, <a href="https://www.inside.com.tw/" target="_blank">inside 硬塞的</a>) 的介紹, 今日得空便實作一番. <div><br /></div><div>不過實際測試卻發現, 此套件已經於 2023 年停止對 orange 科技報橘的支援, 可能是該網站變動頻繁, 使套件維護變得很困難, 參考此套件之 GitHub 說明 : </div><div><br /></div><div># <a href="https://github.com/WisChang005/technews_tw" target="_blank">https://github.com/WisChang005/technews_tw</a><br /><div><br /></div><div><br /></div><div><b><span style="background-color: #fce5cd; color: #990000;">一. 安裝 technews-tw 套件 :</span></b></div><div><br /></div><div>使用 pip 直接安裝 :</div><div><br /></div><div><b><span style="color: #2b00fe;">pip install technews-tw</span></b><br /><div><br /></div><div><div>D:\python\test><b><span style="color: #2b00fe;">pip install technews-tw</span></b> </div><div>Collecting technews-tw</div><div> Downloading technews_tw-1.3.5-py3-none-any.whl.metadata (2.3 kB)</div><div>Collecting bs4 (from technews-tw)</div><div> Downloading bs4-0.0.2-py2.py3-none-any.whl.metadata (411 bytes)</div><div>Requirement already satisfied: requests in c:\users\tony1\appdata\roaming\python\python310\site-packages (from technews-tw) (2.31.0)</div><div>Requirement already satisfied: html5lib in c:\users\tony1\appdata\roaming\python\python310\site-packages (from technews-tw) (1.1)</div><div>Requirement already satisfied: lxml in c:\users\tony1\appdata\roaming\python\python310\site-packages (from technews-tw) (4.9.3)</div><div>Collecting twine (from technews-tw)</div><div> Downloading twine-5.0.0-py3-none-any.whl.metadata (3.3 kB)</div><div>Requirement already satisfied: wheel in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from technews-tw) (0.41.1)</div><div>Requirement already satisfied: setuptools in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from technews-tw) (65.5.0)</div><div>Requirement already satisfied: beautifulsoup4 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from bs4->technews-tw) (4.12.2)</div><div>Requirement already satisfied: six>=1.9 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from html5lib->technews-tw) (1.16.0)</div><div>Requirement already satisfied: webencodings in c:\users\tony1\appdata\roaming\python\python310\site-packages (from html5lib->technews-tw) (0.5.1)</div><div>Requirement already satisfied: charset-normalizer<4,>=2 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests->technews-tw) (3.2.0)</div><div>Requirement already satisfied: idna<4,>=2.5 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests->technews-tw) (3.4)</div><div>Requirement already satisfied: urllib3<3,>=1.21.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests->technews-tw) (2.1.0)</div><div>Requirement already satisfied: certifi>=2017.4.17 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests->technews-tw) (2023.7.22)</div><div>Collecting pkginfo>=1.8.1 (from twine->technews-tw)</div><div> Downloading pkginfo-1.10.0-py3-none-any.whl.metadata (11 kB)</div><div>Collecting readme-renderer>=35.0 (from twine->technews-tw)</div><div> Downloading readme_renderer-43.0-py3-none-any.whl.metadata (2.8 kB)</div><div>Collecting requests-toolbelt!=0.9.0,>=0.8.0 (from twine->technews-tw)</div><div> Downloading requests_toolbelt-1.0.0-py2.py3-none-any.whl.metadata (14 kB)</div><div>Requirement already satisfied: importlib-metadata>=3.6 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from twine->technews-tw) (6.8.0)</div><div>Collecting keyring>=15.1 (from twine->technews-tw)</div><div> Downloading keyring-24.3.1-py3-none-any.whl.metadata (20 kB)</div><div>Collecting rfc3986>=1.4.0 (from twine->technews-tw)</div><div> Downloading rfc3986-2.0.0-py2.py3-none-any.whl.metadata (6.6 kB)</div><div>Requirement already satisfied: rich>=12.0.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from twine->technews-tw) (13.5.3)</div><div>Requirement already satisfied: zipp>=0.5 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from importlib-metadata>=3.6->twine->technews-tw) (3.17.0)</div><div>Collecting jaraco.classes (from keyring>=15.1->twine->technews-tw)</div><div> Downloading jaraco.classes-3.3.1-py3-none-any.whl.metadata (2.7 kB)</div><div>Requirement already satisfied: pywin32-ctypes>=0.2.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from keyring>=15.1->twine->technews-tw) (0.2.2)</div><div>Collecting nh3>=0.2.14 (from readme-renderer>=35.0->twine->technews-tw)</div><div> Downloading nh3-0.2.15-cp37-abi3-win_amd64.whl.metadata (1.8 kB)</div><div>Requirement already satisfied: docutils>=0.13.1 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from readme-renderer>=35.0->twine->technews-tw) (0.20.1)</div><div>Requirement already satisfied: Pygments>=2.5.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from readme-renderer>=35.0->twine->technews-tw) (2.16.1)</div><div>Requirement already satisfied: markdown-it-py>=2.2.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from rich>=12.0.0->twine->technews-tw) (3.0.0)</div><div>Requirement already satisfied: soupsieve>1.2 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from beautifulsoup4->bs4->technews-tw) (2.4.1)</div><div>Requirement already satisfied: mdurl~=0.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from markdown-it-py>=2.2.0->rich>=12.0.0->twine->technews-tw) (0.1.2)</div><div>Collecting more-itertools (from jaraco.classes->keyring>=15.1->twine->technews-tw)</div><div> Downloading more_itertools-10.2.0-py3-none-any.whl.metadata (34 kB)</div><div>Downloading technews_tw-1.3.5-py3-none-any.whl (12 kB)</div><div>Downloading bs4-0.0.2-py2.py3-none-any.whl (1.2 kB)</div><div>Downloading twine-5.0.0-py3-none-any.whl (37 kB)</div><div>Downloading keyring-24.3.1-py3-none-any.whl (38 kB)</div><div>Downloading pkginfo-1.10.0-py3-none-any.whl (30 kB)</div><div>Downloading readme_renderer-43.0-py3-none-any.whl (13 kB)</div><div>Downloading requests_toolbelt-1.0.0-py2.py3-none-any.whl (54 kB)</div><div> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.5/54.5 kB 941.3 kB/s eta 0:00:00</div><div>Downloading rfc3986-2.0.0-py2.py3-none-any.whl (31 kB)</div><div>Downloading nh3-0.2.15-cp37-abi3-win_amd64.whl (563 kB)</div><div> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 563.7/563.7 kB 1.5 MB/s eta 0:00:00</div><div>Downloading jaraco.classes-3.3.1-py3-none-any.whl (6.8 kB)</div><div>Downloading more_itertools-10.2.0-py3-none-any.whl (57 kB)</div><div> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 57.0/57.0 kB 3.1 MB/s eta 0:00:00</div><div>Installing collected packages: nh3, rfc3986, readme-renderer, pkginfo, more-itertools, requests-toolbelt, jaraco.classes, bs4, keyring, twine, technews-tw</div><div>Successfully installed bs4-0.0.2 jaraco.classes-3.3.1 keyring-24.3.1 more-itertools-10.2.0 nh3-0.2.15 pkginfo-1.10.0 readme-renderer-43.0 requests-toolbelt-1.0.0 rfc3986-2.0.0 technews-tw-1.3.5 twine-5.0.0</div></div><div><br /></div></div><div><br /></div><div><b><span style="background-color: #fce5cd; color: #990000;">二. 檢視套件內容 :</span></b></div><div><br /></div><div>雖然安裝時的套件名稱為 technews-tw, 但實際匯入時的套件名稱是 technews, 先用 dir() 觀察套件內容 : </div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">import technews</span></b> </div><div>>>> <b><span style="color: #2b00fe;">dir(technews)</span></b> </div><div>['EmailContentHelper', '<span style="background-color: #fcff01;">TechNews</span>', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'crawlers', 'mail_helper', 'technews_helper']</div></div><div><br /></div><div>可以使用下列自訂模組 members 的 list_members() 來檢視內容 : </div><div><br /></div><div><div>def list_members(parent_obj):</div><div> members=dir(parent_obj)</div><div> parent_obj_name=????? </div><div> for mbr in members:</div><div> child_obj=eval(parent_obj_name + '.' + mbr) </div><div> if not mbr.startswith('_'):</div><div> print(mbr, type(child_obj)) </div></div><div><br /></div><div>將此函式存成 members.py 模組, 放在目前供作目錄下, 然後匯入其 list_members() 函式來檢視 technews 套件 : </div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">from members import list_members</span></b> </div><div>>>> <b><span style="color: #2b00fe;">list_members(technews)</span></b> </div><div>EmailContentHelper <class 'type'></div><div><span style="background-color: #fcff01;">TechNews</span> <class 'type'></div><div>crawlers <class 'module'></div><div>mail_helper <class 'module'></div><div>technews_helper <class 'module'></div></div><div><br /></div><div>我們會用到的是其中的 TechNews 類別, 繼續用此方法來檢視此類別 :</div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">from technews import TechNews</span></b> </div><div>>>> <b><span style="color: #2b00fe;">list_members(TechNews)</span></b> </div><div>get_news_by_page <class 'function'></div><div>get_today_news <class 'function'></div></div><div><br /></div><div>可見 TechNews 類別只有兩個函式 (建立實體後就是方法), 其中 get_today_news() 函式用來取得今天的最新文章 (傳入參數是四大科技新聞網站的英文名稱例如 'orange'); 而 get_news_by_page() 函式則用來取得最近 n 日內的所有科技新聞, 傳入參數為指定之天數.</div><div><br /></div><div><div>參考 :</div><div><br /></div><div># <a href="https://yhhuang1966.blogspot.com/2022/03/python.html" target="_blank">Python 學習筆記 : 檢視物件成員與取得變數名稱字串的方法</a></div></div><div><br /></div><div><br /></div><div><b><span style="background-color: #fce5cd; color: #990000;">三. 爬取今日新聞 :</span></b></div><div><br /></div><div>首先呼叫 TechNesw 類別的建構子 TechNesw() 並傳入網站名稱例如 'ithome', 它會傳回一個 TechNews 物件 :</div><div><br /></div><div>>>> <b><span style="color: #2b00fe;">from technews import TechNews</span></b> </div><div><div>>>> <b><span style="color: #2b00fe;">news=TechNews('ithome')</span></b> </div><div>>>> <b><span style="color: #2b00fe;">type(news)</span></b> </div><div><class 'technews.technews_helper.<span style="background-color: #fcff01;">TechNews</span>'> </div><div><br /></div><div>用 dir() 與 list_members() 檢視此物件 :</div><div><br /></div><div>>>> <b><span style="color: #2b00fe;">dir(news)</span></b> </div><div>['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_init_news_object', 'get_news_by_page', 'get_today_news', 'news_name', 'news_obj']</div><div><div>>>> <b><span style="color: #2b00fe;">list_members(news)</span></b> </div><div><span style="background-color: #fcff01;">get_news_by_page</span> <class 'method'></div><div><span style="background-color: #fcff01;">get_today_news</span> <class 'method'></div><div>news_name <class 'str'></div><div>news_obj <class 'technews.crawlers.ithome.<span style="background-color: #fcff01;">iThome</span>'></div></div><div><br /></div></div><div>可見 TechNews 物件比類別多出兩個成員 : news_name 字串與 news_obj 物件, 前者紀錄新聞網站名稱, 後者為該新聞網站之爬蟲物件 :</div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">news.news_name</span></b> </div><div>'ithome'</div><div>>>> <b><span style="color: #2b00fe;">news.news_obj</span></b> </div><div><technews.crawlers.ithome.iThome object at 0x0000022AB66BB310></div></div><div><br /></div><div>呼叫 TechNews 物件的 get_today_news() 方法會傳回該網站的今日科技新聞的字典物件, 取得的新聞資料 (標題, 日期, URL 等) 會放在 news_contents 屬性裡 :</div></div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">today_news=news.get_today_news()</span></b> </div><div>>>> <b><span style="color: #2b00fe;">today_news</span></b> </div><div>{'timestamp': 1710197043.7131379, 'news_page_title': 'iThome', 'news_contents': {}, <span style="background-color: #fcff01;">'news_counts': 0</span>}</div></div><div><br /></div><div>此處因為爬取時間太早, 故 news_counts 屬性為 0, 而 news_contents 為空字典. 一般在早上八點後應該就可以爬取到資料 :</div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">today_news</span></b> </div><div>{'timestamp': 1710203639.9777424, 'news_page_title': 'iThome', 'news_contents': {'17bed16d5c1012f0b2b065c961ccf6cc': {'link': 'https://www.ithome.com.tw/news/161712', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/header-introducing-the-fused-orientation-provider-api-consistent-device-orientation-for-all-.png?itok=3i2nzoAE', 'title': 'Android地圖應用不再亂指路,Google公開更準確的裝置朝向API', 'date': '2024-03-12'}, '4c8735c116f47019b7f75a216a804a3b': {'link': 'https://www.ithome.com.tw/news/161711', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/blog_denoising_safari_anti_fingerprinting_techniques.png?itok=RPbopH1C', 'title': 'Safari 17新加入的進階音訊指紋辨識保護已經被破解', 'date': '2024-03-12'}}, <span style="background-color: #fcff01;">'news_counts': 2</span>}</div></div><div><br /></div><div>可見已爬取到兩條新聞, 回傳值為一個三層的字典結構 : </div><div><br /></div><div>{'timestamp': TTT,</div><div> 'news_page_title': PAGE-1, </div><div> 'news_contents': {'NEWS-1': {'link': URL-1, </div><div> 'image': IMG-1,</div><div> 'title': TITLE-1, </div><div> 'date': DAT1-1},</div><div><div> 'NEWS-2': {'link': URL-2, </div><div> 'image': IMG-2,</div><div> 'title': TITLE-2, </div><div> 'date': DAT1-2},</div></div><div> ,,,...</div><div> }</div><div> }</div><div><br /></div><div>新聞內容放在 news_contnets 屬性下, 先將其取出存放在變數 : </div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">news_contents=today_news['news_contents'] </span></b> </div><div>>>> <b><span style="color: #2b00fe;">news_contents</span></b> </div><div>{<span style="background-color: #fcff01;">'17bed16d5c1012f0b2b065c961ccf6cc'</span>: {'link': 'https://www.ithome.com.tw/news/161712', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/header-introducing-the-fused-orientation-provider-api-consistent-device-orientation-for-all-.png?itok=3i2nzoAE', 'title': 'Android地圖應用不再亂指路,Google公開更準確的裝置朝向API', 'date': '2024-03-12'}, <span style="background-color: #fcff01;">'4c8735c116f47019b7f75a216a804a3b'</span>: {'link': 'https://www.ithome.com.tw/news/161711', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/blog_denoising_safari_anti_fingerprinting_techniques.png?itok=RPbopH1C', 'title': 'Safari 17新加入的進階音訊指紋辨識保護已經被破解', 'date': '2024-03-12'}}</div></div><div><div><br /></div><div>可見每一則新聞都有各自的 key, 新聞內容是放在值裡面, 只要用迴圈迭代此 key 的值即可取得新聞內容, 利用 title, link, 與 date 屬性即可分別取得新聞的標題, 連結與日期 : </div><div><br /></div><div>>>> <b><span style="color: #2b00fe;">for key in news_contents:</span></b> </div><div> <b><span style="color: #2b00fe;">contents=news_contents[key]</span></b> # 取得新聞內容 (字典)</div><div> <b><span style="color: #2b00fe;">print('標題:', contents['title'])</span></b> </div><div> <b><span style="color: #2b00fe;">print('連結:', contents['link'])</span></b> </div><div> <b><span style="color: #2b00fe;">print('日期:', contents['date'])</span></b> </div><div> <b><span style="color: #2b00fe;">print('----')</span></b> </div><div> </div><div>標題: Android地圖應用不再亂指路,Google公開更準確的裝置朝向API</div><div>連結: <a href="https://www.ithome.com.tw/news/161712" target="_blank">https://www.ithome.com.tw/news/161712</a></div><div>日期: 2024-03-12</div><div>----</div><div>標題: Safari 17新加入的進階音訊指紋辨識保護已經被破解</div><div>連結: <a href="https://www.ithome.com.tw/news/161711" target="_blank">https://www.ithome.com.tw/news/161711</a></div><div>日期: 2024-03-12</div><div>----</div></div><div><br /></div><div>注意, 超連結是我額外加上去的. </div><div><br /></div><div><br /></div><div><b><span style="background-color: #fce5cd; color: #990000;">三. 爬取最近 N 日新聞 :</span></b></div><div><br /></div><div>呼叫 TechNews 物件的方法 get_news_by_page() 並傳入天數 N 可以取得近 N 日的新聞, 例如取得最近一天的新聞 : </div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">from technews import TechNews</span></b> </div><div>>>> <b><span style="color: #2b00fe;">news=TechNews('ithome')</span></b> </div></div><div><div>>>> <b><span style="color: #2b00fe;">recent_news=news.get_news_by_page(1)</span></b> </div><div>>>> <b><span style="color: #2b00fe;">recent_news</span></b> </div></div><div>{'timestamp': 1710209165.2912116, 'news_page_title': 'iThome', '<span style="background-color: #fcff01;">news_contents</span>': {'111631c3b24ce435f66ff57c59d417d8': {'link': 'https://www.ithome.com.tw/news/161714', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/011_-_large_language_models_on-device_with_mediapipe_and_tensorflow_lite_-_-_developers.googleblog.com_.png?itok=TgeBXlbh', 'title': 'Google讓瀏覽器、Android手機、iPhone都可執行大型語言模型', 'date': '2024-03-12'}, '17bed16d5c1012f0b2b065c961ccf6cc': {'link': 'https://www.ithome.com.tw/news/161712', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/header-introducing-the-fused-orientation-provider-api-consistent-device-orientation-for-all-.png?itok=3i2nzoAE', 'title': 'Android地圖應用不再亂指路,Google公開更準確的裝置朝向API', 'date': '2024-03-12'}, '4c8735c116f47019b7f75a216a804a3b': {'link': 'https://www.ithome.com.tw/news/161711', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/blog_denoising_safari_anti_fingerprinting_techniques.png?itok=RPbopH1C', 'title': 'Safari 17新加入的進階音訊指紋辨識保護已經被破解', 'date': '2024-03-12'}, '88e4ccede6c7f8e4c6d472c0a1f63899': {'link': 'https://www.ithome.com.tw/news/161710', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/ying_mu_xie_qu_hua_mian_2024-03-11_144829.png?itok=VKvAP9cD', 'title': 'Fintech周報第233期:摩根士丹利揭露生成式AI發展策略,要以AI助理促進顧問、顧客和平臺三方無縫互動', 'date': '2024-03-11'}, 'bcf58f7506cb665f52b277eaaa293c2d': {'link': 'https://www.ithome.com.tw/news/161709', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/20240311.jpg?itok=63ICJIL3', 'title': '【資安日報】3月11日,為隱匿攻擊流量,駭客濫用虛擬化平臺QEMU設置網路通訊隧道', 'date': '2024-03-11'}, '84122437386ac3eba6c97c2673748322': {'link': 'https://www.ithome.com.tw/news/161705', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/0609-ai-shi_yi_tu_-tu_pian_lai_yuan_-geralt_on_pixabay-960_0.jpg?itok=tzhMxZhH', 'title': 'GPT-4競爭者報到:Gemini 1.5、Mistral Large、Claude 3 Opus與Inflection-2.5', 'date': '2024-03-11'}, '1b37b718e6ad602724ba5c89c5727cd0': {'link': 'https://www.ithome.com.tw/news/161704', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/1102-ai-photo_by_steve_johnson_on_unsplash-960_1.jpg?itok=sMOmLfa7', 'title': '印度政府揭露IndiaAI,將投入12億美元的預算來發展AI', 'date': '2024-03-11'}, 'eca244c0d345578ecdadb28e3db1decd': {'link': 'https://www.ithome.com.tw/tech/161699', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/arm_neoverse_css-main.jpg?itok=2hyF9E0N', 'title': 'Arm資料中心運算平臺Neoverse邁入第三代,正式增設結合CPU與系統IP的運算子系統', 'date': '2024-03-11'}, '8211ae07720ff436567f2a2465e7f1a2': {'link': 'https://www.ithome.com.tw/news/161703', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/1012-cyber-security-microsoft-guan_fang_tu_pian_-960.jpg?itok=ePC4XRIK', 'title': '微軟遭俄羅斯駭客竊取程式碼、存取內部系統', 'date': '2024-03-11'}, '989c02c3aca1102ced057801f50eea14': {'link': 'https://www.ithome.com.tw/news/161702', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/0518-google-google_health-960_0.jpg?itok=UGiAX8iz', 'title': '公然抗議Google和以色列雲端計畫合約的Google員工遭到解聘', 'date': '2024-03-11'}, 'ab27584158de035ec0bb8c6109f57afe': {'link': 'https://www.ithome.com.tw/news/161701', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/0311-direct-to-cell-starlink-960.jpg?itok=3_Zxq0Qn', 'title': 'Starlink在iPhone、Pixel、Galaxy手機上成功測試傳送文字訊息', 'date': '2024-03-11'}, '9717760dc5f7af83f20698398b974458': {'link': 'https://www.ithome.com.tw/news/161700', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/zi_an_zhou_bao_20240309.jpg?itok=LidaF5ds', 'title': '【資安週報】2024年3月4日到3月8日', 'date': '2024-03-11'}, 'ed6bcf2c3854a02437afe1fc8ebe2623': {'link': 'https://www.ithome.com.tw/news/161698', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/007_-_salesforce_launches_einstein_1_studio_low-code_ai_tools_for_customiz_-_www.salesforce.com_.png?itok=2ay2xDcs', 'title': 'Salesforce推CRM低程式碼AI自定義工具Einstein 1 Studio', 'date': '2024-03-11'}, '913f72dbfb7127a6d49d602d7e012be1': {'link': 'https://www.ithome.com.tw/news/161692', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/006_-_image2.png_1999x1117_-_blogger.googleusercontent.com_.png?itok=Y5ZVXR4p', 'title': 'Google應用社會學習,讓模型間不需交換原始資料就可轉移知識', 'date': '2024-03-11'}, 'c2b1da3db5d76516acb154d307bf18ef': {'link': 'https://www.ithome.com.tw/news/161675', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/openssf-guac.png?itok=tECsOFm8', 'title': '軟體安全評估工具GUAC現成為OpenSSF旗下專案', 'date': '2024-03-11'}, '62b59db4edd588d120600602d03e6b5a': {'link': 'https://www.ithome.com.tw/review/161465', 'image': '…</div><div><br /></div><div><div>傳回值同樣是一個字典, 結構與上面呼叫 today_news() 方法傳回的字典幾乎一樣, 唯一的不同是 get_news_by_page() 傳回的字典沒有 news_count 這個屬性. </div><div><br /></div><div>可見雖然傳入 N=1, 但其實會傳回 3/7~3/12 日的新聞, 而且是按時間倒序排列 (最近的放前面). 新聞內容同樣放在 news_contents 裡面, 先取出放在變數裡 : </div><div><br /></div><div><div>>>> <b><span style="color: #2b00fe;">news_contents=recent_news['news_contents']</span></b> </div><div>>>> <b><span style="color: #2b00fe;">news_contents</span></b> </div></div><div>{'111631c3b24ce435f66ff57c59d417d8': {'link': 'https://www.ithome.com.tw/news/161714', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/011_-_large_language_models_on-device_with_mediapipe_and_tensorflow_lite_-_-_developers.googleblog.com_.png?itok=TgeBXlbh', 'title': 'Google讓瀏覽器、Android手機、iPhone都可執行大型語言模型', 'date': '2024-03-12'}, '17bed16d5c1012f0b2b065c961ccf6cc': {'link': 'https://www.ithome.com.tw/news/161712', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/header-introducing-the-fused-orientation-provider-api-consistent-device-orientation-for-all-.png?itok=3i2nzoAE', 'title': 'Android地圖應用不再亂指路,Google公開更準確的裝置朝向API', 'date': '2024-03-12'}, '4c8735c116f47019b7f75a216a804a3b': {'link': 'https://www.ithome.com.tw/news/161711', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/blog_denoising_safari_anti_fingerprinting_techniques.png?itok=RPbopH1C', 'title': 'Safari 17新加入的進階音訊指紋辨識保護已經被破解', 'date': '2024-03-12'}, '88e4ccede6c7f8e4c6d472c0a1f63899': {'link': 'https://www.ithome.com.tw/news/161710', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/ying_mu_xie_qu_hua_mian_2024-03-11_144829.png?itok=VKvAP9cD', 'title': 'Fintech周報第233期:摩根士丹利揭露生成式AI發展策略,要以AI助理促進顧問、顧客和平臺三方無縫互動', 'date': '2024-03-11'}, 'bcf58f7506cb665f52b277eaaa293c2d': {'link': 'https://www.ithome.com.tw/news/161709', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/20240311.jpg?itok=63ICJIL3', 'title': '【資安日報】3月11日,為隱匿攻擊流量,駭客濫用虛擬化平臺QEMU設置網路通訊隧道', 'date': '2024-03-11'}, '84122437386ac3eba6c97c2673748322': {'link': 'https://www.ithome.com.tw/news/161705', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/0609-ai-shi_yi_tu_-tu_pian_lai_yuan_-geralt_on_pixabay-960_0.jpg?itok=tzhMxZhH', 'title': 'GPT-4競爭者報到:Gemini 1.5、Mistral Large、Claude 3 Opus與Inflection-2.5', 'date': '2024-03-11'}, '1b37b718e6ad602724ba5c89c5727cd0': {'link': 'https://www.ithome.com.tw/news/161704', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/1102-ai-photo_by_steve_johnson_on_unsplash-960_1.jpg?itok=sMOmLfa7', 'title': '印度政府揭露IndiaAI,將投入12億美元的預算來發展AI', 'date': '2024-03-11'}, 'eca244c0d345578ecdadb28e3db1decd': {'link': 'https://www.ithome.com.tw/tech/161699', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/arm_neoverse_css-main.jpg?itok=2hyF9E0N', 'title': 'Arm資料中心運算平臺Neoverse邁入第三代,正式增設結合CPU與系統IP的運算子系統', 'date': '2024-03-11'}, '8211ae07720ff436567f2a2465e7f1a2': {'link': 'https://www.ithome.com.tw/news/161703', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/1012-cyber-security-microsoft-guan_fang_tu_pian_-960.jpg?itok=ePC4XRIK', 'title': '微軟遭俄羅斯駭客竊取程式碼、存取內部系統', 'date': '2024-03-11'}, '989c02c3aca1102ced057801f50eea14': {'link': 'https://www.ithome.com.tw/news/161702', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/0518-google-google_health-960_0.jpg?itok=UGiAX8iz', 'title': '公然抗議Google和以色列雲端計畫合約的Google員工遭到解聘', 'date': '2024-03-11'}, 'ab27584158de035ec0bb8c6109f57afe': {'link': 'https://www.ithome.com.tw/news/161701', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/0311-direct-to-cell-starlink-960.jpg?itok=3_Zxq0Qn', 'title': 'Starlink在iPhone、Pixel、Galaxy手機上成功測試傳送文字訊息', 'date': '2024-03-11'}, '9717760dc5f7af83f20698398b974458': {'link': 'https://www.ithome.com.tw/news/161700', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/zi_an_zhou_bao_20240309.jpg?itok=LidaF5ds', 'title': '【資安週報】2024年3月4日到3月8日', 'date': '2024-03-11'}, 'ed6bcf2c3854a02437afe1fc8ebe2623': {'link': 'https://www.ithome.com.tw/news/161698', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/007_-_salesforce_launches_einstein_1_studio_low-code_ai_tools_for_customiz_-_www.salesforce.com_.png?itok=2ay2xDcs', 'title': 'Salesforce推CRM低程式碼AI自定義工具Einstein 1 Studio', 'date': '2024-03-11'}, '913f72dbfb7127a6d49d602d7e012be1': {'link': 'https://www.ithome.com.tw/news/161692', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/006_-_image2.png_1999x1117_-_blogger.googleusercontent.com_.png?itok=Y5ZVXR4p', 'title': 'Google應用社會學習,讓模型間不需交換原始資料就可轉移知識', 'date': '2024-03-11'}, 'c2b1da3db5d76516acb154d307bf18ef': {'link': 'https://www.ithome.com.tw/news/161675', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/field/image/openssf-guac.png?itok=tECsOFm8', 'title': '軟體安全評估工具GUAC現成為OpenSSF旗下專案', 'date': '2024-03-11'}, '62b59db4edd588d120600602d03e6b5a': {'link': 'https://www.ithome.com.tw/review/161465', 'image': 'https://s4.itho.me/sites/default/files/styles/picture_size_small/public/nvidia_r…</div><div><br /></div><div>每一則新聞都有其 key, 同樣用迴圈迭代此 key 的值即可取得新聞內容, 利用 title, link, 與 date 屬性即可分別取得新聞的標題, 連結與日期 :</div></div><div><br /></div><div><div><div>>>> <b><span style="color: #2b00fe;">for key in news_contents:</span></b> </div><div> <b><span style="color: #2b00fe;">contents=news_contents[key]</span></b> # 取得新聞內容 (字典)</div><div> <b><span style="color: #2b00fe;">print('標題:', contents['title'])</span></b> </div><div> <b><span style="color: #2b00fe;">print('連結:', contents['link'])</span></b> </div><div> <b><span style="color: #2b00fe;">print('日期:', contents['date'])</span></b> </div><div> <b><span style="color: #2b00fe;">print('----')</span></b> </div></div><div> </div><div>標題: Google讓瀏覽器、Android手機、iPhone都可執行大型語言模型</div><div>連結: https://www.ithome.com.tw/news/161714</div><div>日期: 2024-03-12</div><div>----</div><div>標題: Android地圖應用不再亂指路,Google公開更準確的裝置朝向API</div><div>連結: https://www.ithome.com.tw/news/161712</div><div>日期: 2024-03-12</div><div>----</div><div>標題: Safari 17新加入的進階音訊指紋辨識保護已經被破解</div><div>連結: https://www.ithome.com.tw/news/161711</div><div>日期: 2024-03-12</div><div>----</div><div>標題: Fintech周報第233期:摩根士丹利揭露生成式AI發展策略,要以AI助理促進顧問、顧客和平臺三方無縫互動</div><div>連結: https://www.ithome.com.tw/news/161710</div><div>日期: 2024-03-11</div><div>----</div><div>標題: 【資安日報】3月11日,為隱匿攻擊流量,駭客濫用虛擬化平臺QEMU設置網路通訊隧道</div><div>連結: https://www.ithome.com.tw/news/161709</div><div>日期: 2024-03-11</div><div>----</div><div>標題: GPT-4競爭者報到:Gemini 1.5、Mistral Large、Claude 3 Opus與Inflection-2.5</div><div>連結: https://www.ithome.com.tw/news/161705</div><div>日期: 2024-03-11</div><div>----</div><div>標題: 印度政府揭露IndiaAI,將投入12億美元的預算來發展AI</div><div>連結: https://www.ithome.com.tw/news/161704</div><div>日期: 2024-03-11</div><div>----</div><div>標題: Arm資料中心運算平臺Neoverse邁入第三代,正式增設結合CPU與系統IP的運算子系統</div><div>連結: https://www.ithome.com.tw/tech/161699</div><div>日期: 2024-03-11</div><div>----</div><div>標題: 微軟遭俄羅斯駭客竊取程式碼、存取內部系統</div><div>連結: https://www.ithome.com.tw/news/161703</div><div>日期: 2024-03-11</div><div>----</div><div>標題: 公然抗議Google和以色列雲端計畫合約的Google員工遭到解聘</div><div>連結: https://www.ithome.com.tw/news/161702</div><div>日期: 2024-03-11</div><div>----</div><div>標題: Starlink在iPhone、Pixel、Galaxy手機上成功測試傳送文字訊息</div><div>連結: https://www.ithome.com.tw/news/161701</div><div>日期: 2024-03-11</div><div>----</div><div>標題: 【資安週報】2024年3月4日到3月8日</div><div>連結: https://www.ithome.com.tw/news/161700</div><div>日期: 2024-03-11</div><div>----</div><div>標題: Salesforce推CRM低程式碼AI自定義工具Einstein 1 Studio</div><div>連結: https://www.ithome.com.tw/news/161698</div><div>日期: 2024-03-11</div><div>----</div><div>標題: Google應用社會學習,讓模型間不需交換原始資料就可轉移知識</div><div>連結: https://www.ithome.com.tw/news/161692</div><div>日期: 2024-03-11</div><div>----</div><div>標題: 軟體安全評估工具GUAC現成為OpenSSF旗下專案</div><div>連結: https://www.ithome.com.tw/news/161675</div><div>日期: 2024-03-11</div><div>----</div><div>標題: 專業繪圖GPU增加選擇,輝達Ada世代產品提供入門款式</div><div>連結: https://www.ithome.com.tw/review/161465</div><div>日期: 2024-03-08</div><div>----</div><div>標題: Check Point中小企業NGFW添頂級款式,防護全開效能4Gbps</div><div>連結: https://www.ithome.com.tw/review/161663</div><div>日期: 2024-03-08</div><div>----</div><div>標題: Patronus AI發表可用來偵測LLM有否輸出侵權內容的CopyrightCatcher API</div><div>連結: https://www.ithome.com.tw/news/161674</div><div>日期: 2024-03-08</div><div>----</div><div>標題: Inflection釋出可比美GPT-4的Inflection-2.5模型,已部署於Pi聊天機器人</div><div>連結: https://www.ithome.com.tw/news/161671</div><div>日期: 2024-03-08</div><div>----</div><div>標題: PayPal、Venmo在美支援iPhone Tap to Pay</div><div>連結: https://www.ithome.com.tw/news/161670</div><div>日期: 2024-03-08</div><div>----</div><div>標題: 蘋果將讓歐盟用戶把iPhone或iCloud資料搬到Android平臺</div><div>連結: https://www.ithome.com.tw/news/161669</div><div>日期: 2024-03-08</div><div>----</div><div>標題: 記取教訓!2023上市櫃公司資安重訊的啟示</div><div>連結: https://www.ithome.com.tw/article/161665</div><div>日期: 2024-03-08</div><div>----</div><div>標題: 【個資保護成為企業無法迴避的挑戰】企業因個資外洩受罰也是資安重訊</div><div>連結: https://www.ithome.com.tw/news/161667</div><div>日期: 2024-03-08</div><div>----</div><div>標題: 【資安日報】3月8日,Linux惡意軟體攻擊鎖定DevOps常用的4種平臺</div><div>連結: https://www.ithome.com.tw/news/161668</div><div>日期: 2024-03-08</div><div>----</div><div>標題: 【2023年有23起資安事件重大訊息】上市櫃公司屢遭網路攻擊,中小企業災情大增</div><div>連結: https://www.ithome.com.tw/news/161666</div><div>日期: 2024-03-08</div><div>----</div><div>標題: 誠實為上策</div><div>連結: https://www.ithome.com.tw/voice/161662</div><div>日期: 2024-03-08</div><div>----</div><div>標題: 零售一手資料的另類玩法,本土C2C龍頭從百萬賣家數據挖寶</div><div>連結: https://www.ithome.com.tw/people/161661</div><div>日期: 2024-03-08</div><div>----</div><div>標題: Chrome瀏覽器將採用共用字典壓縮技術大幅提升壓縮效率</div><div>連結: https://www.ithome.com.tw/news/161664</div><div>日期: 2024-03-08</div><div>----</div><div>標題: 250+學者連署呼籲AI公司提供研究安全港</div><div>連結: https://www.ithome.com.tw/news/161660</div><div>日期: 2024-03-07</div><div>----</div><div>標題: 微軟工程主管要求董事會對Copilot Designer安全風險事件進行獨立調查</div><div>連結: https://www.ithome.com.tw/news/161659</div><div>日期: 2024-03-07</div><div>----</div></div><div><br /></div><div>下面是爬數位時代 (business) 的結果 :</div><div><br /></div><div><div><div><div>>>> <b><span style="color: #2b00fe;">from technews import TechNews</span></b> </div><div>>>> <b><span style="color: #2b00fe;">news=TechNews('<span style="background-color: #fcff01;">business</span>')</span></b> </div></div><div>>>> <b><span style="color: #2b00fe;">recent_news=news.get_news_by_page(1)</span></b> </div></div><div>>>> <b><span style="color: #2b00fe;">news_contents=recent_news['news_contents']</span></b> </div></div><div><div><div>>>> <b><span style="color: #2b00fe;">for key in news_contents:</span></b> </div><div> <b><span style="color: #2b00fe;">contents=news_contents[key]</span></b> # 取得新聞內容 (字典)</div><div> <b><span style="color: #2b00fe;">print('標題:', contents['title'])</span></b> </div><div> <b><span style="color: #2b00fe;">print('連結:', contents['link'])</span></b> </div><div> <b><span style="color: #2b00fe;">print('日期:', contents['date'])</span></b> </div><div> <b><span style="color: #2b00fe;">print('----')</span></b> </div></div><div> </div><div>標題: 國旅變更貴「一晚4660元」,旅客卻變多!晶華、寒舍營收反彈,真的回血了?</div><div>連結: https://www.bnext.com.tw/article/78570/regent-and-humble-revenue</div><div>日期: 2 小時前</div><div>----</div><div>標題: 攻擊鴻海子公司的LockBit一週就重生!資安3大攻擊趨勢揭密:威脅有哪些?</div><div>連結: https://www.bnext.com.tw/article/78571/cyber-security-2024-trendings</div><div>日期: 2 小時前</div><div>----</div><div>標題: Costco單季進帳上億的秘密武器:賣金條!台灣人也愛買,背後藏著巨頭哪些野心?</div><div>連結: https://www.bnext.com.tw/article/78559/costco-sell-gold-silver</div><div>日期: 3 小時前</div><div>----</div><div>標題: 高股息ETF有哪些?除了0056外還有嗎?10 檔熱門高股息 ETF懶人包一次看</div><div>連結: https://www.bnext.com.tw/article/78569/etf-compare</div><div>日期: 3 小時前</div><div>----</div><div>標題: 00939錯過募集還能買嗎?00939定期定額試算,跟0056、0050差在哪?一次看懂</div><div>連結: https://www.bnext.com.tw/article/78568/00939-etf</div><div>日期: 3 小時前</div><div>----</div><div>標題: 台灣foodpanda曾想賣給Uber Eats?公平會說話了!外送婚事告吹,但2個數字有亮點</div><div>連結: https://www.bnext.com.tw/article/78499/foodpanda-ubereat-taiwan-failed-to-merge</div><div>日期: 4 小時前</div><div>----</div><div>標題: 【圖解】Podcast最新趨勢:你會用YouTube聽嗎?「乾爹」藏在哪?一文看懂</div><div>連結: https://www.bnext.com.tw/article/78521/podcast-soundon-report-2023-trends</div><div>日期: 4 小時前</div><div>----</div><div>標題: 00929最新配息0.13元!00929 ETF懶人包:配息、成分股、選股邏輯一次掌握</div><div>連結: https://www.bnext.com.tw/article/77481/00929-etf</div><div>日期: 4 小時前</div><div>----</div><div>標題: 00940募集首日飆破645億元!00940怎麼買?成份股有什麼?現在上車來得及嗎?</div><div>連結: https://www.bnext.com.tw/article/78535/00940-etf</div><div>日期: 5 小時前</div><div>----</div><div>標題: 矽光子是什麼?真正的矽光子概念股有哪些?圖解矽光子原理</div><div>連結: https://www.bnext.com.tw/article/77079/what-is-silicon-photonics</div><div>日期: 7 小時前</div><div>----</div><div>標題: Z世代意思是什麼?嬰兒潮、X、Y、Z、α世代差在哪?一張圖理解「五代差異」</div><div>連結: https://www.bnext.com.tw/article/63653/marketing-5.0</div><div>日期: 8 小時前</div><div>----</div><div>標題: 直擊全台首座固態電池廠!輝能憑什麼打造「電動車聖杯」?關鍵就在這台印刷機!</div><div>連結: https://www.bnext.com.tw/article/78196/prologium-solid-state-battery</div><div>日期: 15 小時前</div><div>----</div></div><div><br /></div><div>下面是爬硬塞的 (inside) 的結果 : </div><div><br /></div><div><div><div>>>> <b><span style="color: #2b00fe;">from technews import TechNews</span></b> </div><div>>>> <b><span style="color: #2b00fe;">news=TechNews('<span style="background-color: #fcff01;">inside</span>')</span></b> </div></div><div>>>> <b><span style="color: #2b00fe;">recent_news=news.get_news_by_page(1)</span></b> </div></div><div>>>> <b><span style="color: #2b00fe;">news_contents=recent_news['news_contents']</span></b> </div><div><div>>>> <b><span style="color: #2b00fe;">for key in news_contents:</span></b> </div><div> <b><span style="color: #2b00fe;">contents=news_contents[key]</span></b> # 取得新聞內容 (字典)</div><div> <b><span style="color: #2b00fe;">print('標題:', contents['title'])</span></b> </div><div> <b><span style="color: #2b00fe;">print('連結:', contents['link'])</span></b> </div><div> <b><span style="color: #2b00fe;">print('日期:', contents['date'])</span></b> </div><div> <b><span style="color: #2b00fe;">print('----')</span></b> </div></div><div><br /></div><div><div>標題: 川普認為TikTok 禁令可能會影響年輕人,且會讓 Facebook 成為一大受益者。川普曾批評 Meta 在美國國會動亂期,撤銷他 FB 和 IG 帳號。</div><div>連結: https://www.inside.com.tw/article/34445-trump-thinks-tiktok-ban-could-drive-kids-crazy</div><div>日期: 2024-03-12</div><div>----</div><div>標題: Airbnb 禁裝設室內監視器的新政策難以完全防止不肖人士裝隱藏攝影機,但至少能讓守規的房東不再在於出租的房屋放置任何鏡頭,讓房客住得安心一點。</div><div>連結: https://www.inside.com.tw/article/34442-airbnb-bans-indoor-cameras</div><div>日期: 2024-03-12</div><div>----</div><div>標題: 資料海嘯席捲、AI 狂飆時代來臨,完善的資料治理能使資料變成新石油。不分產業都希望結合 AI 分析技術,加速解鎖資料的力量。身兼 Google Cloud 和 SAP 技術合作夥伴的「Epic Cloud 聚上雲」,透過本文帶您探索 SAP BTP(業務技術平台)和 Google Cloud BigQuery 資料處理平台的整合運用之道,跟著聚上雲 from Data to Insights。</div><div>連結: https://www.inside.com.tw/article/34362-EpicCloud</div><div>日期: 2024-03-06</div><div>----</div><div>標題: 針對傳言,裕隆指出,現階段電馳利暫時無代理銷售業務。</div><div>連結: https://www.inside.com.tw/article/34444-geely-in-taiwan</div><div>日期: 2024-03-12</div><div>----</div><div>標題: 隨著社群平台 X 上的討論越來越激烈,也有人質疑「馬斯克嗆聲 OpenAI 不開源,那馬斯克旗下自家 Grok 不也是沒有開源?」然而,就在昨日馬斯克宣布本週將開源 Grok 程式碼,並且將這則貼文置頂於個人頁面上。</div><div>連結: https://www.inside.com.tw/article/34443-musk-xai-to-open-source-gork-this-week</div><div>日期: 2024-03-12</div><div>----</div><div>標題: 二月份,Arm 宣布發表次世代的 Neoverse V 系列:Neoverse V3 CPU 與 Neoverse CSS V3,為全球的合作夥伴提供一條最快的路徑,同時帶來顯著的效能、效率以及差異化的功能,滿足需要最高效能的工作負載與使用場景。</div><div>連結: https://www.inside.com.tw/article/34376-ARM</div><div>日期: 2024-03-05</div><div>----</div><div>標題: 分析師認為,其中一個關鍵是特斯拉的駕駛輔助硬體是否會成為標配,這個硬體的成本可能在 2,000 到 3,000 美元之間,佔掉不少生產成本。</div><div>連結: https://www.inside.com.tw/article/34441-tesla-2027-story-evercore-analysts-model-2-deliveries</div><div>日期: 2024-03-12</div><div>----</div><div>標題: Palantir 公司宣布贏得美國陸軍價值 1.78 億美元的合約,將為其打造一套名為「泰坦」的戰場情報系統。泰坦將被安裝在一輛大型卡車內,用於整合來自太空、高空、空中和地面的感應器數據,為美軍提供可操作的目標資訊,以增強任務指揮和遠端精準打擊能力。</div><div>連結: https://www.inside.com.tw/article/34439-palantir-us-army</div><div>日期: 2024-03-11</div><div>----</div><div>標題: 智慧餐飲管理的雲仲資訊,推出「你訂」線上點餐系統,為餐飲業者帶來便利。透過導入 NUEIP 人資系統,解決了人事流程繁瑣、耗時的問題,提升經營效率。NUEIP 系統的簡易操作、專業客服,是新創企業高速成長的得力搭檔,助力企業安心營造更開放的管理文化,讓夥伴更信任企業。</div><div>連結: https://www.inside.com.tw/article/34276-nueip</div><div>日期: 2024-02-26</div><div>----</div><div>標題: 加密貨幣牛市真的來了嗎?從鏈上數據來看看吧。</div><div>連結: https://www.inside.com.tw/article/34438-has-the-cryptocurrency-bull-market-really-arrived-price-vs-value</div><div>日期: 2024-03-11</div><div>----</div><div>標題: 軍方人員所通報的 UAP 目擊事件都歸因於外國飛機、偵察氣球、大氣異常或只是漂浮空中的碎片。</div><div>連結: https://www.inside.com.tw/article/34437-post-wwii-most-comprehensive-ufo-investigation-us-department-of-defense-no-evidence-of-aliens</div><div>日期: 2024-03-11</div><div>----</div><div>標題: 隨著數位時代詐騙氾濫,打詐防騙已成全民共識。2024 年首場『數位信任』暨『防詐產業』交流會登場,產官學研攜手打造堅固的數位信任生態系統。交流會以「共創數位信任新世界」為主題,探討區塊鏈技術在防詐騙和建立數位信任方面的應用。</div><div>連結: https://www.inside.com.tw/article/34285-JcardVerify</div><div>日期: 2024-02-22</div><div>----</div><div>標題: 首先,我們討論 Meta 全球當機事件,探討臉書、IG、Threads 等平台的異常情況。接著,我們將追蹤比特幣現貨 ETF 的波動,細究其歷史新高又跌落的原因。此外,我們將探討社群平台與用戶快樂程度的關聯,發現 LinkedIn 用戶幸福度最高的趨勢。最後,我們將觸及馬斯克狀告阿特曼事件,探討其與 OpenAI 的關係。</div><div>連結: https://www.inside.com.tw/feature/side-chat/34411-side-chat-e220</div><div>日期: 2024-03-11</div><div>----</div><div>標題: 用於 AirPods 的清理工具設計將以筆型外觀呈現,包含軟刷與清潔凝膠;另一項可凹折螢幕的裝置設計,或許有機會應用在可凹折的 iPad。</div><div>連結: https://www.inside.com.tw/article/34435-apple-new-patents</div><div>日期: 2024-03-11</div><div>----</div><div>標題: 基於想導入一款使行銷、業務、客戶成功 (CS) 等團隊一體適用的 CRM,精耕智慧長照領域的智齡科技,透過專業雲服務商 Epic Cloud 聚上雲,成功導入 HubSpot 這款具備完整行銷+銷售+客服功能的 CRM 軟體,完整串連商機開發、追蹤、維繫,引領客戶成功等關鍵流程,產製報表從 1 小時驟降為 10 分鐘內,平均增速幅度 500%。</div><div>連結: https://www.inside.com.tw/article/34105-EpicCloud</div><div>日期: 2024-02-19</div><div>----</div></div><div><br /></div><div><br /></div><div><b><span style="background-color: #fce5cd; color: #990000;">三. 爬取電腦報/數位時代/硬塞的之今日新聞 :</span></b></div><div><br /></div><div>現在將上面測試整合, 一次取得三家科技新聞網的今日新聞, 由於爬取需要時間, 此處匯入 time 模組, 利用 time.sleep() 等待爬蟲下載資料傳回結果的時間 (約 5 秒以上) : </div><div><br /></div><div>>>> <b><span style="color: #2b00fe;">import time</span></b> </div><div>>>> <b><span style="color: #2b00fe;">from technews import TechNews</span></b> </div><div>>>> <b><span style="color: #2b00fe;">technews=['ithome', 'business', 'inside']</span></b> </div><div><div>>>> <b><span style="color: #2b00fe;">for tn in technews: </span></b></div><div><b><span style="color: #2b00fe;"> news=TechNews(tn)</span></b></div><div><b><span style="color: #2b00fe;"> print(f'---- {tn} ----')</span></b></div><div><b><span style="color: #2b00fe;"> today_news=news.get_today_news()</span></b></div><div><b><span style="color: #2b00fe;"> time.sleep(5)</span></b></div><div><b><span style="color: #2b00fe;"> news_contents=today_news['news_contents']</span></b></div><div><b><span style="color: #2b00fe;"> for key in news_contents: </span></b></div><div><b><span style="color: #2b00fe;"> contents=news_contents[key] # 取得新聞內容 (字典)</span></b></div><div><b><span style="color: #2b00fe;"> print('標題:', contents['title']) </span></b></div><div><b><span style="color: #2b00fe;"> print('連結:', contents['link']) </span></b></div><div><b><span style="color: #2b00fe;"> print('日期:', contents['date']) </span></b></div><div><b><span style="color: #2b00fe;"> print('----')</span></b></div><div> </div></div><div><div>---- ithome ----</div><div>標題: Telegram預計明年就會獲利,考慮公開發行股票</div><div>連結: https://www.ithome.com.tw/news/161722</div><div>日期: 2024-03-12</div><div>----</div><div>標題: 馬斯克AI公司將開源Grok聊天機器人</div><div>連結: https://www.ithome.com.tw/news/161716</div><div>日期: 2024-03-12</div><div>----</div><div>標題: 微軟公布允許歐盟地區Windows用戶移除Bing、Edge、OneDrive等多項遵循DMA措施</div><div>連結: https://www.ithome.com.tw/news/161715</div><div>日期: 2024-03-12</div><div>----</div><div>標題: Google讓瀏覽器、Android手機、iPhone都可執行大型語言模型</div><div>連結: https://www.ithome.com.tw/news/161714</div><div>日期: 2024-03-12</div><div>----</div><div>標題: Android地圖應用不再亂指路,Google公開更準確的裝置朝向API</div><div>連結: https://www.ithome.com.tw/news/161712</div><div>日期: 2024-03-12</div><div>----</div><div>標題: Safari 17新加入的進階音訊指紋辨識保護已經被破解</div><div>連結: https://www.ithome.com.tw/news/161711</div><div>日期: 2024-03-12</div><div>----</div><div>---- business ----</div><div>---- inside ----</div><div>標題: 甲骨文公司公布了第三財季財報, 受惠於 AI 伺服器的強勁需求,雲端的營收則年增 25%,達到 51 億美元。</div><div>連結: https://www.inside.com.tw/article/34446-oracle-q3</div><div>日期: 2024-03-12</div><div>----</div><div>標題: 川普認為TikTok 禁令可能會影響年輕人,且會讓 Facebook 成為一大受益者。川普曾批評 Meta 在美國國會動亂期,撤銷他 FB 和 IG 帳號。</div><div>連結: https://www.inside.com.tw/article/34445-trump-thinks-tiktok-ban-could-drive-kids-crazy</div><div>日期: 2024-03-12</div><div>----</div><div>標題: Airbnb 禁裝設室內監視器的新政策難以完全防止不肖人士裝隱藏攝影機,但至少能讓守規的房東不再在於出租的房屋放置任何鏡頭,讓房客住得安心一點。</div><div>連結: https://www.inside.com.tw/article/34442-airbnb-bans-indoor-cameras</div><div>日期: 2024-03-12</div><div>----</div><div>標題: 針對傳言,裕隆指出,現階段電馳利暫時無代理銷售業務。</div><div>連結: https://www.inside.com.tw/article/34444-geely-in-taiwan</div><div>日期: 2024-03-12</div><div>----</div><div>標題: 隨著社群平台 X 上的討論越來越激烈,也有人質疑「馬斯克嗆聲 OpenAI 不開源,那馬斯克旗下自家 Grok 不也是沒有開源?」然而,就在昨日馬斯克宣布本週將開源 Grok 程式碼,並且將這則貼文置頂於個人頁面上。</div><div>連結: https://www.inside.com.tw/article/34443-musk-xai-to-open-source-gork-this-week</div><div>日期: 2024-03-12</div><div>----</div><div>標題: 分析師認為,其中一個關鍵是特斯拉的駕駛輔助硬體是否會成為標配,這個硬體的成本可能在 2,000 到 3,000 美元之間,佔掉不少生產成本。</div><div>連結: https://www.inside.com.tw/article/34441-tesla-2027-story-evercore-analysts-model-2-deliveries</div><div>日期: 2024-03-12</div><div>----</div></div><div><br /></div><div>可見除 inside 呼叫 get_today_news() 未傳回資料外, ithome 與 inside 都已有今日新聞.</div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-79778799877556822292024-03-11T23:50:00.003+08:002024-03-11T23:50:16.020+08:00水某買 Acer Swift Go 筆電<div>水某辦公室電腦決定要買筆電, 晚上陪她去民族路全國電子看看要買哪一種, 電員推薦目前 Acer Swift Go 14 吋 (銀色) 這款 CP 直最高, 優惠後 25900 元送 1000 元抵用券, 剛好可用來抵買 Office 2021 ($4100), 所以就決定買這款了. </div><div><br /></div><div>機型 : SFG14-71-513W</div><div>電池 : UN3418 (AP18C8K)</div><div><br /></div><div>紙箱上貼的規格如下 :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMrktYnXOD85VYTYx4KHxzWt10GQYT2IXs0W_lO2hCPRr9o6RU4H72pYMZuAt3_tevfuk7QP6C7RobZkGfISKQ2glpFkjf3XH8ACB33qF3220FtcjalB4_29jb68piiWF7C58ue6rAzTSXYgv7jJjfi8OqZ30iM6kjvG_OnjLQadxyj4QBodHX0Bv188Mv/s1625/acer_swift_go_1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1625" data-original-width="923" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMrktYnXOD85VYTYx4KHxzWt10GQYT2IXs0W_lO2hCPRr9o6RU4H72pYMZuAt3_tevfuk7QP6C7RobZkGfISKQ2glpFkjf3XH8ACB33qF3220FtcjalB4_29jb68piiWF7C58ue6rAzTSXYgv7jJjfi8OqZ30iM6kjvG_OnjLQadxyj4QBodHX0Bv188Mv/s320/acer_swift_go_1.jpg" width="182" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilfJSZfJqw11He72LojNh9i7cDLI_LNCh-N0sP5AX4vUFbNJQZxznGej_PuU7jp1D1g2FoIjQ7_Eqr3OBlvsXDpHaJUY6IuCZN573T8_gZ6t04GWPzEuqPE_cGl8RFGKmFBxp2_K655tDN02Ha0tyjOTxINvW-hRgAXzIAX3P8jXDoKmwa4fXEQW_0Ok1r/s1411/acer_swift_go_2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1411" data-original-width="706" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilfJSZfJqw11He72LojNh9i7cDLI_LNCh-N0sP5AX4vUFbNJQZxznGej_PuU7jp1D1g2FoIjQ7_Eqr3OBlvsXDpHaJUY6IuCZN573T8_gZ6t04GWPzEuqPE_cGl8RFGKmFBxp2_K655tDN02Ha0tyjOTxINvW-hRgAXzIAX3P8jXDoKmwa4fXEQW_0Ok1r/s320/acer_swift_go_2.jpg" width="160" /></a></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIKFs5JN5xSy42oeJfRsc_bfAVqyvFVEKNmHC3ST31ykQJoucQxobufdAKOWx_koc8jT0gKyfHFyV3jQXQvKtjH7WQuI6ZQHDG1hWRt2VP9TY1Q8Vnb1Udrl_fRIcfWBUoDy79zvzUEGAVNivE9wJS6HUXKWzqBZaRH8klxrSzRWM4ms3c-QjD-FzHq_WF/s790/acer_swift_go_3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="732" data-original-width="790" height="297" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIKFs5JN5xSy42oeJfRsc_bfAVqyvFVEKNmHC3ST31ykQJoucQxobufdAKOWx_koc8jT0gKyfHFyV3jQXQvKtjH7WQuI6ZQHDG1hWRt2VP9TY1Q8Vnb1Udrl_fRIcfWBUoDy79zvzUEGAVNivE9wJS6HUXKWzqBZaRH8klxrSzRWM4ms3c-QjD-FzHq_WF/s320/acer_swift_go_3.jpg" width="320" /></a></div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-10536500214989654422024-03-11T09:32:00.008+08:002024-03-11T09:38:00.230+08:00好站 : STEAM 教學網<div>最近在學習 Line Bot 時找到下面這個很棒的網站 :</div><div><br /></div><div># <a href="https://steam.oxxostudio.tw/" target="_blank">STEAM 教學網</a></div><div><br /></div><div>作者是技術社群活躍者 OXXO (張宗彥), 秉持 STEAM 精神將所學編寫為此網站, 供大小朋友學習參考. 分享是社會進步的推力 (自利利他), 與我的想法不謀而合. </div><div><br /></div><div>此外作者也寫了兩本好書 : </div><div><ol style="text-align: left;"><li><a href="https://www.books.com.tw/products/0010956162" target="_blank">一本精通 : OpenCV與AI影像辨識</a> (深智, 2023)<br /><br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://im2.book.com.tw/image/getImage?i=https://www.books.com.tw/img/001/095/61/0010956162_bc_01.jpg&v=644a4fd7k&w=348&h=348" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="348" data-original-width="348" height="348" src="https://im2.book.com.tw/image/getImage?i=https://www.books.com.tw/img/001/095/61/0010956162_bc_01.jpg&v=644a4fd7k&w=348&h=348" width="348" /></a><br />Source: 博客來<br /><br /></div><br /></li><li><a href="https://www.books.com.tw/products/0010964726" style="background-color: white;" target="_blank">一本精通 : Python範例應用大全 : Python詳細語法教學&100+個Python範例</a> (深智, 2023)<br /><br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://im2.book.com.tw/image/getImage?i=https://www.books.com.tw/img/001/096/47/0010964726_bc_01.jpg&v=64c79bb5k&w=348&h=348" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="348" data-original-width="348" height="348" src="https://im2.book.com.tw/image/getImage?i=https://www.books.com.tw/img/001/096/47/0010964726_bc_01.jpg&v=64c79bb5k&w=348&h=348" width="348" /></a><br />Source: 博客來</div><br /></li></ol></div><div>其中 No,2 這本書收集了作者撰寫過的 Python 教學文章, 內容含括各種 Python 應用, 其中大部分也可在 iT 邦幫忙 Python 系列文章找到, 參考 : </div><div><br /></div><div># <a href="https://ithelp.ithome.com.tw/users/20091306/ironman/6545" target="_blank">跟著 OXXO 一起學 Python 系列</a> </div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-44197593171323118982024-03-10T23:31:00.001+08:002024-03-10T23:31:07.075+08:002024 年第 10 周記事<div>這個周末主要有兩大任務, 一是週六去觀音廟幫吾妹阿蘭掃墓, 師姐說去年往生者要在 3/15 日前掃. 週五晚上上完 GAS 的課已九點, 整理一下十點出發回鄉下. 週六早上先去小竹伯母家拿紅龜粄與發粄共 260 元, 回程經榮發舅媽家拿牲禮, 結果她好像搞錯日期以為是周日, 發一下簿子才知搞錯了, 拿了九點才要取貨的一副給我 (共 1200 元), 然後轉身再去煮一副. </div><div><br /></div><div>到達觀音廟時約九點, 人還蠻多的, 但也不算擠, 約莫有七八張桌子, 擺好祭品點香先拜地藏與天神, 然後拿香到塔裡面跟阿蘭講今天掃墓, 請她隨香到外面供桌享用. 擺祭品時發現沒帶到蠟燭, 但觀察很多家也沒點蠟燭, 而且這裡似乎不讓燃放鞭炮. 燒完壽金 (給神的在金爐燒) 與九金銀紙 (給往收者在外面露天磚爐燒), 酒過三巡即可點香或以手拜後收祭品結束掃墓. </div><div><br /></div><div>第二件任務是為下周日 (3/17) 家族掃墓預先整理墓園, 週六下午先去整理家祠, 原以為可以半天搞定, 但去年掃墓之後我一整年沒來巡墓園, 雜草叢生不說, 兩側雨水溝裡蘆葦叢是又高又難砍除, 從 13:30 忙到 16:00 總算大勢底定, 只剩下明堂帶整理. 今天早上七 點半備好掃把再次前去清理, 花了兩小時終於搞定. 下午兩點則是與堂哥兄弟三人去整理來台祖墓園, 聽堂哥說現在整理墓園人手不好找, 基本上 3500 元起跳, 哇, 那我這兩天不就省下 7 千元了?</div><div><br /></div><div>月底 (ˇ3/28) 要給阿蘭做對年, 所以三月份共有四副牲禮, 冰箱會爆滿. 我看整個三月中午要盡量帶便當了, 哈哈. </div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-71738871287519364792024-03-10T20:20:00.003+08:002024-03-10T20:20:53.388+08:00如何檢查 Windows 是哪種授權版本<div>昨天在做迷你電腦市調時, 詢問賣家搭載的 Win11 是否為正版, 賣家回答是 VOL 版, 蛤? VOL 是啥? 我查詢谷歌, 找到下面這篇 :</div><div><br /></div><div># <a href="https://walker-a.com/archives/5507" target="_blank">檢查您的Windows 10 License 是零售、OEM或VOL大量授權</a></div><div><br /></div><div>原來 Windows 的授權主要有下列四種 :</div><div><ol style="text-align: left;"><li>零售版 (Retail) : 在全國電子/燦坤買的盒裝 Windows.</li><li>隨機版 (OEM) : 品牌桌機或筆電搭機出售的版本.</li><li>升級版 (Upgrade) : 與零售版類似的盒裝 Windows, 但僅限升級, 無法全新安裝.</li><li>大量授權版 (VOL) : 團體機構向微軟購買的版本. </li></ol></div><div>檢查桌機或筆電是哪種授權, 可開啟命令提示字元視窗, 輸入 <b><span style="color: #2b00fe;">SLMGR -DLI</span></b> 查詢, 它會跳出一個視窗顯示查詢結果, 例如我那台超過 10 年的 LEMEL 桌電居然是零售版 :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQeCKUT9_4j6Y6fFeVIvpidsmtOtjrJYNjpBWDXp7mPKciTe9tyZbpbcmM96HfemVGralwIdAJOt7bqwmQAskyYrkNQ7LYxwoyXOM-3UROzpi-mkp-d7reiIbzPJnWpJYHAgZ8jG5ILWrVLW0PYC5hiiS4-QBpdXFGTeJzbWuo6TJMasNPfcgeTt1GiIWJ/s832/check_windows_auth_type_lemel_desktop.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="536" data-original-width="832" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQeCKUT9_4j6Y6fFeVIvpidsmtOtjrJYNjpBWDXp7mPKciTe9tyZbpbcmM96HfemVGralwIdAJOt7bqwmQAskyYrkNQ7LYxwoyXOM-3UROzpi-mkp-d7reiIbzPJnWpJYHAgZ8jG5ILWrVLW0PYC5hiiS4-QBpdXFGTeJzbWuo6TJMasNPfcgeTt1GiIWJ/s320/check_windows_auth_type_lemel_desktop.jpg" width="320" /></a></div><br /><div><br /></div><div>而 LG Gram 筆電則是 OEM 版 :</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizUTw3OuAuC4hCNoPq2ZHiajzf-103gusU65udFm7wR7MxnLToTI2BtUgALmSiErc6yowbgelVBnOTi21FPtdQFGymQWmYZ4HzebnT5RguYpy_iVr3yXLweSV8w4XSQNgZj5CMGIgHnyshqnvHtZ4xwhWPOYJXV8A9UhHb99zZcnjvUKlIVpFtObe7q_oj/s994/check_windows_auth_type_lg_gram.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="514" data-original-width="994" height="165" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizUTw3OuAuC4hCNoPq2ZHiajzf-103gusU65udFm7wR7MxnLToTI2BtUgALmSiErc6yowbgelVBnOTi21FPtdQFGymQWmYZ4HzebnT5RguYpy_iVr3yXLweSV8w4XSQNgZj5CMGIgHnyshqnvHtZ4xwhWPOYJXV8A9UhHb99zZcnjvUKlIVpFtObe7q_oj/s320/check_windows_auth_type_lg_gram.jpg" width="320" /></a></div><br /><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-48547163539551162422024-03-09T00:19:00.008+08:002024-03-09T12:02:35.328+08:00魔方 Intel N100 迷你電腦 (NUC)<div>昨天水某說她辦公室的迷你桌機太老舊速度很慢想要換一台, 我今天在蝦皮找到賣家 miniPC 販售的魔方 N100 迷你電腦, 12G DDR5 + 1TB SSD 價格 7999 (8G 是 DDR4), 搭載 Win11 + Office2021 (試用版) :</div><div><br /></div><div># <a href="https://shopee.tw/product/32979677/19586545926?gad_source=1&gclid=CjwKCAiAi6uvBhADEiwAWiyRdsky-XBqmajKxbxB86iQMog8fr_qN_k7VxxCokdx3fC9nDCcGcItPxoChLAQAvD_BwE" target="_blank">2023 MoreFine 摩方 最新 4K Intel 迷你電腦 N5105 N100 現貨 LOL 原神</a> $5999~7999</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAVHOift0y2d54o6mUdAPdXEU487eliOIrUK-POXMdA079LZpLk37-sQtSeUoK__KZ-Oxy46v91UFhK6KDcuwvKNA9xFDVknHqq9KxJaptwHxbvauRbkzxSGIX8dhQzxeLZ3Z4kf5rmvizFbKH3D6vd9vcqs2xehD4KEF-OkakQMUzwzKIw2xNPiju2VxT/s1034/%E9%AD%94%E6%96%B9N100%E8%BF%B7%E4%BD%A0%E9%9B%BB%E8%85%A6-12G1TB.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="598" data-original-width="1034" height="185" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAVHOift0y2d54o6mUdAPdXEU487eliOIrUK-POXMdA079LZpLk37-sQtSeUoK__KZ-Oxy46v91UFhK6KDcuwvKNA9xFDVknHqq9KxJaptwHxbvauRbkzxSGIX8dhQzxeLZ3Z4kf5rmvizFbKH3D6vd9vcqs2xehD4KEF-OkakQMUzwzKIw2xNPiju2VxT/s320/%E9%AD%94%E6%96%B9N100%E8%BF%B7%E4%BD%A0%E9%9B%BB%E8%85%A6-12G1TB.jpg" width="320" /></a></div><br /><div><br /></div><div>規格如下 : </div><div><br /></div><div><div>處理器:N100 7nm</div><div>記憶體:DDR4 2400 12G </div><div>硬碟:1T SSD</div><div>wifi 5:Intel(R) Dual Band Wireless-AC 7265</div><div>網路孔:Intel 225</div><div>藍牙:4.2</div><div>輸出:雙HDMI 2.0 4K 60Hz</div><div>系統:W11+Office2021</div><div>開機:支援過電開機</div><div>散熱:純銅散熱片+PWM風扇</div><div>尺寸:7.2*7.2*4.5cm 190g</div><div>電源:12V/3A 36W 支援PD(Type-C接口)</div><div>可記憶卡擴充最大:512G</div><div>USB:3.0*3 &音頻接口:3.5mm</div><div>系統救援終生免費維護</div></div><div><br /></div><div>momo 也有賣, 但只有 256GB SSD 就要 7490 元 :</div><div><br /></div><div># <a href="https://www.momoshop.com.tw/goods/GoodsDetail.jsp?i_code=11766742&osm=Ad07&utm_source=googleshop&utm_medium=googleshop-pmax-all-mb-feed&utm_content=bn&gclid=CjwKCAiAi6uvBhADEiwAWiyRdnHDxeTwIMNLQo7jHN9iE17up2InY4nSQcJ0y609KOwIpOe5Ixr32hoCo_YQAvD_BwE" target="_blank">MOREFINE M6S 迷你電腦(Intel N100 3.4GHz/12G/256G/Win 11)</a> momo $7490</div><div><br /></div><div>下面是舊款 CPU N5105 與新款 CPU N100 的性能比較 (當然選 N100) :</div><div><br /></div><div># <a href="https://www.cpu-panda.com/zh-tw/compare_cpu-intel_celeron_n5105-vs-intel_processor_n100" target="_blank">Intel Celeron N5105 vs Intel Processor N100</a></div><div><br /></div><div>以後鄉下家的老電腦若壞掉要改買這種迷你電腦, 便宜又可攜帶. </div><div><br /></div><div><br /></div><div>2024-03-09 補充 :</div><div><br /></div><div>松果的介紹很詳盡 (搭 Win10) :</div><div><br /></div><div># <a href="https://www.pcone.com.tw/product/info/230826287375?gad_source=1&gclid=CjwKCAiAi6uvBhADEiwAWiyRdpoCsAE6Dyhxp8krOhG5QiIZgjuaab88Uo-LLj43Ikb3DhVbxlt3BBoCeuEQAvD_BwE&gmc=1&sid=gsa_23&utm_content=23&utm_medium=gsa&utm_source=google" target="_blank">MOREFINE M6S 迷你電腦(Intel N100 3.4GHz) - 12G/256G</a> $7190</div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-80919917028351788052024-03-08T14:27:00.003+08:002024-03-08T14:27:30.802+08:00Pi 3 主機 Crontab 停止傳送外網 Email<div>我在年初 (元旦) 時完成用 Line Notify 傳送 Pi 3 主機的外網 IP (中華電信光世代浮動 IP), 兩個月下來運作正常, 每小時都會收到 Line 推播的 IP, 參考 :</div><div><br /></div><div># <a href="https://yhhuang1966.blogspot.com/2024/01/python-ip-line.html" target="_blank">Python 學習筆記 : 取得本機外網 IP 傳送 Line 訊息的方法</a></div><div><br /></div><div>由於我的 Hinet 信箱是免費的 5GB 而已, 一段時間就要清一清以免信箱爆掉, 被清掉的信件大部分是廣告信與一天 48 封的 IP 回報 Email, 雖然每封容量不大, 但清信件好累, 所以今天把它給停了. 原本的 Crontab 如下 : </div><div><br /></div><div><div>pi@raspberrypi:~ $ <b><span style="color: #2b00fe;">sudo crontab -l</span></b> </div></div><div>0 * * * * sudo /usr/local/bin/checkwifi.sh</div><div><div><span style="background-color: #fcff01;">30 * * * * /usr/bin/python3 /home/pi/reportip3.py</span> </div><div>0 * * * * /usr/bin/python3 /home/pi/reportip4.py</div></div><div><br /></div><div>只要用 <span style="background-color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 14.85px;"><b><span style="color: #2b00fe;">sudo crontab -e</span></b></span> 指令將 reportip3.py 這行註解掉即可 : </div><div><br /></div><div>pi@raspberrypi:~ $ <b><span style="color: #2b00fe;">sudo crontab -l</span></b></div><div><div>0 * * * * sudo /usr/local/bin/checkwifi.sh</div><div><span style="background-color: #fcff01;">#</span>30 * * * * /usr/bin/python3 /home/pi/reportip3.py</div><div>0 * * * * /usr/bin/python3 /home/pi/reportip4.py</div></div><div><br /></div><div>這樣就完工啦!</div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-47015636116390469802024-03-08T14:01:00.002+08:002024-03-08T14:03:15.545+08:00向 SpoM 購買 S24 Ultra 保護套<div>雖然前幾天去幫 S24U 貼螢幕保護時買了一個透明保護殼, 但我還是習慣可蓋住螢幕的保護套, 所以在 SpoM 買了三個 : </div><div><br /></div><div># <a href="https://www.spom.com.tw/products/samsung-galaxy-s24-ultra-s24-s24-%E7%9A%AE%E9%9D%A9%E4%BF%9D%E8%AD%B7%E5%A5%97-buckle-%E6%89%A3%E5%B8%B6%E5%B7%A6%E5%8F%B3%E7%BF%BB%E8%93%8B%E7%9A%AE%E5%A5%97%E6%89%8B%E6%A9%9F%E5%A5%97?gad_source=1&gclid=CjwKCAiA6KWvBhAREiwAFPZM7rAiUa5WqnPhtjRB9e0GLwgjy7xF4bMjmdBwXk6ws9jq7x3QJj7W5BoCPWYQAvD_BwE" target="_blank">Samsung Galaxy S24 Ultra S24+ S24 皮革保護套(BUCKLE) - 扣帶左右翻蓋皮套手機套</a> NT$ 299</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUvKeP_JMPYmINMcejXdld67rRhvwlpXurZmfuc4nQuFvnvvfgRfu9MZH6jCAJEVgyaWGMEmwc98YQXYBML29tjUsWZH1vGh9IxP2aQ9yvPPOgfp1Q_M1ScAwNejpleCw9PBFYnSvYCCDDTuNqH40-6b5fJWcwUCafic9uSq8HUGgil-AbXohkvIWUhR4o/s2437/%E5%90%91%20SpoM%20%E8%B3%BC%E8%B2%B7%20S24%20Ultra%20%E4%BF%9D%E8%AD%B7%E5%A5%97-1.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1254" data-original-width="2437" height="165" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUvKeP_JMPYmINMcejXdld67rRhvwlpXurZmfuc4nQuFvnvvfgRfu9MZH6jCAJEVgyaWGMEmwc98YQXYBML29tjUsWZH1vGh9IxP2aQ9yvPPOgfp1Q_M1ScAwNejpleCw9PBFYnSvYCCDDTuNqH40-6b5fJWcwUCafic9uSq8HUGgil-AbXohkvIWUhR4o/s320/%E5%90%91%20SpoM%20%E8%B3%BC%E8%B2%B7%20S24%20Ultra%20%E4%BF%9D%E8%AD%B7%E5%A5%97-1.jpg" width="320" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVyJni5PPLiIcENPPm3Ypx5DSattOecPmG2H2IiMFnNVlsIA4gApf-5JxccU1b3JbGrWapMM3CykBLuKBh01sil5FC5Qf0uU6lDJu3cNEDHdSX_uhcwA4Em7gl3JOQTDW0TjzFQTo5K6lvyJHGEdpn-ZqW3H1gIH9P4jh6e3kMDk9YVTQMyeuPX4DPqvIB/s978/SPORN%20%E8%B2%B7%20S24U%20%E4%BF%9D%E8%AD%B7%E5%A5%97%E4%B8%89%E5%80%8B.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="928" data-original-width="978" height="304" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVyJni5PPLiIcENPPm3Ypx5DSattOecPmG2H2IiMFnNVlsIA4gApf-5JxccU1b3JbGrWapMM3CykBLuKBh01sil5FC5Qf0uU6lDJu3cNEDHdSX_uhcwA4Em7gl3JOQTDW0TjzFQTo5K6lvyJHGEdpn-ZqW3H1gIH9P4jh6e3kMDk9YVTQMyeuPX4DPqvIB/s320/SPORN%20%E8%B2%B7%20S24U%20%E4%BF%9D%E8%AD%B7%E5%A5%97%E4%B8%89%E5%80%8B.jpg" width="320" /></a></div><br /><div><br /></div><div>另有看來外觀差不多的真牛皮款 (較貴, 且我也不喜歡動物皮草製品) : </div><div><br /></div><div># <a href="https://www.spom.com.tw/products/samsung-galaxy-s24-ultra-s24-s24-%E7%9A%AE%E9%9D%A9%E4%BF%9D%E8%AD%B7%E5%A5%97-cover-%E7%BF%BB%E8%93%8B%E7%84%A1%E7%A3%81%E7%89%9B%E7%9A%AE%E7%9C%9F%E7%9A%AE%E6%89%8B%E6%A9%9F%E5%A5%97%E6%89%8B%E6%A9%9F%E7%9A%AE%E5%A5%97?gad_source=1&gclid=CjwKCAiA6KWvBhAREiwAFPZM7u0hzoHyq54Adsk0HAq4bGxTSevx2rkKqxuq_hgdtNr8VlgthKrd3hoC4hsQAvD_BwE" target="_blank">Samsung Galaxy S24 Ultra S24+ S24 皮革保護套(COVER) - 翻蓋無磁牛皮真皮手機套手機皮套</a> $499</div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-18705840200140034072024-03-08T09:20:00.006+08:002024-03-08T09:20:47.717+08:00好站 : Taiwan LLM 解析台灣第一個大型對話式語言模型<div>最近加入了一個台灣大型語言模型的臉書社群, 昨天在 YT 有林彥廷的直播 (約 46 分鐘) : </div><div><br /></div><div># <a href="https://www.youtube.com/watch?v=3Y3-79NZQZg">Taiwan LLM 解析台灣第一個大型對話式語言模型 (youtube.com)</a></div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen="" class="BLOG_video_class" height="266" src="https://www.youtube.com/embed/3Y3-79NZQZg" width="320" youtube-src-id="3Y3-79NZQZg"></iframe></div><br /><div><br /></div><div>裡面提到一些訓練模型時採用較少 bit 與 GPU 的設定建議, 值得參考. </div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-35759306777976831432024-03-08T08:40:00.002+08:002024-03-08T08:40:14.407+08:00好書 : 非監督式學習-使用 Python<div style="text-align: left;">最近從母校借到下面這本好書 : </div><div style="text-align: left;"><br /></div><div style="text-align: left;"># <a href="https://www.books.com.tw/products/0010852754" target="_blank">非監督式學習:使用Python</a></div><div style="text-align: left;"><br /></div><div style="text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://im1.book.com.tw/image/getImage?i=https://www.books.com.tw/img/001/085/27/0010852754.jpg&v=5e6f553bk&w=348&h=348" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="348" data-original-width="348" height="348" src="https://im1.book.com.tw/image/getImage?i=https://www.books.com.tw/img/001/085/27/0010852754.jpg&v=5e6f553bk&w=348&h=348" width="348" /></a></div><div class="separator" style="clear: both; text-align: center;">Source : 博客來</div><br /><div style="text-align: left;"><br /></div><div style="text-align: left;">此書譯自歐萊里的 "<a href="https://www.oreilly.com/library/view/hands-on-unsupervised-learning/9781492035633/" target="_blank">Hands-On Unsupervised Learning Using Python</a>" (2019, Oreilly), 使用 TensorFlow/Keras 框架, 書中程式範例檔可從 GitHub 下載 :</div><div style="text-align: left;"><br /></div><div style="text-align: left;"># <a href="https://github.com/aapatel09/handson-unsupervised-learning" target="_blank">https://github.com/aapatel09/handson-unsupervised-learning</a></div><div style="text-align: left;"><br /></div><div style="text-align: left;">我要每天抽出 10 分鐘來好好讀這本, 用滴水穿石策略把它肯完. </div><div style="text-align: left;"><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-56256298422589759922024-03-07T18:34:00.006+08:002024-03-13T21:00:36.264+08:00Google Apps Script 共讀筆記 (2024-03-06)昨日 (3/6) 參加謝昌勳老師主辦的 GAS 共讀會第二次課程, 由曾慶良老師介紹如何利用 GAS 抓取氣象資料後串接 Line Notify 推播訊息, 上課資料如下 :<div><br /></div><div># <a href="https://line.me/R/ti/p/@822jbliz?oat_content=url" target="_blank">https://line.me/R/ti/p/@822jbliz?oat_content=url</a></div><div># <a href="https://drive.google.com/file/d/1wqQWlTwGBaXpYrPYzfm7uPutCY22GVOt/view" target="_blank">AI 自動化設計快閃班</a> </div><div># <a href="https://chat.openai.com/g/g-OHGkxtrVQ-liang-de-zi-dong-hua-google-app-script-zhi-shi-xue-xi-yu-jian-zhi-you-hua-gpt" target="_blank">亮的~自動化(Google APP Script)知識學習與建置優化GPT</a></div><div># <a href="https://docs.google.com/document/d/1299FPp6RW7YnFEghXKvMWaJS6l5MsGrY/edit" target="_blank">天氣預報通知GAS板模</a></div><div># <a href="https://data.gov.tw/dataset/9176" target="_blank">自動氣象站-氣象觀測資料</a></div><div># <a href="https://docs.google.com/spreadsheets/d/1nYFtYxz1jRNsj94iaI0JsbpPUhh2m9F6GDcA787BwVU/edit#gid=0" target="_blank">Stock Demo</a></div><div># <a href="https://docs.google.com/presentation/d/1MnKSjYjG0UUXXMBXhOB696sEijg58xBODv1RAYnSulU/edit#slide=id.p" style="background-color: #fcff01;" target="_blank">LINE 多功能應用</a></div><div># <a href="https://sites.google.com/view/gasabc/" style="background-color: #fcff01;" target="_blank">https://sites.google.com/view/gasabc/</a></div><div># <a href="https://docs.google.com/spreadsheets/d/1SEokblNBFeHBy0RRNJ83Z7bhY5dHXHkY2E7uD1B-uss/edit#gid=0" target="_blank">股票預報 的副本</a></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0tag:blogger.com,1999:blog-4877487320781767952.post-37179638480152090142024-03-07T16:32:00.004+08:002024-03-07T16:32:31.277+08:00三星 S24U 密技 : 如何不必按電源鍵喚醒手機<div>這幾天在使用新手機 S24U 時每次要喚醒手機都是按電源鍵, 其實可以在 "設定/進階功能/動作與手勢" 選單中, 開啟 "請輕觸兩下來開啟螢幕" 選項, 就可以用手指輕觸兩下螢幕來喚醒手機, 參考 : </div><div><br /></div><div># <a href="https://www.samsung.com/tw/support/mobile-devices/how-to-wake-up-the-phone-without-touching-the-phone-when-it-is-dormant/" target="_blank">手機休眠時,如何透過不按壓電源鍵的方式喚醒手機?</a></div><div><br /></div><div><br /></div><div>選 "進階功能" : </div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiB3MZxLEcaXbmhvQuj5OQ_UbNifB-2AdhyphenhyphengjdFNecSRRM_GyvLdPR5L0QH9ehxebOxLqVUSzuada7PHEkWWTf0NiTdUMl9RSZ8AXYXypr2g-PhgKJBq7qflMdYaOYhOC3oWyn8Bu9d3b4lFc-MPJoptpLMG4l-mldKHYxHpci_L1QDoYyNjHBHomlje3QZ/s1048/S24U-wakeup-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1048" data-original-width="869" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiB3MZxLEcaXbmhvQuj5OQ_UbNifB-2AdhyphenhyphengjdFNecSRRM_GyvLdPR5L0QH9ehxebOxLqVUSzuada7PHEkWWTf0NiTdUMl9RSZ8AXYXypr2g-PhgKJBq7qflMdYaOYhOC3oWyn8Bu9d3b4lFc-MPJoptpLMG4l-mldKHYxHpci_L1QDoYyNjHBHomlje3QZ/s320/S24U-wakeup-1.jpg" width="265" /></a></div><div><br /></div><div><br /></div><div>選 "動作與手勢" :</div><div><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjx6WZe1-lOwXdTTH0oTTsz0A9-jRlgwn9kJryN_9AoKKnKc5zdZqpRNHfbvm9W_WUcJ4KLoaAAeQydGMJHkuvBLRW8WSHLMNtI4gyCaOqp_F4pW-stnJj-EDo1xAqzd9HrDC8rkWV_M_jB0kBRdWcU7pcXYPQAXuTrJNyQRww2z7uRs6yIRHwADeV_5PN_/s922/S24U-wakeup-2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="922" data-original-width="869" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjx6WZe1-lOwXdTTH0oTTsz0A9-jRlgwn9kJryN_9AoKKnKc5zdZqpRNHfbvm9W_WUcJ4KLoaAAeQydGMJHkuvBLRW8WSHLMNtI4gyCaOqp_F4pW-stnJj-EDo1xAqzd9HrDC8rkWV_M_jB0kBRdWcU7pcXYPQAXuTrJNyQRww2z7uRs6yIRHwADeV_5PN_/s320/S24U-wakeup-2.jpg" width="302" /></a></div><div><br /></div><div><br /></div><div><br /></div><div>開啟 "請輕觸兩下來開啟螢幕" : </div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4JvYB4TAcXfzJlid7ZakIZ98o19i8dFkesikDzCaQL0H2HFzfmaBSoRCAWlgRdHZ9q445QTfhsKYXnGRepQ70n7g4VuqShFLHjPzmyWpZJKNpOtFFUY8pW8fdwYWD-3wH_PUnIfhsUsyZoZBkoABmq8G2drrUOdlDFejdzB5PDtwUGgTHuikingL9vC9d/s959/S24U-wakeup-3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="959" data-original-width="869" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4JvYB4TAcXfzJlid7ZakIZ98o19i8dFkesikDzCaQL0H2HFzfmaBSoRCAWlgRdHZ9q445QTfhsKYXnGRepQ70n7g4VuqShFLHjPzmyWpZJKNpOtFFUY8pW8fdwYWD-3wH_PUnIfhsUsyZoZBkoABmq8G2drrUOdlDFejdzB5PDtwUGgTHuikingL9vC9d/s320/S24U-wakeup-3.jpg" width="290" /></a></div><br /><div><br /></div><div>這樣就不必按開機鈕了. </div><div><br /></div>小狐狸事務所http://www.blogger.com/profile/09435160519044041137noreply@blogger.com0