<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5413673165485961878</id><updated>2026-10-01T19:05:21.754-07:00</updated><category term="Excel"/><category term="VBA"/><category term="Python"/><category term="VC"/><category term="MultiCharts"/><category term="Visual Studio"/><category term="Google Apps Script"/><category term="Google Spreadsheet"/><category term="jupyter"/><category term="GAS"/><category term="Winpe"/><category term="Line"/><category term="WINAPI"/><category term="股票"/><category term="Crawler"/><category term="Anaconda"/><category term="Google Sheets API"/><category term="IPython"/><category term="MySQL"/><category term="封存"/><category term="LINE Notify"/><category term="C#"/><category term="JavaScript"/><category term="batch"/><category term="Apache"/><category term="PHP"/><category term="R"/><category term="UEFI"/><category term="ubuntu"/><category term="DDE"/><category term="Google Drive"/><category term="Google Visualization API Query Language"/><category term="Line Bot"/><category term="Line Messaging API"/><category term="phpMyAdmin"/><category term="BCDedit"/><category term="Node.js"/><category term="FCM"/><category term="Firebase Cloud Messaging"/><category term="Flask"/><category term="Google OAuth"/><category term="VBScript"/><category term="BIOS"/><category term="Fiddler"/><category term="OpenSSL"/><category term="Power BI"/><category term="RW"/><category term="UDK2010"/><category term="redmine"/><category term="ATA Command"/><category term="DOS"/><category term="EFI"/><category term="Google Cloud Messaging"/><category term="HDD"/><category term="Heroku"/><category term="Postman"/><category term="Push Notification"/><category term="RStudio"/><category term="RTD"/><category term="Ruby"/><category term="SATA Controller"/><category term="SGX"/><category term="SyntaxHighlighter"/><category term="Windows 8"/><category term="Windows 8.1"/><category term="交易明細"/><category term="Access"/><category term="Chrome"/><category term="Custom UI Editor For Microsoft Office"/><category term="EDK"/><category term="GCM"/><category term="GDI+"/><category term="Inno Setup"/><category term="InnoIDE"/><category term="Line Login"/><category term="MathJax"/><category term="Protocol"/><category term="Rails"/><category term="Registry"/><category term="Remote Debug"/><category term="Ribbon"/><category term="SMBus"/><category term="SQLyog"/><category term="Stored Procedure"/><category term="WMI"/><category term="pyxmpp"/><category term="ANSI"/><category term="Android"/><category term="Android Studio"/><category term="Api Hook"/><category term="AppLocale"/><category term="CHM"/><category term="Chkdsk"/><category term="Codec"/><category term="Container"/><category term="Critical section"/><category term="Docker"/><category term="FaceBook外掛"/><category term="GPIO"/><category term="Ghost"/><category term="Google+ 留言框"/><category term="Google網誌搜尋"/><category term="InternetExplorer"/><category term="Memory speed"/><category term="Mutex"/><category term="PE文件格式"/><category term="Passenger"/><category term="Quantmod"/><category term="ROR"/><category term="Regular Expression"/><category term="SQLite"/><category term="SSL"/><category term="Selenium"/><category term="Spyder"/><category term="Ta-lib"/><category term="UTF8"/><category term="VSCode"/><category term="WTG、VHD、Windows to go"/><category term="WinIO"/><category term="Windbg"/><category term="Wireshark"/><category term="diskpart"/><category term="iInfo 愛資訊"/><category term="jQuery"/><category term="jsoncpp"/><category term="mod_evasive"/><category term="xmlhttprequest"/><category term="價量"/><category term="價量教學"/><category term="學習推薦"/><category term="版聚"/><category term="籌碼"/><category term="線上工具"/><title type='text'>iInfo 資訊交流</title><subtitle type='html'>我是Amin，喜好整合軟體之間的應用至數據分析，如Excel VBA、Python、C/C++、C#、JavaScript、Google  Apps Script、Batch、MultiCharts的相互應用，歡迎各領域同好相互討論，創造人生精采的火花&#xa;</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>399</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-6744402439998603464</id><published>2023-08-24T23:27:00.005-07:00</published><updated>2023-08-24T23:27:30.639-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><category scheme="http://www.blogger.com/atom/ns#" term="Ta-lib"/><title type='text'>Python TA-Lib 套件建置安裝</title><content type='html'>&lt;p&gt;&amp;nbsp;Ta-Lib 是一個 Python 金融套件，主要用來計算金融數據指標與K線型態的套件，該套件安裝上有分成使用 whl 包安裝 &lt;a href=&quot;https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib&lt;/a&gt;&amp;nbsp;安裝與透過 C++ 自行建置套件的方式2種，但對於 Windwos 的使用者來說自行建置的方式相對不友善，以下將介紹如何在Windows環境上自行建置 Ta-Lib 套件與安裝。&lt;/p&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;p&gt;在 Windows 上，若直接下 pip install ta-lib 是無法進行安裝 ta-lib 套件，原因缺少相關Visual Studio 2015 的編譯程式編譯的檔案所導致。&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrqNsUT8JeEfqstpgD9Xi-gwQWWQDwiH4Eam2HgD8cVlT-ggUwz4Fg5k4UqeUwMrYjyNpnjDTv7lFieHZRoLaNW5LSoNn0yLEWe2WIAACKHyVKWPwT3rn7VBfNWDWdmtBQ-6SuuLVBeIWBX_u54xCDrTPV5Tr8wEYDDoWqWFyPKIR2msuDKBrsHVfZ5hU/s1237/20230825-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1031&quot; data-original-width=&quot;1237&quot; height=&quot;334&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrqNsUT8JeEfqstpgD9Xi-gwQWWQDwiH4Eam2HgD8cVlT-ggUwz4Fg5k4UqeUwMrYjyNpnjDTv7lFieHZRoLaNW5LSoNn0yLEWe2WIAACKHyVKWPwT3rn7VBfNWDWdmtBQ-6SuuLVBeIWBX_u54xCDrTPV5Tr8wEYDDoWqWFyPKIR2msuDKBrsHVfZ5hU/w400-h334/20230825-1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;依據 Ta-Lib GitHub 在 Windows 環境的建置方法如：&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimSGYM5RdXqh_sVlDLshr5jxOaOfxYjjH5yTTKYw8-tpeOnPvtf6bhgmhbz-gE0bV1ouJGA8QobwA8BnqwaonmUXEnGDlzOnFY-uaXtZcbvcPWFJBfKt7sS0l06vUs846npEWpIcp75VAXMjtS4X2MBacqry2CFiTcvfC0FmcluThSTOZVELL1FtdbjYs/s839/20230825-0.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;378&quot; data-original-width=&quot;839&quot; height=&quot;180&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimSGYM5RdXqh_sVlDLshr5jxOaOfxYjjH5yTTKYw8-tpeOnPvtf6bhgmhbz-gE0bV1ouJGA8QobwA8BnqwaonmUXEnGDlzOnFY-uaXtZcbvcPWFJBfKt7sS0l06vUs846npEWpIcp75VAXMjtS4X2MBacqry2CFiTcvfC0FmcluThSTOZVELL1FtdbjYs/w400-h180/20230825-0.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;步驟1：下載&amp;nbsp;&lt;a href=&quot;http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-msvc.zip&quot;&gt;ta-lib-0.4.0-msvc.zip&lt;/a&gt;&amp;nbsp;壓縮檔，並解壓縮到 C:\ta-lib，請注意這個步驟，一定要加檔案解壓縮至 C:\ta-lib，若放置他處將無法順利安裝。&lt;/p&gt;&lt;p&gt;步驟2：至微軟官網下載&amp;nbsp;&lt;a href=&quot;https://visualstudio.microsoft.com/zh-hant/vs/community/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Visual Studio Community&lt;/a&gt;&amp;nbsp;軟體安裝。&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkUXoHDYF2wgngPgWCGNW8AECz4MwH6pOIoGoEPSnILBtpdhOX9DFNfckuMqr7b4E6api1TRQhfl6QS3rzkQNjfRXFNruRjV3pyT27X-K5stlVm0joZ9Mt2hiGt1niAKfqH7q2n9_yl5J3rP3jLUZz-7OveDsOKOUW4wAx29IdDOs-X6mC25VQaPxAQ6s/s480/20230825-2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;282&quot; data-original-width=&quot;480&quot; height=&quot;235&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkUXoHDYF2wgngPgWCGNW8AECz4MwH6pOIoGoEPSnILBtpdhOX9DFNfckuMqr7b4E6api1TRQhfl6QS3rzkQNjfRXFNruRjV3pyT27X-K5stlVm0joZ9Mt2hiGt1niAKfqH7q2n9_yl5J3rP3jLUZz-7OveDsOKOUW4wAx29IdDOs-X6mC25VQaPxAQ6s/w400-h235/20230825-2.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRfJ19t5WYfQT5h_TOeZusttFYcBW9MjoK1ShOdiJ3mAB3WUOnl2ynCpvW4wqBdeTeXW3YWrfcMoBfM7X1HxNtSuOMSZ0lrRIlm7zNPbpTPrWSSUPokfkGtgVVW4eH-0fOv4qGaSSgA8UsBloN8Fg_Smb2UAojgytRwb_ZWm33qL9JPVB5GPCl1Yt-j-s/s480/20230825-3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;282&quot; data-original-width=&quot;480&quot; height=&quot;235&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRfJ19t5WYfQT5h_TOeZusttFYcBW9MjoK1ShOdiJ3mAB3WUOnl2ynCpvW4wqBdeTeXW3YWrfcMoBfM7X1HxNtSuOMSZ0lrRIlm7zNPbpTPrWSSUPokfkGtgVVW4eH-0fOv4qGaSSgA8UsBloN8Fg_Smb2UAojgytRwb_ZWm33qL9JPVB5GPCl1Yt-j-s/w400-h235/20230825-3.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;步驟3：安裝&amp;nbsp;「使用C++的桌面開發」與「MSVC v140 - VS 2015 C++ 建置工具 (v14.00)」。&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFiYLJ6AVKkICc0GsDQTK_TUtHBX5VL2xbCFGw1_35vjXSdx7IBhpF-z4WXXIyJhyeasAeFsOprxBdQdUiA55blthsDazsn_8aPG4cMrTT2aw9AguUysQXkzxQP6ZxsBWl5e1Z8tPuZSb3TXfyuwgVXCfwOEKP-OJSuVBXNEiXNzvVIGisZ1TKLz36KsI/s1280/20230825-4.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;720&quot; data-original-width=&quot;1280&quot; height=&quot;225&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFiYLJ6AVKkICc0GsDQTK_TUtHBX5VL2xbCFGw1_35vjXSdx7IBhpF-z4WXXIyJhyeasAeFsOprxBdQdUiA55blthsDazsn_8aPG4cMrTT2aw9AguUysQXkzxQP6ZxsBWl5e1Z8tPuZSb3TXfyuwgVXCfwOEKP-OJSuVBXNEiXNzvVIGisZ1TKLz36KsI/w400-h225/20230825-4.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikpIhbfJK0PcYysfclP7R5K1ZvagFKDeAi1nBt5KHYRZxPhPH8Vgftn18QEQs5dpV2KKK07d_mP33uXNUhWn6jqrt73pZ_x-9opN8nhfTFU_kxWwyN2T-phu7WzHK2mrahppCYzJLBHdxCTxrta7sJtlIwnIe8ueCPxS0fb14ADosk4g4VstFsjFnLZbs/s1280/20230825-5.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;720&quot; data-original-width=&quot;1280&quot; height=&quot;225&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikpIhbfJK0PcYysfclP7R5K1ZvagFKDeAi1nBt5KHYRZxPhPH8Vgftn18QEQs5dpV2KKK07d_mP33uXNUhWn6jqrt73pZ_x-9opN8nhfTFU_kxWwyN2T-phu7WzHK2mrahppCYzJLBHdxCTxrta7sJtlIwnIe8ueCPxS0fb14ADosk4g4VstFsjFnLZbs/w400-h225/20230825-5.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;步驟4：開啟 VS2016 x64 Native Tools 命令提示字元。&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEie2ZeqeVbrEgV-DIes3yLrqrdCBUtT2lxrflauGa19XgH-g0WIKSa7PO9ayxyx4e4yl-x6umNn2sMfDiqqnR7EQ_AmSARv259lIlE-9NLv1vXxWIgJss8dcxqTh97gjxmYbb7_8ZtUTiKWHmYy3MWmBQn1zp64ksVAH-_J-IUAzJ8s902Tr_YRFtlaqxk/s643/20230825-7.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;643&quot; data-original-width=&quot;322&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEie2ZeqeVbrEgV-DIes3yLrqrdCBUtT2lxrflauGa19XgH-g0WIKSa7PO9ayxyx4e4yl-x6umNn2sMfDiqqnR7EQ_AmSARv259lIlE-9NLv1vXxWIgJss8dcxqTh97gjxmYbb7_8ZtUTiKWHmYy3MWmBQn1zp64ksVAH-_J-IUAzJ8s902Tr_YRFtlaqxk/w200-h400/20230825-7.png&quot; width=&quot;200&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;步驟5：將路徑切換到 C:\ta-lib\c\make\cdr\win32\msvc，輸入 nmake 建置 ta-lib 套件。&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPrtJmR5u6tzwy8BWJVpAI3Zl2FTpAWfIogjT-tGJ38LIeL5Q03S8kYSnXno5p8cxObwOUeoEs3M76sw5Azfi66dMb0gxs8b5cm-8tA_J37YpLuuXy9YsEi5BtQK_HzIkLvKyDwXdD5RGys43ibcBb19U1i0rILorFxeO39ufMjrBaqUZMRec0be1dTK8/s979/20230825-9.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;508&quot; data-original-width=&quot;979&quot; height=&quot;208&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPrtJmR5u6tzwy8BWJVpAI3Zl2FTpAWfIogjT-tGJ38LIeL5Q03S8kYSnXno5p8cxObwOUeoEs3M76sw5Azfi66dMb0gxs8b5cm-8tA_J37YpLuuXy9YsEi5BtQK_HzIkLvKyDwXdD5RGys43ibcBb19U1i0rILorFxeO39ufMjrBaqUZMRec0be1dTK8/w400-h208/20230825-9.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-kLGcwB6_8AGrj7C6nhc3GCGebquC4MooEgjZ1nE11F4qLpwypsQ1MYpCANq0dTYKQzz_kGGPi-CV1Kj3yrT6AxjfXNRcH8Njt1jr8jsg8MDe4UiGVOh4kv9e-UrzrK2kd5PesBf3VTWdRLYpC_xVEHEPQgL3Jt98Mi4nxYmRrvyNggs8vUauU0sAP1Y/s979/20230825-10.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;508&quot; data-original-width=&quot;979&quot; height=&quot;208&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-kLGcwB6_8AGrj7C6nhc3GCGebquC4MooEgjZ1nE11F4qLpwypsQ1MYpCANq0dTYKQzz_kGGPi-CV1Kj3yrT6AxjfXNRcH8Njt1jr8jsg8MDe4UiGVOh4kv9e-UrzrK2kd5PesBf3VTWdRLYpC_xVEHEPQgL3Jt98Mi4nxYmRrvyNggs8vUauU0sAP1Y/w400-h208/20230825-10.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;步驟6：輸入 pip install ta-lib 進行套件安裝。&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUAZdKHSEq49iKJW4YIDHj5LQequfOj3n2KDjxTHuqgXb5sRn_0OnZmi7QWIRyXYKtaVF3lRUk-U7G7TNegc4ctjkY5ipF0AWdWEWk4Tnw66Z_kx-HZqFAc_eSc38voXZLpOwI6ntoD27Qn7b-jOGyxjIJwQyLlF3u9K3kbSiyLblaoMi_Cm7uwl2tqts/s979/20230825-11.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;508&quot; data-original-width=&quot;979&quot; height=&quot;208&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUAZdKHSEq49iKJW4YIDHj5LQequfOj3n2KDjxTHuqgXb5sRn_0OnZmi7QWIRyXYKtaVF3lRUk-U7G7TNegc4ctjkY5ipF0AWdWEWk4Tnw66Z_kx-HZqFAc_eSc38voXZLpOwI6ntoD27Qn7b-jOGyxjIJwQyLlF3u9K3kbSiyLblaoMi_Cm7uwl2tqts/w400-h208/20230825-11.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;步驟7：最後輸入 python -c &quot;import talib&quot;，只要沒出現錯誤訊息表示成功安裝 Ta-Lib 套件。&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJbOP6meHTXfkvGgzhAhiPT6fcOziUMXiq3VG9bAl6mh9KBpuiigMhpxzu-_X3sF53C9FGugUPxvIw7qzbPTae-CFfVL7QcND7Oaz4dTXQwaugzhbSqLfPoc-nCHPjCuPyH6sDJNEBk_uTOYXk0SkAUlyp1ulVrsyuKeNscvXfKFGczIbcNJvjU7cwud8/s979/20230825-12.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;508&quot; data-original-width=&quot;979&quot; height=&quot;208&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJbOP6meHTXfkvGgzhAhiPT6fcOziUMXiq3VG9bAl6mh9KBpuiigMhpxzu-_X3sF53C9FGugUPxvIw7qzbPTae-CFfVL7QcND7Oaz4dTXQwaugzhbSqLfPoc-nCHPjCuPyH6sDJNEBk_uTOYXk0SkAUlyp1ulVrsyuKeNscvXfKFGczIbcNJvjU7cwud8/w400-h208/20230825-12.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/6744402439998603464/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2023/08/python-ta-lib.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/6744402439998603464'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/6744402439998603464'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2023/08/python-ta-lib.html' title='Python TA-Lib 套件建置安裝'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrqNsUT8JeEfqstpgD9Xi-gwQWWQDwiH4Eam2HgD8cVlT-ggUwz4Fg5k4UqeUwMrYjyNpnjDTv7lFieHZRoLaNW5LSoNn0yLEWe2WIAACKHyVKWPwT3rn7VBfNWDWdmtBQ-6SuuLVBeIWBX_u54xCDrTPV5Tr8wEYDDoWqWFyPKIR2msuDKBrsHVfZ5hU/s72-w400-h334-c/20230825-1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-2493766335168671779</id><published>2023-06-01T23:09:00.007-07:00</published><updated>2023-06-05T19:43:25.384-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Android Studio"/><title type='text'>Android Studio環境設定與問題處理</title><content type='html'>&lt;p&gt;
  &amp;nbsp;近期工作又需要再使用Android
  Studio，在執行專案後模擬器都無法正常，移除重裝了好幾次，最後似乎看到了解決的曙光，將過程整理與記錄下來，方便之後在遇到相同問題時可以解決。
&lt;/p&gt;
&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
  &lt;li&gt;下載 Android Studio&lt;/li&gt;
  &lt;ul style=&quot;text-align: left;&quot;&gt;
    &lt;li&gt;下載最新版的 Android Studio&lt;/li&gt;
    &lt;ul&gt;
      &lt;li&gt;連結：https://developer.android.com/studio&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li&gt;若因為專案需求要下載舊版Android Studio&lt;/li&gt;
    &lt;ul&gt;
      &lt;li&gt;連結：https://developer.android.com/studio/archive?hl=zh-tw&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;
  &lt;li&gt;安裝Android Studio後的環境變數設定&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;JDK環境變數&lt;/li&gt;
    &lt;ul&gt;
      &lt;li&gt;JDK下載：https://www.oracle.com/tw/java/technologies/downloads/&lt;/li&gt;
      &lt;li&gt;Windwos上環境變數設定&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;

  &lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
    &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIsavjXr8wWwdI2T52tGpE3Laezl3Ve2TAKuVT6tApLbNV6UDcoTD210iYsZD0k5ppluro1GXvNacluclIoy3pD8HhkVldP42VuL_tZ-AnlTgLoNPDc3RHyL1oXLwwsoh0wPKKKuVnkdZfYuo8h6rvbNKvxyMY0Qc1ZRk35HwYC7jVfSBtIS2G_DNu/s657/20230602-1.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;591&quot; data-original-width=&quot;657&quot; height=&quot;360&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIsavjXr8wWwdI2T52tGpE3Laezl3Ve2TAKuVT6tApLbNV6UDcoTD210iYsZD0k5ppluro1GXvNacluclIoy3pD8HhkVldP42VuL_tZ-AnlTgLoNPDc3RHyL1oXLwwsoh0wPKKKuVnkdZfYuo8h6rvbNKvxyMY0Qc1ZRk35HwYC7jVfSBtIS2G_DNu/w400-h360/20230602-1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;
  &lt;/div&gt;

  &lt;ul style=&quot;text-align: center;&quot;&gt;
    &lt;li style=&quot;text-align: left;&quot;&gt;Android SDK環境變數&lt;/li&gt;
    &lt;ul&gt;
      &lt;li style=&quot;text-align: left;&quot;&gt;變數名稱：ANDROID_SDK_HOME&lt;/li&gt;
      &lt;li style=&quot;text-align: left;&quot;&gt;
        變數路徑：C:\Users\Amin\AppData\Local\Android\Sdk
      &lt;/li&gt;
      &lt;li style=&quot;text-align: left;&quot;&gt;Windwos上環境變數設定&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;

  &lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
    &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitEmIDr643x7BNTrvVU0rAQ5qoOpddp-Jz1xUKuG01ANHtr1dRZPpXT107BFDOdS0cN57hw0qx7rg014-oNI-2fI1ZjP7CfJrGy6iDnz9OaLYoRtYDZY88Ch4HQ2IXveIxRK8rZVSbfpuN9Q-G5X2PPYdti8UtsHkAu-FsFTtOa4fyVdUquV6xn7YL/s658/20230602-2.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;591&quot; data-original-width=&quot;658&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitEmIDr643x7BNTrvVU0rAQ5qoOpddp-Jz1xUKuG01ANHtr1dRZPpXT107BFDOdS0cN57hw0qx7rg014-oNI-2fI1ZjP7CfJrGy6iDnz9OaLYoRtYDZY88Ch4HQ2IXveIxRK8rZVSbfpuN9Q-G5X2PPYdti8UtsHkAu-FsFTtOa4fyVdUquV6xn7YL/s400/20230602-2.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;
  &lt;/div&gt;

  &lt;ul style=&quot;text-align: center;&quot;&gt;
    &lt;li style=&quot;text-align: left;&quot;&gt;path下新增環境變數&lt;/li&gt;
    &lt;ul&gt;
      &lt;li style=&quot;text-align: left;&quot;&gt;
        變數路徑：&lt;br /&gt;
        %JAVA_HOME%\bin&lt;br /&gt;
        %JAVA_HOME%\jre\bin&lt;br /&gt;
        %ANDROID_SDK_HOME%\platform-tools&lt;br /&gt;
        %ANDROID_SDK_HOME%\tools
      &lt;/li&gt;
      &lt;li style=&quot;text-align: left;&quot;&gt;Windwos上環境變數設定&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;
  &lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
    &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYaLUVUHGyhXwYhtIZOU8FZtMI5IPHD0JnbQzDSp5OPcCzA4moIGAaLgOqyrLEi-2m8oJ6xdIxwVwV4iHuorMOjuJPdbXtGUzFQDwPAzKKTV-kSLjaDE5NI1S-h3-r-8FJQifnp-ZKKLg5Kmyy06HcabnqzEooMdnn8USudZZ4jGN9BBa7G-63itXD/s618/20230602-3.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;581&quot; data-original-width=&quot;618&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYaLUVUHGyhXwYhtIZOU8FZtMI5IPHD0JnbQzDSp5OPcCzA4moIGAaLgOqyrLEi-2m8oJ6xdIxwVwV4iHuorMOjuJPdbXtGUzFQDwPAzKKTV-kSLjaDE5NI1S-h3-r-8FJQifnp-ZKKLg5Kmyy06HcabnqzEooMdnn8USudZZ4jGN9BBa7G-63itXD/s400/20230602-3.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;
  &lt;/div&gt;

  &lt;li&gt;修改模擬器設定~/.android/avd/[[name of your avd]].avd/config.ini&lt;/li&gt;
  當發生如畫面錯誤，要調整disk.dataPartition.size。&lt;br /&gt;
  &lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
    &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMWlhrPgMYWt-eKSDWNDYPTQE89qU2kQjG0hkcVlyTYDqaQtO4R2jssOmQD3u4Mcyl70VTlInua31CdJ7Ps7YhKkEiZ6mYjBgGW3jnJ0JDSSK_YDBKFMjlsaQJ7-5s_nq6aAomJNPstlkLHb0QX7iVk0jgkHWbTTVDUb4iImMGDNHuiuivmPvsgEos/s1475/20230602-4.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;997&quot; data-original-width=&quot;1475&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMWlhrPgMYWt-eKSDWNDYPTQE89qU2kQjG0hkcVlyTYDqaQtO4R2jssOmQD3u4Mcyl70VTlInua31CdJ7Ps7YhKkEiZ6mYjBgGW3jnJ0JDSSK_YDBKFMjlsaQJ7-5s_nq6aAomJNPstlkLHb0QX7iVk0jgkHWbTTVDUb4iImMGDNHuiuivmPvsgEos/s400/20230602-4.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;
  &lt;/div&gt;
  &lt;ul&gt;
    &lt;li&gt;disk.dataPartition.size = 512M&lt;/li&gt;
    &lt;li&gt;fastboot.forceColdBoot = yes&lt;/li&gt;
    &lt;li&gt;fastboot.forceFastBoot = no&lt;/li&gt;
  &lt;/ul&gt;
  &lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9_yZ28TIxNI91hbROjYc7DWEu5STY_rhKa9X2UXWIPdBXZ1aY07NVYbBklmdygoZZt_nQfu_aOIHtfHzTM_pabKE3dmarX0uOd_ItNPMsbxnDiCLpJmKJnq8oTyb_bs440QoqaDAfhmRcofsl6QP9lp3gdjZQ_MEH3LHJLV9gKotXkaxHvGGIGtws/s893/20230602-5.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;643&quot; data-original-width=&quot;893&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9_yZ28TIxNI91hbROjYc7DWEu5STY_rhKa9X2UXWIPdBXZ1aY07NVYbBklmdygoZZt_nQfu_aOIHtfHzTM_pabKE3dmarX0uOd_ItNPMsbxnDiCLpJmKJnq8oTyb_bs440QoqaDAfhmRcofsl6QP9lp3gdjZQ_MEH3LHJLV9gKotXkaxHvGGIGtws/s400/20230602-5.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;li&gt;發生&amp;nbsp;INSTALL_FAILED_NO_MATCHING_ABIS 錯誤&lt;/li&gt;
    &lt;ul&gt;
    &lt;li&gt;The application could not be installed: INSTALL_FAILED_NO_MATCHING_ABIS&lt;/li&gt;&lt;li&gt;Installation failed due to: &#39;INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res=-113&#39;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilDnCMv3ReidB2Z2v2_d0XNf5X7AMM9m94ua6vp6RXcUryxvSe6yt2ikkYJpSwdk6BMPZes6-hQ4m84ZbSukZ2xNHZ80g_zHYHk2qz6V1mUJkcmNWtbvonFAPhnvckIYdY5yedsL9PbS5ftQNNgqPf3yIzGTGZF-GL5Uezq_aVsdjLCmhmIx0l2oF_/s911/20230606-1.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;266&quot; data-original-width=&quot;911&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilDnCMv3ReidB2Z2v2_d0XNf5X7AMM9m94ua6vp6RXcUryxvSe6yt2ikkYJpSwdk6BMPZes6-hQ4m84ZbSukZ2xNHZ80g_zHYHk2qz6V1mUJkcmNWtbvonFAPhnvckIYdY5yedsL9PbS5ftQNNgqPf3yIzGTGZF-GL5Uezq_aVsdjLCmhmIx0l2oF_/s400/20230606-1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
    &lt;ul&gt;
    &lt;li&gt;解決方式：在app的build:gradle中添加以下內容&lt;/li&gt;
    splits {&lt;br /&gt;
        &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;abi {&lt;br /&gt;
            &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;enable true&lt;br /&gt;
            &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;reset()&lt;br /&gt;
            &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;include &#39;x86&#39;,&#39;x86_64&#39;,&#39;armeabi&#39;,&#39;armeabi-v7a&#39;,&#39;mips&#39;,&#39;mips64&#39;,&#39;arm64-v8a&#39;&lt;br /&gt;
            &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;universalApk true&lt;br /&gt;
        &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;}&lt;br /&gt;
    }&lt;br /&gt;
  &lt;/ul&gt;
  
&lt;/ol&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/2493766335168671779/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2023/06/android-studio.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/2493766335168671779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/2493766335168671779'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2023/06/android-studio.html' title='Android Studio環境設定與問題處理'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIsavjXr8wWwdI2T52tGpE3Laezl3Ve2TAKuVT6tApLbNV6UDcoTD210iYsZD0k5ppluro1GXvNacluclIoy3pD8HhkVldP42VuL_tZ-AnlTgLoNPDc3RHyL1oXLwwsoh0wPKKKuVnkdZfYuo8h6rvbNKvxyMY0Qc1ZRk35HwYC7jVfSBtIS2G_DNu/s72-w400-h360-c/20230602-1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-4817547134017474322</id><published>2021-03-17T19:44:00.011-07:00</published><updated>2021-11-14T20:26:47.220-08:00</updated><title type='text'>新書出版：Python x Excel VBA x JavaScript｜網路爬蟲 x 實戰演練</title><content type='html'>&lt;div&gt;感謝長期關注部落格的朋友們，小弟預計在 2021/3/26出版第二本書&lt;span style=&quot;color: #2b00fe;&quot;&gt;《Python x Excel VBA x JavaScript｜網路爬蟲 x 實戰演練》&lt;/span&gt;，距離第一本書&lt;span style=&quot;color: #6aa84f;&quot;&gt;《Excel VBA 實戰技巧｜金融數據x網路爬蟲》&lt;/span&gt;快2年了。&lt;br /&gt;
  &lt;a name=&#39;more&#39;&gt;&lt;/a&gt;若您喜歡本書第一本書&lt;span style=&quot;color: #6aa84f;&quot;&gt;《Excel VBA 實戰技巧｜金融數據x網路爬蟲》&lt;/span&gt;的內容，那這本書&lt;span style=&quot;color: #2b00fe;&quot;&gt;《Python x Excel VBA x JavaScript｜網路爬蟲 x 實戰演練》&lt;/span&gt;您也不能錯過，這本書結合了Python、Excel VBA、JavaScript內容，是非常值得研讀與學習的爬蟲書籍。&lt;br /&gt;&lt;br /&gt;
  如果大家喜歡小弟寫的書籍，請用「新台幣」讓它下架， 按讚、分享及留言，並在購書網頁按讚，讓更多人知道這本書存在，因為真的太超值了，謝謝。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-fW8i1Q0poKELmIuk2PPH2E8I9upU3cnlDG_D1E6uVTWa-VdngoL1gmmT7HYxDX0elD3YWCY8yVr4UFkqlQ7oPP2bHL1qIBr-J4BZZA2lJ3vBgvGxp4X4a2AyNhO6OBH0Md6dS2UYLQw/s257/ACD020100.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;257&quot; data-original-width=&quot;190&quot; height=&quot;407&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-fW8i1Q0poKELmIuk2PPH2E8I9upU3cnlDG_D1E6uVTWa-VdngoL1gmmT7HYxDX0elD3YWCY8yVr4UFkqlQ7oPP2bHL1qIBr-J4BZZA2lJ3vBgvGxp4X4a2AyNhO6OBH0Md6dS2UYLQw/w301-h407/ACD020100.jpg&quot; width=&quot;301&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
天瓏&lt;br /&gt;&lt;a href=&quot;https://www.tenlong.com.tw/products/9789865027698&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://www.tenlong.com.tw/products/9789865027698&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;
博客來&lt;br /&gt;&lt;a href=&quot;https://www.books.com.tw/products/0010887169&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://www.books.com.tw/products/0010887169&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;
金石堂&lt;br /&gt;&lt;a href=&quot;https://www.kingstone.com.tw/basic/2014713613240&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://www.kingstone.com.tw/basic/2014713613240&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;
MOMO&lt;br /&gt;&lt;a href=&quot;https://www.momoshop.com.tw/goods/GoodsDetail.jsp?i_code=8696355&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://www.momoshop.com.tw/goods/GoodsDetail.jsp?i_code=8696355&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;
碁峰圖書&lt;br /&gt;&lt;a href=&quot;http://books.gotop.com.tw/v_ACD020100&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;http://books.gotop.com.tw/v_ACD020100&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/4817547134017474322/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2021/03/python-x-excel-vba-x-javascript-x.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/4817547134017474322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/4817547134017474322'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2021/03/python-x-excel-vba-x-javascript-x.html' title='新書出版：Python x Excel VBA x JavaScript｜網路爬蟲 x 實戰演練'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-fW8i1Q0poKELmIuk2PPH2E8I9upU3cnlDG_D1E6uVTWa-VdngoL1gmmT7HYxDX0elD3YWCY8yVr4UFkqlQ7oPP2bHL1qIBr-J4BZZA2lJ3vBgvGxp4X4a2AyNhO6OBH0Md6dS2UYLQw/s72-w301-h407-c/ACD020100.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-8699139286698183778</id><published>2021-03-12T00:28:00.011-08:00</published><updated>2021-03-16T02:05:53.268-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Google OAuth"/><title type='text'>Google、Facebook、Line OAuth 實做登入操作 (4) - 將 Google Login 加入到 Android app  </title><content type='html'>今天 Login 進度到如何在 Android 上加入 Google Login ，一樣手把手一步一步操作。&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;br /&gt;步驟1：在Android Studio 建立App「GoogleLogin」，在 MainActivity.java 輸入以下程式碼。&lt;br /&gt;
&lt;pre class=&quot;brush:java&quot;&gt;package com.amin.googlelogin;

import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.Scopes;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.Scope;
import com.google.android.gms.tasks.Task;

public class MainActivity extends AppCompatActivity {
    private SignInButton signInButton;
    private static final int RC_SIGN_IN = 1;

    //https://stackoverflow.com/questions/47437678/why-do-i-get-com-google-android-gms-common-api-apiexception-10
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 設定 Google 登入 Client
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestScopes(new Scope(Scopes.OPEN_ID), new Scope(Scopes.PLUS_ME))
                .requestIdToken(getString(R.string.default_web_client_id))
                .requestProfile()
                .requestEmail()
                .build();

        final GoogleSignInClient mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
        SignInButton signInBtn = findViewById(R.id.login_button);
        signInBtn.setOnClickListener(new View.OnClickListener() {

            private void signIn() {
                Intent signInIntent = mGoogleSignInClient.getSignInIntent();
                startActivityForResult(signInIntent, RC_SIGN_IN);
            }

            public void onClick(View v) {
                switch (v.getId()) {
                    case R.id.login_button:
                        signIn();
                        break;
                }
            }
        });
    }

    //https://developers.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInAccount
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == RC_SIGN_IN) {
            // The Task returned from this call is always completed, no need to attach a listener.
            Task&amp;lt;GoogleSignInAccount&amp;gt; task = GoogleSignIn.getSignedInAccountFromIntent(data);

            handleSignInResult(task);
        }
    }

    private void handleSignInResult(Task&amp;lt;GoogleSignInAccount&amp;gt; completedTask) {
        try {//代表有成功
            GoogleSignInAccount account = completedTask.getResult(ApiException.class);

            // Signed in successfully, show authenticated UI.
            Log.d(&quot;GoogleLoginlog&quot;, &quot;DisplayName : &quot;  + account.getDisplayName());
            Log.d(&quot;GoogleLoginlog&quot;, &quot;GivenName : &quot;  + account.getGivenName());
            Log.d(&quot;GoogleLoginlog&quot;, &quot;FamilyName : &quot;  + account.getFamilyName());
            Log.d(&quot;GoogleLoginlog&quot;, &quot;Email : &quot;  + account.getEmail());
            Log.d(&quot;GoogleLoginlog&quot;, &quot;Id : &quot;  + account.getId());
            Log.d(&quot;GoogleLoginlog&quot;, &quot;idtoken : &quot;  + account.getIdToken());
            Log.d(&quot;GoogleLoginlog&quot;, &quot;PhotoUrl : &quot;  + account.getPhotoUrl());

            Intent it = new Intent(this, showinfo.class);
            it.putExtra(&quot;displayname&quot;, account.getDisplayName());
            it.putExtra(&quot;givenname&quot;, account.getGivenName());
            it.putExtra(&quot;familyname&quot;, account.getFamilyName());
            it.putExtra(&quot;id&quot;, account.getId());
            it.putExtra(&quot;idtoken&quot;, account.getIdToken());
            it.putExtra(&quot;email&quot;, account.getEmail());
            it.putExtra(&quot;photourl&quot;, account.getPhotoUrl().toString());
            startActivity(it);
        } catch (ApiException e) {//代表沒成功
            // The ApiException status code indicates the detailed failure reason.
            // Please refer to the GoogleSignInStatusCodes class reference for more information.
            Log.w(&quot;TAG&quot;, &quot;signInResult:failed code=&quot; + e.getStatusCode());

        }
    }
}&lt;/pre&gt;
在 activity_main.xml 添加&lt;br /&gt;
&lt;pre class=&quot;brush:xml&quot;&gt;     &amp;lt;com.google.android.gms.common.SignInButton
        android:id=&quot;@+id/login_button&quot;
        android:layout_width=&quot;246dp&quot;
        android:layout_height=&quot;75dp&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintHorizontal_bias=&quot;0.496&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;
        app:layout_constraintVertical_bias=&quot;0.453&quot; /&amp;gt;
&lt;/pre&gt;
步驟2：新增「showinfo」的 Empty Activity，在 showinfo.java 輸入以下程式碼。&lt;br /&gt;
&lt;pre class=&quot;brush:java&quot;&gt;package com.amin.googlelogin;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;

public class showinfo extends AppCompatActivity {

    private Button logoutBtn;
    GoogleSignInClient mGoogleSignInClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_showinfo);

        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .build();

        // Build a GoogleSignInClient with the options specified by gso.
        mGoogleSignInClient = GoogleSignIn.getClient(this, gso);

        final Button m_button  = (Button) findViewById(R.id.button);
        m_button.setOnClickListener(new Button.OnClickListener(){
            @Override
            public void onClick(View v) {
                Intent it = new Intent(showinfo.this, MainActivity.class);
                startActivity(it);
                finish();
            }
        });

        logoutBtn = findViewById(R.id.logoutBtn);
        logoutBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                signOut();
            }
        });

        TextView result = null;

        Intent intent = getIntent();
        String displayname = intent.getStringExtra(&quot;displayname&quot;);
        result = (TextView) findViewById(R.id.displayname);
        result.setText(&quot;使用者displayname : &quot; + displayname);

        String givenname = intent.getStringExtra(&quot;givenname&quot;);
        result = (TextView) findViewById(R.id.givenname);
        result.setText(&quot;使用者givenname : &quot; + givenname);

        String familyname = intent.getStringExtra(&quot;familyname&quot;);
        result = (TextView) findViewById(R.id.familyname);
        result.setText(&quot;使用者familyname : &quot; + familyname);

        String id = intent.getStringExtra(&quot;id&quot;);
        result = (TextView) findViewById(R.id.id);
        result.setText(&quot;使用者id : &quot; + id);

        String idtoken = intent.getStringExtra(&quot;idtoken&quot;);
        result = (TextView) findViewById(R.id.idtoken);
        result.setText(&quot;使用者idtoekn : &quot; + idtoken);

        String email = intent.getStringExtra(&quot;email&quot;);
        result = (TextView) findViewById(R.id.email);
        result.setText(&quot;使用者email : &quot; + email);

        String photourl = intent.getStringExtra(&quot;photourl&quot;);
        result = (TextView) findViewById(R.id.photourl);
        result.setText(&quot;圖片連結 : &quot; + photourl);
    }

    private void signOut() {
        mGoogleSignInClient.signOut()
                .addOnCompleteListener(this, new OnCompleteListener() {
                    @Override
                    public void onComplete(@NonNull Task task) {
                        Intent intent = new Intent(showinfo.this, MainActivity.class);
                        startActivity(intent);
                    }
                });
        Toast.makeText(this, &quot;登出成功!!&quot;, Toast.LENGTH_SHORT).show();
    }
}
&lt;/pre&gt;
在 activity_showinfo.xml 添加&lt;br /&gt;
&lt;pre class=&quot;brush:xml&quot;&gt;   &amp;lt;TextView
        android:id=&quot;@+id/idtoken&quot;
        android:layout_width=&quot;300dp&quot;
        android:layout_height=&quot;50dp&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintHorizontal_bias=&quot;0.405&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;
        app:layout_constraintVertical_bias=&quot;0.599&quot; /&amp;gt;

    &amp;lt;TextView
        android:id=&quot;@+id/photourl&quot;
        android:layout_width=&quot;300dp&quot;
        android:layout_height=&quot;60dp&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintHorizontal_bias=&quot;0.405&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;
        app:layout_constraintVertical_bias=&quot;0.845&quot; /&amp;gt;

    &amp;lt;TextView
        android:id=&quot;@+id/id&quot;
        android:layout_width=&quot;300dp&quot;
        android:layout_height=&quot;40dp&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintHorizontal_bias=&quot;0.378&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;
        app:layout_constraintVertical_bias=&quot;0.499&quot; /&amp;gt;

    &amp;lt;TextView
        android:id=&quot;@+id/familyname&quot;
        android:layout_width=&quot;300dp&quot;
        android:layout_height=&quot;40dp&quot;
        android:layout_margin=&quot;10dp&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintHorizontal_bias=&quot;0.378&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;
        app:layout_constraintVertical_bias=&quot;0.384&quot; /&amp;gt;

    &amp;lt;Button
        android:id=&quot;@+id/logoutBtn&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_gravity=&quot;right&quot;
        android:text=&quot;登出&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintHorizontal_bias=&quot;0.498&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;
        app:layout_constraintVertical_bias=&quot;0.049&quot; /&amp;gt;

    &amp;lt;TextView
        android:id=&quot;@+id/givenname&quot;
        android:layout_width=&quot;300dp&quot;
        android:layout_height=&quot;40dp&quot;
        android:layout_margin=&quot;10dp&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintHorizontal_bias=&quot;0.351&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;
        app:layout_constraintVertical_bias=&quot;0.264&quot; /&amp;gt;

    &amp;lt;TextView
        android:id=&quot;@+id/displayname&quot;
        android:layout_width=&quot;300dp&quot;
        android:layout_height=&quot;40dp&quot;
        android:layout_margin=&quot;10dp&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintHorizontal_bias=&quot;0.351&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;
        app:layout_constraintVertical_bias=&quot;0.159&quot; /&amp;gt;

    &amp;lt;Button
        android:id=&quot;@+id/button&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:text=&quot;返回&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintHorizontal_bias=&quot;0.13&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;
        app:layout_constraintVertical_bias=&quot;0.049&quot; /&amp;gt;

    &amp;lt;TextView
        android:id=&quot;@+id/email&quot;
        android:layout_width=&quot;300dp&quot;
        android:layout_height=&quot;40dp&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintHorizontal_bias=&quot;0.378&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;
        app:layout_constraintVertical_bias=&quot;0.713&quot; /&amp;gt;
&lt;/pre&gt;
步驟3：在「專案」的 build.gradle 添加&amp;nbsp;「classpath &#39;com.google.gms:google-services:4.3.5&#39;」。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNQ1xZCybVjOIIH-5IFe0nQaspip7yBBwPFd9zObzrUpHgTuQKSAXuyKINn3dcKiq-0-RQRh8rvk6gaKYPywIROiofSZTIxrDSYXzvaHFI6DV5-_VkNPHijERLCVLZD0qaImOxyyENBnY/s1160/20210312-1.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;490&quot; data-original-width=&quot;1160&quot; height=&quot;169&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNQ1xZCybVjOIIH-5IFe0nQaspip7yBBwPFd9zObzrUpHgTuQKSAXuyKINn3dcKiq-0-RQRh8rvk6gaKYPywIROiofSZTIxrDSYXzvaHFI6DV5-_VkNPHijERLCVLZD0qaImOxyyENBnY/w400-h169/20210312-1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
步驟4：在「模組」的 build.gradle 添加&amp;nbsp;「implementation &#39;com.google.android.gms:play-services-auth:19.0.0&#39;」。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSnSsUHAumDRExohWnV8Qd19Hglrhfpoh0Y_-o_cwOFz6Z6iLvirzcDTCWyHl15_6I2E_xWvT91dHik8bQxyGjHVpx4dzZow7pxfe9vHEVSOGMp6bREx02Oc9Z9puBJ6haZD04GqrWQtw/s1224/20210312-2.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;808&quot; data-original-width=&quot;1224&quot; height=&quot;264&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSnSsUHAumDRExohWnV8Qd19Hglrhfpoh0Y_-o_cwOFz6Z6iLvirzcDTCWyHl15_6I2E_xWvT91dHik8bQxyGjHVpx4dzZow7pxfe9vHEVSOGMp6bREx02Oc9Z9puBJ6haZD04GqrWQtw/w400-h264/20210312-2.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
步驟5：在 AndroifManifest.xml 添加&amp;nbsp;「&amp;lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&amp;gt;」。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgfTH8d9_uhI8MLtGUHdPJ55k09sI2GT1_8YaWz4euJdPgP5_6cB6Uo8JDuGHUPlrFZMz8y8ALalopowPlDdvgrVcbT9frg3fWKHek6uVm0vn6RPep_5DbTo35kPYYW4AJlRPxQB4eOcg/s1034/20210312-3.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;537&quot; data-original-width=&quot;1034&quot; height=&quot;208&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgfTH8d9_uhI8MLtGUHdPJ55k09sI2GT1_8YaWz4euJdPgP5_6cB6Uo8JDuGHUPlrFZMz8y8ALalopowPlDdvgrVcbT9frg3fWKHek6uVm0vn6RPep_5DbTo35kPYYW4AJlRPxQB4eOcg/w400-h208/20210312-3.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;步驟6：點擊 Gradle &amp;gt;&amp;nbsp;Tasks &amp;gt; android &amp;gt; signingReport，產生SHA1金鑰。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7XfH0WxJ2HVIfBRCgHdp5v_CxgUpBKwJ49nxy2FoChTlRw9AxFQQGW1A-cyN6jbQEthWZtaM-InqdVRF5Zd-LYvu0bfoxWO3riP68JUcAVKic35AmIEPSbLI9IKI8GduJnt7i7LJaKpY/s1539/20210312-4.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1032&quot; data-original-width=&quot;1539&quot; height=&quot;269&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7XfH0WxJ2HVIfBRCgHdp5v_CxgUpBKwJ49nxy2FoChTlRw9AxFQQGW1A-cyN6jbQEthWZtaM-InqdVRF5Zd-LYvu0bfoxWO3riP68JUcAVKic35AmIEPSbLI9IKI8GduJnt7i7LJaKpY/w400-h269/20210312-4.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;步驟7：到 Google APIs&amp;nbsp; &lt;a href=&quot;https://console.developers.google.com/apis/credentials&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://console.developers.google.com/apis/credentials&lt;/a&gt;，新增憑證服務，這一步一定要做，不然&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;quot;Calibri&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 12.0pt; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: &amp;quot;Times New Roman&amp;quot;; mso-bidi-font-size: 11.0pt; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: 新細明體; mso-fareast-language: ZH-TW; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-latin;&quot;&gt;&amp;nbsp;MainActivity.java中，第62行無法成功執行&lt;/span&gt;。&lt;div&gt;(1) 點擊 建立憑證。&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVpJpfTP8kh1kjc3-wAs37e4DQGU0xqtkf-r903w1ANyYwMDP4ttwwuy_RJYaaN6NH9CkdaVVUokq9dRdQCxqMyRY0smhE9Y1iqVTAq1oFdXgXIv6IbDAn2M5SNDOumhHG_Gh11ElqFyU/s789/20210312-5.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;363&quot; data-original-width=&quot;789&quot; height=&quot;184&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVpJpfTP8kh1kjc3-wAs37e4DQGU0xqtkf-r903w1ANyYwMDP4ttwwuy_RJYaaN6NH9CkdaVVUokq9dRdQCxqMyRY0smhE9Y1iqVTAq1oFdXgXIv6IbDAn2M5SNDOumhHG_Gh11ElqFyU/w400-h184/20210312-5.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;(2) 點擊「Android」。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCT7m-59vNWAe_lVZqs-7K8KW_zIwtGULGu39BqyGZ9qR_p2pq34bT80fcf5auIrL8kl_RKVaxwv8WKuf0abzWZ9ZINRNb6SRnc1ytS0PNJD24le0JGXjkrbA5y2pGouqvSnq_AC0d_N0/s569/20210312-6.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;394&quot; data-original-width=&quot;569&quot; height=&quot;278&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCT7m-59vNWAe_lVZqs-7K8KW_zIwtGULGu39BqyGZ9qR_p2pq34bT80fcf5auIrL8kl_RKVaxwv8WKuf0abzWZ9ZINRNb6SRnc1ytS0PNJD24le0JGXjkrbA5y2pGouqvSnq_AC0d_N0/w400-h278/20210312-6.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
(3) 輸入建立 「建立OAuth 用戶端 ID」所需資料。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjErhAamCnEOLxshIjlgdjRI86F4uOA7cUHsM3dqjXu8uHBdO4r-PS3pO1GCDyMf6XNLszRWa2VljS3Bjccy3_CnhyFwTFaY4DDFLIBt43DhuGUHpIOFgdT2V9rUjfhpT9taY9SW0aqJA/s1551/20210312-7.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1035&quot; data-original-width=&quot;1551&quot; height=&quot;268&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjErhAamCnEOLxshIjlgdjRI86F4uOA7cUHsM3dqjXu8uHBdO4r-PS3pO1GCDyMf6XNLszRWa2VljS3Bjccy3_CnhyFwTFaY4DDFLIBt43DhuGUHpIOFgdT2V9rUjfhpT9taY9SW0aqJA/w400-h268/20210312-7.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;(4) 最後完成建立。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuLyfs0flppM0hexApDaNTff5aTrf_fcsmF3MWCZt-B3uxvwT-uuhj12QstO2gf220S381SDaJwnHHXgbLG-T8IJpwh_YFruNKjVXBEkRWBMdpEAMkHdC2cLLBXiZpmLlf7k2oSWjrbYY/s524/20210312-8.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;374&quot; data-original-width=&quot;524&quot; height=&quot;285&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuLyfs0flppM0hexApDaNTff5aTrf_fcsmF3MWCZt-B3uxvwT-uuhj12QstO2gf220S381SDaJwnHHXgbLG-T8IJpwh_YFruNKjVXBEkRWBMdpEAMkHdC2cLLBXiZpmLlf7k2oSWjrbYY/w400-h285/20210312-8.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjupFTF2mBOuGY_7dTfOOLOmC15F7bAemdOwQ0ZxHRD1iGNYd3-7uvqikXgyLdElxmIRTHmFs5uG7VLRstVX92IXss6idpPJASu_A8_gUpPjO9H5BYMkilUmnewEDc5Nli_CGLxSwASh58/s710/20210312-9.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;222&quot; data-original-width=&quot;710&quot; height=&quot;125&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjupFTF2mBOuGY_7dTfOOLOmC15F7bAemdOwQ0ZxHRD1iGNYd3-7uvqikXgyLdElxmIRTHmFs5uG7VLRstVX92IXss6idpPJASu_A8_gUpPjO9H5BYMkilUmnewEDc5Nli_CGLxSwASh58/w400-h125/20210312-9.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;最後 Build 專案。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoipatp-_jT0wHL7-sUT8Pq76hxNDDVyUwnup4z4YZLAj4IDf_RSgGweZKiRvFkEtWtqWpUCmPZjvwlexMSsMzhUB0m746Slf8zSmjD2fxWxnoOp7W8x2Ot-sh8NX1hordvLU1chPInxo/s904/20210312-10.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;904&quot; data-original-width=&quot;460&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoipatp-_jT0wHL7-sUT8Pq76hxNDDVyUwnup4z4YZLAj4IDf_RSgGweZKiRvFkEtWtqWpUCmPZjvwlexMSsMzhUB0m746Slf8zSmjD2fxWxnoOp7W8x2Ot-sh8NX1hordvLU1chPInxo/w204-h400/20210312-10.png&quot; width=&quot;204&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMGKwb4rD95ksqnYtDVlrF43UgV_pwYd2DBO64F0WQ_qI8pScV1rjgi_qpsZm2g1D7RliW-OtbbDej2OuCWofFX23MVSZi3xaXHJB4kmVxWUZ8iTGm2coOaYNGYKuP03UKUUqzuRjqlYg/s904/20210312-11.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;904&quot; data-original-width=&quot;460&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMGKwb4rD95ksqnYtDVlrF43UgV_pwYd2DBO64F0WQ_qI8pScV1rjgi_qpsZm2g1D7RliW-OtbbDej2OuCWofFX23MVSZi3xaXHJB4kmVxWUZ8iTGm2coOaYNGYKuP03UKUUqzuRjqlYg/w204-h400/20210312-11.png&quot; width=&quot;204&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQCu-uILOrZLXOY8y0wSS4IoUL_tpUHiZypBUTtkyW1hUX2zSjEWDUoue2bPwwCs2oi6hjQDwextO96bEl-6JgjQvPdkJ5Sy5TpEvGOEXLcna4BL_9Ay0ObbTwxp1VZR3SDLgPv55Ueu0/s904/20210312-12.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;904&quot; data-original-width=&quot;460&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQCu-uILOrZLXOY8y0wSS4IoUL_tpUHiZypBUTtkyW1hUX2zSjEWDUoue2bPwwCs2oi6hjQDwextO96bEl-6JgjQvPdkJ5Sy5TpEvGOEXLcna4BL_9Ay0ObbTwxp1VZR3SDLgPv55Ueu0/w204-h400/20210312-12.png&quot; width=&quot;204&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/8699139286698183778/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2021/03/googlefacebookline-oauth-6-google-login.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/8699139286698183778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/8699139286698183778'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2021/03/googlefacebookline-oauth-6-google-login.html' title='Google、Facebook、Line OAuth 實做登入操作 (4) - 將 Google Login 加入到 Android app  '/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNQ1xZCybVjOIIH-5IFe0nQaspip7yBBwPFd9zObzrUpHgTuQKSAXuyKINn3dcKiq-0-RQRh8rvk6gaKYPywIROiofSZTIxrDSYXzvaHFI6DV5-_VkNPHijERLCVLZD0qaImOxyyENBnY/s72-w400-h169-c/20210312-1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-1039837061677550158</id><published>2021-02-28T07:36:00.007-08:00</published><updated>2021-02-28T08:53:44.805-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="GAS"/><category scheme="http://www.blogger.com/atom/ns#" term="Google Apps Script"/><category scheme="http://www.blogger.com/atom/ns#" term="Google Spreadsheet"/><title type='text'>Google Spredsheet 抓 TWN 富台期未平倉量與預估富台期契約開倉成本</title><content type='html'>富台期未平倉量資料一直是投資朋友們想收集統計，筆者透過Google Spreadsheet每日自動抓取富台期未平倉量，並計算&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;預估富台期&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;color: red;&quot;&gt;次月&lt;/b&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;契約開倉成本&lt;/b&gt;&lt;/span&gt;，藉此觀察富台期指數與外資未平倉量的動向。&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
富台期未平倉量資料顯示如下功能：
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;每日下午3:00 ~ 4:00由Google排程自動更新每日富台期未平倉量資料。&lt;/li&gt;
&lt;li&gt;每月富台期結算日後，自動計算次月的開倉成本並畫成圖。&lt;/li&gt;
&lt;li&gt;從2020/07/20後，開始記錄每月資料並自動留存。&lt;/li&gt;
&lt;li&gt;程式以Google Apps Script、JavaScript撰寫。&lt;/li&gt;
&lt;/ol&gt;
補充說明：
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;富台期期貨契約換倉預估成本是以結算日計算開倉預估成本，不是每天預估計算的成本。&lt;/li&gt;
&lt;li&gt;從2020/07/20後開始記錄未平倉量資料。&lt;/li&gt;
&lt;li style=&quot;margin: 0px 0px 0.25em; padding: 0px;&quot;&gt;資料僅就2020/07開始的上午T盤資料為主。&lt;/li&gt;
&lt;/ol&gt;
資料來源：&lt;a href=&quot;http://www.sgx.com/wps/portal/sgxweb_ch/home/marketinfo/derivatives/delayed_prices/futures&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;新加坡交易所SGX&lt;/a&gt;。&lt;br /&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCUDnFdAsSRjvNf5A5jsmibIKeH9T-YIJZ6cverUVCabFuPDvoN2hRe0HAWaqDluF0bpEMHhAAucqIaxI-lNI6epeBk3kjVxcWB-OpgjlknanP4yLctVp-UNmespUZZ1QzbDydWD9wBec/s1600/SGX.bmp&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;255&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCUDnFdAsSRjvNf5A5jsmibIKeH9T-YIJZ6cverUVCabFuPDvoN2hRe0HAWaqDluF0bpEMHhAAucqIaxI-lNI6epeBk3kjVxcWB-OpgjlknanP4yLctVp-UNmespUZZ1QzbDydWD9wBec/s400/SGX.bmp&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;免責聲明：以下內容僅供網路程式教學使用，請勿以此作為投資參考之依據，盈虧不負。&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;

&lt;iframe frameborder=&quot;0&quot; height=&quot;600px&quot; src=&quot;https://docs.google.com/spreadsheets/d/e/2PACX-1vQWnhmO2glD0Y5efI-6mr3esvmU1kUkGE7V1xPvgU6I0gA6LIzfnIIgUO8qfkD7iLi-wVmE7A3Fzhq5/pubhtml?widget=true&amp;amp;headers=false&quot; style=&quot;text-align: center;&quot; width=&quot;750px&quot;&gt;&lt;/iframe&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/1039837061677550158/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2021/02/google-spredsheet-twn.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/1039837061677550158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/1039837061677550158'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2021/02/google-spredsheet-twn.html' title='Google Spredsheet 抓 TWN 富台期未平倉量與預估富台期契約開倉成本'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCUDnFdAsSRjvNf5A5jsmibIKeH9T-YIJZ6cverUVCabFuPDvoN2hRe0HAWaqDluF0bpEMHhAAucqIaxI-lNI6epeBk3kjVxcWB-OpgjlknanP4yLctVp-UNmespUZZ1QzbDydWD9wBec/s72-c/SGX.bmp" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-337809818226219452</id><published>2021-02-22T22:21:00.005-08:00</published><updated>2021-02-22T22:21:41.862-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="GAS"/><category scheme="http://www.blogger.com/atom/ns#" term="Google Apps Script"/><title type='text'>Google Apps Script 入門到進階(22) - 使用 Cheerio 協助爬蟲解析網頁 </title><content type='html'>1年前 Google 雲端爬蟲程式突然無法運作，加上寫書緣故就去處理，最近有空重新整理，發現原來 Google App Script 解析網頁的函數 Xml.parse 已無法再使用了，換成 XmlService.parse 又發現非常難用，需要刪除很多網頁元素，原因是 XmlService.parse 對於 XML 的規則要求格，但HTML結構鬆散，所以無法直接適用，後來捨棄 XmlService.parse。&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;div&gt;在網路尋找中無意間發現有外部套件 Cheerio 可以用來解析HTML，經過測試確實可以在GAS環境上使用也非常方便，之後也將全面採行，以下就稍微說明相關作法。&lt;br /&gt;GAS版的 Cheerio 是外國人將 Cheerio 封裝而成的函式庫，需要透過Script ID加入GAS函式庫中。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi228KS7CZu6nt5V4srT058TyzReuhjQc1EQBtUpXCqt9v9C-spmA0eoB97zAvAGBWJ6TK_uJE8rJnTtNEJmuIQUsXnK3a79lELhmtyg9n9QjGS5PkJby9_O-78BwzTPp2HvOM5wpZmek6Q/s1462/20210223-1.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1020&quot; data-original-width=&quot;1462&quot; height=&quot;279&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi228KS7CZu6nt5V4srT058TyzReuhjQc1EQBtUpXCqt9v9C-spmA0eoB97zAvAGBWJ6TK_uJE8rJnTtNEJmuIQUsXnK3a79lELhmtyg9n9QjGS5PkJby9_O-78BwzTPp2HvOM5wpZmek6Q/w400-h279/20210223-1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Script ID：1ReeQ6WO8kKNxoaA_O0XEQ589cIrRvEBA9qcWpNqdOP17i47u6N9M5Xh0&lt;br /&gt;
&lt;br /&gt;以下就手把手帶各位操作。&lt;br /&gt;
步驟1：新增 Google 試算表。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjooZZGCL8lKGpILLW6t7Cm0kCC1ekElmM2u1-2P32a0y7I2Mdk_fKO5VlP7PEkJa18yE2wnz4hCPhaWsDj8Zof6N6naq1RgoFTF7EKBlWV5epRMXQ0IhbL33S2f736eBQTKMvGyXgcSa4/s404/20210223-2.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;404&quot; data-original-width=&quot;362&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjooZZGCL8lKGpILLW6t7Cm0kCC1ekElmM2u1-2P32a0y7I2Mdk_fKO5VlP7PEkJa18yE2wnz4hCPhaWsDj8Zof6N6naq1RgoFTF7EKBlWV5epRMXQ0IhbL33S2f736eBQTKMvGyXgcSa4/w359-h400/20210223-2.png&quot; width=&quot;359&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;步驟2：點擊「指令碼編輯器」，開啟「App Script」編輯環境。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgONAUAwKlBDoPlKj7F6nbX5BmB5EgoTAtkzRtrJfu6MY4_zc-pusILT7TDimyBJSYKxHzVmZhPglZiI8_QhNAA93I1YFvbTwpWMqH-JZxkG4-eUs6RAbQJVnrcmjyoKNlp3rLjRQtReUo/s864/20210223-4.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;337&quot; data-original-width=&quot;864&quot; height=&quot;250&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgONAUAwKlBDoPlKj7F6nbX5BmB5EgoTAtkzRtrJfu6MY4_zc-pusILT7TDimyBJSYKxHzVmZhPglZiI8_QhNAA93I1YFvbTwpWMqH-JZxkG4-eUs6RAbQJVnrcmjyoKNlp3rLjRQtReUo/w640-h250/20210223-4.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;步驟3：點擊「資料庫」，輸入Script ID，新增「函式庫」。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin9s1tQNGmZqHV9iXIDnLbQ7heuhw_iCTz9r-4IS-tRgZsvwmrPnKdgXccZ__w6RnPCUzVUxWT_TCIf_aULUo5CeJTKbI4opOTjPvm2CJh5nT5GpNdTZo62T3yFFT0PFb035wV8vHVY8c/s1128/20210223-5.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;944&quot; data-original-width=&quot;1128&quot; height=&quot;335&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin9s1tQNGmZqHV9iXIDnLbQ7heuhw_iCTz9r-4IS-tRgZsvwmrPnKdgXccZ__w6RnPCUzVUxWT_TCIf_aULUo5CeJTKbI4opOTjPvm2CJh5nT5GpNdTZo62T3yFFT0PFb035wV8vHVY8c/w400-h335/20210223-5.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;
步驟4：輸入程式碼，抓取「Yahoo主力進出表」。&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt;function getStockMajor()
{
  var st = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = st.getSheets()[0].clear(); 

  //連線Yahoo主力進出表
  var URL = &quot;https://tw.stock.yahoo.com/d/s/major_2330.html&quot;;
  var source = UrlFetchApp.fetch(URL);
  var html = source.getContentText(&#39;BIG5&#39;);

  //DOM解析HTML
  const $ = Cheerio.load(html,{ decodeEntities: false });

  var table, tr, td;
  //表格資訊
  table = $(&#39;table table&#39;).eq(0);  
  tr = table.find(&#39;tr&#39;);
  td = tr.eq(0).find(&#39;td&#39;);    
  sheet.getRange(1, 1).setValue(td.eq(0).text().trim());
  sheet.getRange(1, 3).setValue(td.eq(1).text().trim());

  //表格內容
  table = $(&#39;table table&#39;).eq(1); 
  tr = table.find(&#39;tr&#39;);
  for(var i = 0 ; i &amp;lt; tr.length ; ++i)
  {
    td = tr.eq(i).find(&#39;td&#39;);
    for(var j = 0 ; j &amp;lt; td.length ; ++j)
    {
      sheet.getRange(i + 2, j + 1).setValue(td.eq(j).text().trim());
    }
  } 
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQDtpBQnfxdxVryfSBuaaCDi5yEafAfTyeJn-5-Pdc-IHs7NL3TxgaXJxzawGjj8DhqxDHoo8SXdlgiFLt-tdRwTLdM2pQjaX3TpPikKj__Frl-LCiO_xmCSYx9pi473kHUVEfTnJqAaA/s1040/20210223-7.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1040&quot; data-original-width=&quot;943&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQDtpBQnfxdxVryfSBuaaCDi5yEafAfTyeJn-5-Pdc-IHs7NL3TxgaXJxzawGjj8DhqxDHoo8SXdlgiFLt-tdRwTLdM2pQjaX3TpPikKj__Frl-LCiO_xmCSYx9pi473kHUVEfTnJqAaA/w363-h400/20210223-7.png&quot; width=&quot;363&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟5：點擊「存檔」與「執行」按鈕。
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxluS0A0wefunE4iPwSCZnyiC7J-2LSg0asriUIlTsBHUCCrpzLsq6OKkiiVE4q-epAmMOA0NxWSRnYHNFjiRfFnoTUGJIF_9gQMPfPPosCzv-bJmW9yvPEOJpjJu0i-A5UNGseEryje0/s769/20210223-6.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;239&quot; data-original-width=&quot;769&quot; height=&quot;198&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxluS0A0wefunE4iPwSCZnyiC7J-2LSg0asriUIlTsBHUCCrpzLsq6OKkiiVE4q-epAmMOA0NxWSRnYHNFjiRfFnoTUGJIF_9gQMPfPPosCzv-bJmW9yvPEOJpjJu0i-A5UNGseEryje0/w640-h198/20210223-6.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;接著就是一連串的權限設定。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxNQWggip1yvANHlUdTGGyW_1PXiP71aRfTC6GOwQjiIs3WGcNcYjiJp-y4a6rfyvUmCWXojjrXPsOPZQyyWxjd8Ph7JB0BqpO7NJDyOdIBvKCLwd4tqTNeO1-up43w0YYYOmcxFFD-IU/s1128/20210223-8.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;944&quot; data-original-width=&quot;1128&quot; height=&quot;335&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxNQWggip1yvANHlUdTGGyW_1PXiP71aRfTC6GOwQjiIs3WGcNcYjiJp-y4a6rfyvUmCWXojjrXPsOPZQyyWxjd8Ph7JB0BqpO7NJDyOdIBvKCLwd4tqTNeO1-up43w0YYYOmcxFFD-IU/w400-h335/20210223-8.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6zrw7eplF_gngPi_ievXZAduJkZmUC8Y3O7ouzew4vmvBryVEB80i7TvMhBNJgR6geL1s-KbC7sqtXgNeJkEsWUR0Ta2hDZH9vTrx7C2G0XT4YVoevzf9hm3FyGHG_3xadUjkX5_p6AA/s1128/20210223-9.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;944&quot; data-original-width=&quot;1128&quot; height=&quot;335&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6zrw7eplF_gngPi_ievXZAduJkZmUC8Y3O7ouzew4vmvBryVEB80i7TvMhBNJgR6geL1s-KbC7sqtXgNeJkEsWUR0Ta2hDZH9vTrx7C2G0XT4YVoevzf9hm3FyGHG_3xadUjkX5_p6AA/w400-h335/20210223-9.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWvyCw4XgBF613dUPGmiPMMf2Q6LHU_R6av9Wa3FLwEGlkLFygsJpfp40YywE1hwWx1acZiSNAtxddhhyphenhyphen2vd1IhW6u-_2Uq2-Hu1l1_G4dDPsJngCXT1LIKBzlTi8nVQ5DmZ3UcajbCYs/s784/20210223-10.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;784&quot; data-original-width=&quot;658&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWvyCw4XgBF613dUPGmiPMMf2Q6LHU_R6av9Wa3FLwEGlkLFygsJpfp40YywE1hwWx1acZiSNAtxddhhyphenhyphen2vd1IhW6u-_2Uq2-Hu1l1_G4dDPsJngCXT1LIKBzlTi8nVQ5DmZ3UcajbCYs/w336-h400/20210223-10.png&quot; width=&quot;336&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEWQSo5Kb2rF3v3NhjQ1abXHAsy3J0tP2lwotrPXPTsEHGhL7htDRN198lkft8Agkj6bLM7h9GWFmFqAENJnSId3cKTldddAbUXa_OXrxifkDIRsCR8fbQTPik3wBGXx8MGiYuDpx2A_8/s784/20210223-11.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;784&quot; data-original-width=&quot;658&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEWQSo5Kb2rF3v3NhjQ1abXHAsy3J0tP2lwotrPXPTsEHGhL7htDRN198lkft8Agkj6bLM7h9GWFmFqAENJnSId3cKTldddAbUXa_OXrxifkDIRsCR8fbQTPik3wBGXx8MGiYuDpx2A_8/w336-h400/20210223-11.png&quot; width=&quot;336&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwBU8HRDRP4_yNdsxAsjRu6j6xuXQ1XIVv7mS14gmUdn6CTRS07JOXZPlevwFwlD155SEFATcW3t2OtZGAQcFD932tC5qv0V-06HmGokb6-5KeWYS52vVL1hBO7ugUOt07bOAOGoL9wV0/s784/20210223-12.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;784&quot; data-original-width=&quot;658&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwBU8HRDRP4_yNdsxAsjRu6j6xuXQ1XIVv7mS14gmUdn6CTRS07JOXZPlevwFwlD155SEFATcW3t2OtZGAQcFD932tC5qv0V-06HmGokb6-5KeWYS52vVL1hBO7ugUOt07bOAOGoL9wV0/w336-h400/20210223-12.png&quot; width=&quot;336&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDRepxO2oXWzfKTXQlDImzpUcZYvWTDO6N5fPuA3CnpO2o6OFXnaBj44sqlhPHm6RkQi1Or0mmBxjOgblZiCW10jKaLDQ0hp30M15x2G-soa8jvkmVlo9Pd3sAFUk1uzXJti4rPY_1Cs4/s784/20210223-13.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;784&quot; data-original-width=&quot;658&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDRepxO2oXWzfKTXQlDImzpUcZYvWTDO6N5fPuA3CnpO2o6OFXnaBj44sqlhPHm6RkQi1Or0mmBxjOgblZiCW10jKaLDQ0hp30M15x2G-soa8jvkmVlo9Pd3sAFUk1uzXJti4rPY_1Cs4/w336-h400/20210223-13.png&quot; width=&quot;336&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgE_H0MTlX_fCsP-GZ60kn66aEvkGiG73ZWFFXbPrPrtw2CUGtTnWarNRkpCsMj0N4gCxybDi_dlux1V7cQEzJyEGsnw4DAiY6RTFvj4Q_2pCCz1f53XqQjbB8e2O3EXfdf8t7NEG4zjnQ/s1128/20210223-14.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;944&quot; data-original-width=&quot;1128&quot; height=&quot;335&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgE_H0MTlX_fCsP-GZ60kn66aEvkGiG73ZWFFXbPrPrtw2CUGtTnWarNRkpCsMj0N4gCxybDi_dlux1V7cQEzJyEGsnw4DAiY6RTFvj4Q_2pCCz1f53XqQjbB8e2O3EXfdf8t7NEG4zjnQ/w400-h335/20210223-14.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
最後執行的結果。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVS3QRIk5t-VgPsJ_xHY4sD6UOP_77uQ3PC84sjSe7HJLVXRmpKaHeAgKAHJdoiIjrGc7mJfosFyXIg60sUOGL4kTRzkNg94lE2p0is65tl9Dyyl9PpkO2oB6X6mNawR2yzzxRu9Ha1DI/s961/20210223-15.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;573&quot; data-original-width=&quot;961&quot; height=&quot;239&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVS3QRIk5t-VgPsJ_xHY4sD6UOP_77uQ3PC84sjSe7HJLVXRmpKaHeAgKAHJdoiIjrGc7mJfosFyXIg60sUOGL4kTRzkNg94lE2p0is65tl9Dyyl9PpkO2oB6X6mNawR2yzzxRu9Ha1DI/w400-h239/20210223-15.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;參考資料&lt;br /&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://www.tpisoftware.com/tpu/articleDetails/2344&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;GAS + Cheerio 分析網頁資訊寫入Google 試算表&amp;nbsp;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/337809818226219452/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2021/02/google-apps-script-22-cheerio.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/337809818226219452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/337809818226219452'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2021/02/google-apps-script-22-cheerio.html' title='Google Apps Script 入門到進階(22) - 使用 Cheerio 協助爬蟲解析網頁 '/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi228KS7CZu6nt5V4srT058TyzReuhjQc1EQBtUpXCqt9v9C-spmA0eoB97zAvAGBWJ6TK_uJE8rJnTtNEJmuIQUsXnK3a79lELhmtyg9n9QjGS5PkJby9_O-78BwzTPp2HvOM5wpZmek6Q/s72-w400-h279-c/20210223-1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-1529189446668692346</id><published>2021-02-21T07:42:00.005-08:00</published><updated>2021-02-21T23:34:51.437-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Line"/><category scheme="http://www.blogger.com/atom/ns#" term="Line Login"/><title type='text'>Google、Facebook、Line OAuth 實做登入操作 (2) - 再談 Line Login </title><content type='html'>前一篇 &lt;a href=&quot;http://white5168.blogspot.com/2021/02/openid-googlefacebookline-line-login.html#.YDIVSRoza73&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Google、Facebook、Line OAuth 實做登入操作 (1) - Line Login&lt;/a&gt; 介紹如何建構 「LINE Login」 的操作步作，過程中有部分內容因為篇幅關係沒能一次到位介紹，接著就對 LINE Login 作細部測試進行說明。&lt;br /&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;以下分別針對「USBWebserver 與 Ngrok 設定操作」、「使用Postman 測試取得 LINE Login 帳戶資訊」兩個主題做說明。&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;b&gt;USBWebserver&amp;nbsp;與 Ngrok 設定操作&lt;/b&gt;&lt;/span&gt;&lt;div&gt;USBWebserver 伺服器在本機端建立「linelogin.html」網頁服務，透過網頁連結埠 443，對外提供 HTTPS 連結，「Ngrok.com」將實際網址「https://00a14ff8c66e.ngrok.io/」導向 USBWebserver 連結埠 443，這樣對外的服務網址「https://00a14ff8c66e.ngrok.io/linelogin.html」才能正確連接至使用者本機的網頁。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdzFvfcpcOw9aCtRmRRnjQLNhjjtd7Bn8lesNN_wKQ-Mld3GO6hhwSgtJXPZnoiBlfqVbEhKrrwbmb3CR2ToUBfqFcMo5_zYvvm-uJJqxnVOrRYEQ5-mu0OhBegPmBO_A9BUYCzoT21fc/s730/20210221-1.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;300&quot; data-original-width=&quot;730&quot; height=&quot;264&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdzFvfcpcOw9aCtRmRRnjQLNhjjtd7Bn8lesNN_wKQ-Mld3GO6hhwSgtJXPZnoiBlfqVbEhKrrwbmb3CR2ToUBfqFcMo5_zYvvm-uJJqxnVOrRYEQ5-mu0OhBegPmBO_A9BUYCzoT21fc/w640-h264/20210221-1.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;b&gt;使用 Postman 取得 LINE Login 帳戶資訊&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;「LINE Login」串接取得帳戶資訊流程與說明如下。&lt;br /&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
  &lt;li&gt;取得帳戶授權碼。&lt;/li&gt;
  說明：需要 HTTPS 網址，才能透過 HTTPS 網址取回「帳戶授權碼」，這部分無法使用「Postman」取得。&lt;br /&gt;&lt;br /&gt;
  &lt;li&gt;透過「帳戶授權碼」取得帳戶 Token。&lt;/li&gt;
  說明：需要 HTTPS 網址搭配，不需要透過 HTTPS 網址取回Token，因此可使用「Postman」取得。&lt;br /&gt;&lt;br /&gt;
  &lt;li&gt;透過 Token 取得帳戶資訊如姓名、email。&lt;/li&gt;
  說明：使用 Token 取得帳戶資訊可使用「Postman」取得。
  &lt;br /&gt;
&lt;/ol&gt;&lt;b&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;取得帳戶授權碼&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
透過以下JavaScrippt程式碼抓取伺服器回傳「帳戶授權碼 code」，&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;請注意code的有效性指有10分鐘，10分鐘後就要重新在抓新的code&lt;/b&gt;&lt;/span&gt;。&lt;br /&gt;
&lt;pre class=&quot;brush:html&quot;&gt; &amp;lt;!DOCTYPE html&amp;gt;
    &amp;lt;html lang=&quot;en&quot;&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
        &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&amp;gt;
        &amp;lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&amp;gt;
        &amp;lt;title&amp;gt;LINE Login Demo&amp;lt;/title&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;button id=&quot;lineLoginBtn&quot;&amp;gt;LINE login&amp;lt;/button&amp;gt;
        &amp;lt;script src=&#39;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js&#39;&amp;gt;&amp;lt;/script&amp;gt;
        &amp;lt;script&amp;gt;
            var channel_id = &quot;channel id&quot;;
            var channel_secret = &quot;channel secret&quot;;
            var uri = &quot;Https網址&quot;;
            
            //var code = &quot;&quot;; 
            $(&#39;#lineLoginBtn&#39;).on(&#39;click&#39;, function(e) {
                let client_id = channel_id;
                let redirect_uri = uri;
                let link = &#39;https://access.line.me/oauth2/v2.1/authorize?&#39;;
                link += &#39;response_type=code&#39;;
                link += &#39;&amp;amp;client_id=&#39; + client_id;
                link += &#39;&amp;amp;redirect_uri=&#39; + redirect_uri;
                link += &#39;&amp;amp;state=login&#39;;
                link += &#39;&amp;amp;scope=openid%20profile%20email&#39;;
                window.location.href = link;
            });

            var url = new URL(window.location.href);
            var code = url.searchParams.get(&quot;code&quot;); 
            if(code != null) document.write(&#39;&amp;lt;br / &amp;gt; code : &#39; + code + &#39;&amp;lt;br / &amp;gt;&#39;); 
        &amp;lt;/script&amp;gt;
    &amp;lt;/body&amp;gt;
    &amp;lt;/html&amp;gt;
&lt;/pre&gt;
 執行後「帳戶授權碼 code」為 2nqdeDexLvgn5LTdHGPC。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEji71JvK03Q3KtSTQ1eJhAeiRxkJWXDZ2KAG51z61OpXukGl8kDcFuINtbmPyvS4c-wbTL-__l8ZIs_n76uxFLfzqHUBu9eDnBwV7VDYgMbzIMxOI3D8LLXAqCZR9tngLdPFAYjnpDOZP8/s1053/20210221-2.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;204&quot; data-original-width=&quot;1053&quot; height=&quot;78&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEji71JvK03Q3KtSTQ1eJhAeiRxkJWXDZ2KAG51z61OpXukGl8kDcFuINtbmPyvS4c-wbTL-__l8ZIs_n76uxFLfzqHUBu9eDnBwV7VDYgMbzIMxOI3D8LLXAqCZR9tngLdPFAYjnpDOZP8/w400-h78/20210221-2.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;

&lt;b&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;透過「帳戶授權碼」取得帳戶 Token&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
開啟 Postman 輸入以下資訊。&lt;br /&gt;
方法&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;POST&lt;/li&gt;
&lt;/ul&gt;
Header&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Content-Type:application/x-www-form-urlencoded&lt;/li&gt;
&lt;/ul&gt;
參數&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;grant_type:authorization_code&lt;/li&gt;
&lt;li&gt;code:2nqdeDexLvgn5LTdHGPC&lt;/li&gt;
&lt;li&gt;redirect_uri: Https網址&lt;/li&gt;
&lt;li&gt;client_id:你的channel id&lt;/li&gt;
&lt;li&gt;client_secret:你的channel secret&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
「Postman」測試的結果如畫面，「id_token」的內容就是帳戶的Token，也是第三步所需的參數。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUdxvFAzEB6jNam6n13xooFWYySzEFv6dHa2_JgsFzoXddzoc-u759w7_gjVpfFTkQZzUqGGwaakCUjQtT4aLEhis8imHP114PZFT4FqLuoRQZK0ZUa4A1wJ5s5XHaVAsXn5AsxQ0SUj0/s1264/20210221-3.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;964&quot; data-original-width=&quot;1264&quot; height=&quot;305&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUdxvFAzEB6jNam6n13xooFWYySzEFv6dHa2_JgsFzoXddzoc-u759w7_gjVpfFTkQZzUqGGwaakCUjQtT4aLEhis8imHP114PZFT4FqLuoRQZK0ZUa4A1wJ5s5XHaVAsXn5AsxQ0SUj0/w400-h305/20210221-3.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;注意事項：&lt;br /&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;每一組「帳戶授權碼 code」只能用「Postman」取得一次「帳戶Token」，若使用「Postman」發送第2次後就會產生錯誤。&lt;/li&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyYQgIwCsCDnBVxudek4RheK2EtCMeRbxNwm-ouTZWdl7Bzm7hV0c6RM6QubXO2IY7-aApiN2TzYi_YSkrsXNIJdgGcKtmpLdstE2rsQU6AteUadzI_zDA0qpS52h9h_7ID_SouMJ6hk0/s1083/20210221-4.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;902&quot; data-original-width=&quot;1083&quot; height=&quot;334&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyYQgIwCsCDnBVxudek4RheK2EtCMeRbxNwm-ouTZWdl7Bzm7hV0c6RM6QubXO2IY7-aApiN2TzYi_YSkrsXNIJdgGcKtmpLdstE2rsQU6AteUadzI_zDA0qpS52h9h_7ID_SouMJ6hk0/w400-h334/20210221-4.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;  
&lt;li&gt;
「id_token」的內容本身就是一個 JWT 的加密結果，可透過 &lt;a href=&quot;http://JWT.io&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;JWT.io&lt;/a&gt; 進行解密，解密的內容就是第三步的結果，。&lt;/li&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNckpWpd1PqC8Wiqm3nu90yaSnYYwjZQL0LPAJx9M_M0ZVuju_4UP9N98ojwIXpCt01iotn0XVsgh6WI0kTFylxdvBmtI3Wc2u4lg5L9coc-saiKwdjMked3zTNHfkp2baTJ7GbdWh4M4/s1346/20210221-5.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1014&quot; data-original-width=&quot;1346&quot; height=&quot;301&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNckpWpd1PqC8Wiqm3nu90yaSnYYwjZQL0LPAJx9M_M0ZVuju_4UP9N98ojwIXpCt01iotn0XVsgh6WI0kTFylxdvBmtI3Wc2u4lg5L9coc-saiKwdjMked3zTNHfkp2baTJ7GbdWh4M4/w400-h301/20210221-5.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/ol&gt;
&lt;b&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;透過 Token 取得帳戶資訊如姓名、email&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Postman 輸入以下資訊。&lt;br /&gt;
方法&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;POST&lt;/li&gt;
&lt;/ul&gt;
Header&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Content-Type:application/x-www-form-urlencoded&lt;/li&gt;
&lt;/ul&gt;
參數&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;client_id:你的channel id&lt;/li&gt;
&lt;li&gt;id_token: 你的id_token&lt;/li&gt;
&lt;/ul&gt;
「Postman」測試的結果如畫面。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPJzKdAnR3kUP8kGGa9YTQ3th0zrCpqMf32vUboMCFkGroBbaLad0TXrGAXv-8QGmtwzFZRzBskNo2P71B6qGD1AITxST9F_PHhax8JbmRTAW6rhd0fY8re-uO1_P8cA17kucWhmgikJk/s1083/20210221-6.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;965&quot; data-original-width=&quot;1083&quot; height=&quot;356&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPJzKdAnR3kUP8kGGa9YTQ3th0zrCpqMf32vUboMCFkGroBbaLad0TXrGAXv-8QGmtwzFZRzBskNo2P71B6qGD1AITxST9F_PHhax8JbmRTAW6rhd0fY8re-uO1_P8cA17kucWhmgikJk/w400-h356/20210221-6.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;關於Email的取得，即使在程式碼中有設定，若使用者在授權階段選擇不同意授權存取email，也會導致無法取得email。&lt;br /&gt;&lt;br /&gt;
測試階段可以透過以下設定抓取email，到 Line Developers 後台的「Basic settings」頁籤畫面的下方「OpenID Connect」，將畫面中的內容設定完成才能取得email。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgttSWdzoKUj1yc_T4MstjB0appD_771LcBjf896kbjWUsQxVefRnNC1lCTgNySWMyOMd8hdmZSRV4B_OuVOeeb08eO4OW6KwFB39Y7p2WqIk3-8AZk0W0mBdteSzxUY2R2d3-_xzoAK2I/s1379/20210221-7.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1010&quot; data-original-width=&quot;1379&quot; height=&quot;293&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgttSWdzoKUj1yc_T4MstjB0appD_771LcBjf896kbjWUsQxVefRnNC1lCTgNySWMyOMd8hdmZSRV4B_OuVOeeb08eO4OW6KwFB39Y7p2WqIk3-8AZk0W0mBdteSzxUY2R2d3-_xzoAK2I/w400-h293/20210221-7.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
  &lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNlx7_TFoBjxQ7cySqCycf0OciniDMjzV-0bQbsuTc2_KjYNjKdbaCuR32ll7TvAYHBjTPrfA6Qz0OHtXRKqJ0HdOSdrV363d0x3VukFp9uEmhQ9tbMDOf_vlue3L4YcrIPwBB6WqnMYU/s687/20210221-8.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;371&quot; data-original-width=&quot;687&quot; height=&quot;216&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNlx7_TFoBjxQ7cySqCycf0OciniDMjzV-0bQbsuTc2_KjYNjKdbaCuR32ll7TvAYHBjTPrfA6Qz0OHtXRKqJ0HdOSdrV363d0x3VukFp9uEmhQ9tbMDOf_vlue3L4YcrIPwBB6WqnMYU/w400-h216/20210221-8.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;
授權Email取得許可。&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
「OpenID Connect」設定成功後，在一次重新授權，這實可建到授權畫面多出了email選項。&lt;br /&gt;
 &lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik4RWGbTWnB5Fsnb21hn97STIaTP6vUc3Zw-5F-mBufjX9v0m2d38gslH3FabExMtJvLGv2W1X5US4OiCwdWAw5jP1OOak-aIe4ztucE96_hAj_HbU05OHIo_o9jYEN9Ak0G6DOyG_Brg/s967/20210221-11.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;967&quot; data-original-width=&quot;803&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik4RWGbTWnB5Fsnb21hn97STIaTP6vUc3Zw-5F-mBufjX9v0m2d38gslH3FabExMtJvLGv2W1X5US4OiCwdWAw5jP1OOak-aIe4ztucE96_hAj_HbU05OHIo_o9jYEN9Ak0G6DOyG_Brg/w333-h400/20210221-11.png&quot; width=&quot;333&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;發送「Postman」也可取得email。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQye2HWM43skBOQqGSOl6MqJYAd1-nFY1k5mcbgeiWaHH3nDTZrGnWZZI9m1A9ys68hIocdzRNxmVia3emb1TAZN-S8yrFRq_6cn6lz_skvxdpidRwiZ1_F5fmiawij8_SihlhM0RwLs4/s1083/20210221-12.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;965&quot; data-original-width=&quot;1083&quot; height=&quot;356&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQye2HWM43skBOQqGSOl6MqJYAd1-nFY1k5mcbgeiWaHH3nDTZrGnWZZI9m1A9ys68hIocdzRNxmVia3emb1TAZN-S8yrFRq_6cn6lz_skvxdpidRwiZ1_F5fmiawij8_SihlhM0RwLs4/w400-h356/20210221-12.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;發佈給顧客&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;最後在所有測試步驟就成功後，請務必確認「已發佈」 開放給顧客 LINE 登入。&lt;div&gt;頁面右上角可以找到灰色「Developing」狀態按鈕，請點擊選「Publish」，接著狀態會更新為「Published」即正式發布開放。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuKjK69809TbJT7QObBPULh1xqyN2uqtlYBBnu9IPWHyCfNrHx4Mf688RoyKOQ7nuSkrhB2Ov-VX0Saa9cMDtwiNVQLQpUPjZsjZTyEn8ME8ZUG7qkxMOOZs2xv-hLl_5NHM2kv8hPjsI/s1038/20210221-9.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;784&quot; data-original-width=&quot;1038&quot; height=&quot;303&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuKjK69809TbJT7QObBPULh1xqyN2uqtlYBBnu9IPWHyCfNrHx4Mf688RoyKOQ7nuSkrhB2Ov-VX0Saa9cMDtwiNVQLQpUPjZsjZTyEn8ME8ZUG7qkxMOOZs2xv-hLl_5NHM2kv8hPjsI/w400-h303/20210221-9.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;
完成發佈。&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzIKBvgrouHfphJwd3KMNixseL_damJQ3TVYt1MVNRiob0Z_q2HrQFo_vHjsPo6E5XY4fMlww2wnQZsCaXwxugWqmEzg915e643BlVYFlhcr4kIblN7S9oDGOIaxlHc1XpSOPh3yeYSjA/s1038/20210221-10.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;784&quot; data-original-width=&quot;1038&quot; height=&quot;303&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzIKBvgrouHfphJwd3KMNixseL_damJQ3TVYt1MVNRiob0Z_q2HrQFo_vHjsPo6E5XY4fMlww2wnQZsCaXwxugWqmEzg915e643BlVYFlhcr4kIblN7S9oDGOIaxlHc1XpSOPh3yeYSjA/w400-h303/20210221-10.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/1529189446668692346/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2021/02/openid-googlefacebookline-2-line-login.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/1529189446668692346'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/1529189446668692346'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2021/02/openid-googlefacebookline-2-line-login.html' title='Google、Facebook、Line OAuth 實做登入操作 (2) - 再談 Line Login '/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdzFvfcpcOw9aCtRmRRnjQLNhjjtd7Bn8lesNN_wKQ-Mld3GO6hhwSgtJXPZnoiBlfqVbEhKrrwbmb3CR2ToUBfqFcMo5_zYvvm-uJJqxnVOrRYEQ5-mu0OhBegPmBO_A9BUYCzoT21fc/s72-w640-h264-c/20210221-1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-4827446623317947109</id><published>2021-02-20T09:57:00.012-08:00</published><updated>2021-02-21T22:56:29.447-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Line"/><category scheme="http://www.blogger.com/atom/ns#" term="Line Login"/><title type='text'>Google、Facebook、Line OAuth 實做登入操作 (1) - Line Login</title><content type='html'>最近研究透過Google、Facebook、Line提供的OpenID登入，順到記錄一下所有操作內容，OpenID是一種分散式認證系統，使用者可透過一個帳號、密碼就能登入多個網站，可省去管理多組帳號、密碼。&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;Google、Facebook兩者的驗證流程相似，但與Line不同，就先以Line Login的操作方式來說明，透過JavaScript來操作，各位朋友若有其他語言有興趣可自行轉換。&lt;br /&gt;
&lt;br /&gt;步驟1：登入&amp;nbsp;&lt;a href=&quot;https://developers.line.biz/zh-hant/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Line&amp;nbsp;Developers&lt;/a&gt;&amp;nbsp;後台。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigEllFPKl6QUvd2Vft3VNHGxVeNterAQmR8C35Mj01CeOKB7GXvwvoXYrh5cTgmE-mkU9dE5zla0n17Xx78-PsrVuBIawRwlaFIiPqGtMX2mB2WUGeCTfwOjva8ZYBBp6xbVIVvJa0v70/s1331/20210220-1.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;916&quot; data-original-width=&quot;1331&quot; height=&quot;275&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigEllFPKl6QUvd2Vft3VNHGxVeNterAQmR8C35Mj01CeOKB7GXvwvoXYrh5cTgmE-mkU9dE5zla0n17Xx78-PsrVuBIawRwlaFIiPqGtMX2mB2WUGeCTfwOjva8ZYBBp6xbVIVvJa0v70/w400-h275/20210220-1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;步驟2：點擊「Products」。&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiShCSzEfIIQUE4v6OQPGM_6xPKdVUbe4RjvfKMLN33cOjkzjBcFHKoNWzXoXBLzgFC4vULOQG-Kc1SW9oFs2zX7Vfvich_IV8r4ucDgqxxMSD10sLc_28lASMbwn6PYp_vdhJeYxfGYj0/s844/20210220-2.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;369&quot; data-original-width=&quot;844&quot; height=&quot;175&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiShCSzEfIIQUE4v6OQPGM_6xPKdVUbe4RjvfKMLN33cOjkzjBcFHKoNWzXoXBLzgFC4vULOQG-Kc1SW9oFs2zX7Vfvich_IV8r4ucDgqxxMSD10sLc_28lASMbwn6PYp_vdhJeYxfGYj0/w400-h175/20210220-2.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
步驟3：點擊「&amp;nbsp;LINE Login」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRQInmGuFIrx1j7iVnHz5ezoDGB-XbZVkhA0QLndcK_YLXGP3-abX2DYDVoK9fqWqci-0y0Nz0tn_R85I0bX0hCcRcjYMaANORFGo5FkU0grwdGiIQBTfc750xrC_zW1zO3hTlAt2mAbU/s1335/20210220-3.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;957&quot; data-original-width=&quot;1335&quot; height=&quot;286&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRQInmGuFIrx1j7iVnHz5ezoDGB-XbZVkhA0QLndcK_YLXGP3-abX2DYDVoK9fqWqci-0y0Nz0tn_R85I0bX0hCcRcjYMaANORFGo5FkU0grwdGiIQBTfc750xrC_zW1zO3hTlAt2mAbU/w400-h286/20210220-3.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟4：點擊「開始體驗」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVJMPeUxlU2X6vGOY-Mi7F6WCcTUQgkqtWihvo-jUpcaNgDquh6vrS36xyOaM1VzEJiRVdW4fwrGmG8Dhq_i2ED68hDWs89CquAr47ZclMsn4FztyaXXkvt7sQN6fCLeRjcBuQgxOIUgA/s830/20210220-4.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;492&quot; data-original-width=&quot;830&quot; height=&quot;238&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVJMPeUxlU2X6vGOY-Mi7F6WCcTUQgkqtWihvo-jUpcaNgDquh6vrS36xyOaM1VzEJiRVdW4fwrGmG8Dhq_i2ED68hDWs89CquAr47ZclMsn4FztyaXXkvt7sQN6fCLeRjcBuQgxOIUgA/w400-h238/20210220-4.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟5：點選「Create a new provider」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH2kKKDwIV_SD_A1nlW_2E42P_Kc8uu-4q7d3-CyM9VRWhN0J7KcMba81OjODnVAbjmP-ShMn0as3B5FZnnaslQbYceazIQ-6sOQPzLIh9KLi4WDWcAzlxycT3iv1ewzXyGVkQKP7QDc4/s619/20210220-5.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;384&quot; data-original-width=&quot;619&quot; height=&quot;249&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH2kKKDwIV_SD_A1nlW_2E42P_Kc8uu-4q7d3-CyM9VRWhN0J7KcMba81OjODnVAbjmP-ShMn0as3B5FZnnaslQbYceazIQ-6sOQPzLIh9KLi4WDWcAzlxycT3iv1ewzXyGVkQKP7QDc4/w400-h249/20210220-5.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟6：輸入「Provider」名稱與選擇「Region」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMyVNCG4sYxhCRQfYkWTYMhtiKAGH84yIrKjqoUCwHjLe49-o7baD8VEFmU0ACcack-NB1tTp3xlQM309r3Fpj_Gw2RJWTIQ_HuAb9zRoxDb3f7uxwSsVDOlIBYeiYz4i8f562pIIrMQA/s617/20210220-6.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;384&quot; data-original-width=&quot;617&quot; height=&quot;249&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMyVNCG4sYxhCRQfYkWTYMhtiKAGH84yIrKjqoUCwHjLe49-o7baD8VEFmU0ACcack-NB1tTp3xlQM309r3Fpj_Gw2RJWTIQ_HuAb9zRoxDb3f7uxwSsVDOlIBYeiYz4i8f562pIIrMQA/w400-h249/20210220-6.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟7：填寫「Channel name」、「Channel description」內容與選擇「App types」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiX9iGdOmH1q7scNtLKLMUYXkV0T9KACHa3WvHBbDCXHC8D-mL3wcV7tJKzDgnfImfrm_JK9VKb1cQzVSVf3CrIjk6iZE5ZnQWpLU6c6r4Ua-X6t_kYczaY7M7-F5rxrtd12FRSSyaKqX0/s618/20210220-7.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;545&quot; data-original-width=&quot;618&quot; height=&quot;353&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiX9iGdOmH1q7scNtLKLMUYXkV0T9KACHa3WvHBbDCXHC8D-mL3wcV7tJKzDgnfImfrm_JK9VKb1cQzVSVf3CrIjk6iZE5ZnQWpLU6c6r4Ua-X6t_kYczaY7M7-F5rxrtd12FRSSyaKqX0/w400-h353/20210220-7.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟8：勾選「I have read and agress to the LINE Developers Agreement」與點擊「Create」&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqZpmhReQvLwTGohQHQJnQMdom7kTb3SvLt7-AtCEdGnECX9LItYsu8qV9hzZPZdyWhR1k5IQ8U68Tpi3bF6lLlDHym7Nj2pQe9H-PHp0p1AtAfhoxNd7Hd0tnCQVCPFFtv5Tvfd_bWKs/s630/20210220-8.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;355&quot; data-original-width=&quot;630&quot; height=&quot;225&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqZpmhReQvLwTGohQHQJnQMdom7kTb3SvLt7-AtCEdGnECX9LItYsu8qV9hzZPZdyWhR1k5IQ8U68Tpi3bF6lLlDHym7Nj2pQe9H-PHp0p1AtAfhoxNd7Hd0tnCQVCPFFtv5Tvfd_bWKs/w400-h225/20210220-8.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟9：點選「LINE Login」頁籤，這裡「Callback URL」需要一個 Https 的網址，由下面幾個步驟來建立。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNZMFfNndsUljYc-e99NF0uuOwos23al4wCBOVTVEx3IZVJyZu0qwfHTI4w5fe_7mJRD3dNwQiEqMNcW4uyIBAgmXLmWSlzyWl3PvDz8uBfMys_8xVm6wg4lOXee56xtxLMTZXwVSZ6HU/s472/20210220-9.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;374&quot; data-original-width=&quot;472&quot; height=&quot;318&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNZMFfNndsUljYc-e99NF0uuOwos23al4wCBOVTVEx3IZVJyZu0qwfHTI4w5fe_7mJRD3dNwQiEqMNcW4uyIBAgmXLmWSlzyWl3PvDz8uBfMys_8xVm6wg4lOXee56xtxLMTZXwVSZ6HU/w400-h318/20210220-9.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟10：至 &lt;a href=&quot;https://www.usbwebserver.net/webserver/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;USBWebserver&lt;/a&gt; 官網下載輕量級網站伺服器軟體&amp;nbsp;&lt;a href=&quot;https://www.usbwebserver.net/webserver/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;USBWebserver&lt;/a&gt;，解壓縮&amp;nbsp;USBWebserver。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgW7JWWLhDrumUfe2muVUJ1vZUV0KLlUTjtCxlJHeCC5Q4Za9XzhS1BeAhKQlpB1f6Q7fsM1r-1lwjwbJmslU56_fEdsLfkHCNpCnJ6ESj-LHp7wxdPp1CUddFbWhDZupPgSZ8BSxbloNU/s807/20210220-10.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;639&quot; data-original-width=&quot;807&quot; height=&quot;316&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgW7JWWLhDrumUfe2muVUJ1vZUV0KLlUTjtCxlJHeCC5Q4Za9XzhS1BeAhKQlpB1f6Q7fsM1r-1lwjwbJmslU56_fEdsLfkHCNpCnJ6ESj-LHp7wxdPp1CUddFbWhDZupPgSZ8BSxbloNU/w400-h316/20210220-10.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟11：至 &lt;a href=&quot;https://ngrok.com/download&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;ngrok&lt;/a&gt; 官網下載 &lt;a href=&quot;https://ngrok.com/download&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;ngrok&lt;/a&gt;，&lt;a href=&quot;https://ngrok.com/download&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;ngrok&lt;/a&gt; 是一個可以讓內網伺服器與外界溝通的服務，解壓縮&amp;nbsp;&lt;a href=&quot;https://ngrok.com/download&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;ngrok&lt;/a&gt;。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDh29tWZB-hLKAwYEodz6r3Rn5h3n4RRazsnuNZSLVTvLqgKeTSo-LoArWXv3QR7L7oVV0kgeI7gP38CRgOYxJln4HsNNYPH91Foe4Uj_pTx-AO8LMjtV0vdBpSBTXFY6x74jPGgn4-SU/s812/20210220-11.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;658&quot; data-original-width=&quot;812&quot; height=&quot;324&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDh29tWZB-hLKAwYEodz6r3Rn5h3n4RRazsnuNZSLVTvLqgKeTSo-LoArWXv3QR7L7oVV0kgeI7gP38CRgOYxJln4HsNNYPH91Foe4Uj_pTx-AO8LMjtV0vdBpSBTXFY6x74jPGgn4-SU/w400-h324/20210220-11.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟12：啟動USBWebserver.exe，此時Apache已啟動，web 預設 port 為 8080。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioitRVV4mQYQ_UiQ2JHRFxd7ZVzxEaBxo-BIM7_EgaA8kur6vGSkg7tEuedm_RiwtJWLG3ebP_35CjmdEOpXZbmj8Yy7dBifXqzwge3XTZSSWgmUKzBp1SiueLwzF_pcdwYmJ5vIPv5-M/s500/20210220-12.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;250&quot; data-original-width=&quot;500&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioitRVV4mQYQ_UiQ2JHRFxd7ZVzxEaBxo-BIM7_EgaA8kur6vGSkg7tEuedm_RiwtJWLG3ebP_35CjmdEOpXZbmj8Yy7dBifXqzwge3XTZSSWgmUKzBp1SiueLwzF_pcdwYmJ5vIPv5-M/w400-h200/20210220-12.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟13：開啟「命令提示字元」切換到 ngrok 所在目錄，輸入「ngrok&amp;nbsp;http 8080」，起動內網伺服器與外界溝通的服務。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfNzsbH_MiLus8JmmSm17EFFNgxqkBapQ_-9vRY63lB-ejbR1EOzaXWhcoLJrCvoLFuWTVhpj_DFrMNYwgkaABanf8uLy3X5Uk4A-M1p8bVlzjqVhW32C9kJZnqB6wds9rCuLsoy3Lz1k/s677/20210220-13.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;442&quot; data-original-width=&quot;677&quot; height=&quot;261&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfNzsbH_MiLus8JmmSm17EFFNgxqkBapQ_-9vRY63lB-ejbR1EOzaXWhcoLJrCvoLFuWTVhpj_DFrMNYwgkaABanf8uLy3X5Uk4A-M1p8bVlzjqVhW32C9kJZnqB6wds9rCuLsoy3Lz1k/w400-h261/20210220-13.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;此時就會產生一個&amp;nbsp;Https 的網址。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsmmG1Tox4gXWg_tP1KnLu4ozBj7TBw24mrea2huqAgtU3AT4tZmCO9PRUPS3takZr_HovdUK4FbIbm4SrcbZHedZj4Rmbkzn3-vYGd_f0ghKTWRTXI96edC0_XIAz2Rw2frWyy8AT4ec/s660/20210220-14.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;442&quot; data-original-width=&quot;660&quot; height=&quot;268&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsmmG1Tox4gXWg_tP1KnLu4ozBj7TBw24mrea2huqAgtU3AT4tZmCO9PRUPS3takZr_HovdUK4FbIbm4SrcbZHedZj4Rmbkzn3-vYGd_f0ghKTWRTXI96edC0_XIAz2Rw2frWyy8AT4ec/w400-h268/20210220-14.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;複製網址貼到 Chrome 瀏覽器的新分面上開啟測試，若成功開啟，表示 Https&amp;nbsp;網址已經串接完成。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqzdjDz1aPwmwNidhD_cBdWqw48K20lavfEF_uZ-zik1vKsK7uhYuYfy9G2J4iDEoxNKq5SaP1RdEQfVaibWVAaYh4FQ5k06SPIUVcPz_WVWgExyrq8OhR8Czb1FHdpmB1zRcGRn8DwcI/s1155/20210220-15.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;875&quot; data-original-width=&quot;1155&quot; height=&quot;303&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqzdjDz1aPwmwNidhD_cBdWqw48K20lavfEF_uZ-zik1vKsK7uhYuYfy9G2J4iDEoxNKq5SaP1RdEQfVaibWVAaYh4FQ5k06SPIUVcPz_WVWgExyrq8OhR8Czb1FHdpmB1zRcGRn8DwcI/w400-h303/20210220-15.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟14：將 Https&amp;nbsp;網址填到 步驟9「LINE Login」頁籤的「Callback URL」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXZE1cFCAZvHV45eQShDeb_-XjQDom8EwQw-l3B97-hmpEynobv2e7FWR834c77KFgjCk9FRvgQBc5rI-QLD6v5Y3PtqOczZmRiL1APilc2DQeZFwY-Rt6FYgiMZHWtVkG_k6elsJde90/s724/20210220-16.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;389&quot; data-original-width=&quot;724&quot; height=&quot;215&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXZE1cFCAZvHV45eQShDeb_-XjQDom8EwQw-l3B97-hmpEynobv2e7FWR834c77KFgjCk9FRvgQBc5rI-QLD6v5Y3PtqOczZmRiL1APilc2DQeZFwY-Rt6FYgiMZHWtVkG_k6elsJde90/w400-h215/20210220-16.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟15： 建立 Line 授權，將以下 JavaScript 程式碼存成 linelogin.html，並到&amp;nbsp;&lt;a href=&quot;https://developers.line.biz/zh-hant/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Line&amp;nbsp;Developers&lt;/a&gt;&amp;nbsp;後台的「Basic settings」頁籤將「Channel ID」、「Your user ID」與將 linelogin.html 與 Https&amp;nbsp;網址完整的串接在一起填入程式碼。&lt;br /&gt;
&lt;pre class=&quot;brush:html&quot;&gt; &amp;lt;!DOCTYPE html&amp;gt;
    &amp;lt;html lang=&quot;en&quot;&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
        &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&amp;gt;
        &amp;lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&amp;gt;
        &amp;lt;title&amp;gt;LINE Login Demo&amp;lt;/title&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;button id=&quot;lineLoginBtn&quot;&amp;gt;LINE login&amp;lt;/button&amp;gt;
        &amp;lt;script src=&#39;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js&#39;&amp;gt;&amp;lt;/script&amp;gt;
        &amp;lt;script&amp;gt;
            var channel_id = &quot;channel id&quot;;
            var channel_secret = &quot;channel secret&quot;;
            var uri = &quot;Https網址&quot;;
            
            //var code = &quot;&quot;; 
            $(&#39;#lineLoginBtn&#39;).on(&#39;click&#39;, function(e) {
                let client_id = channel_id;
                let redirect_uri = uri;
                let link = &#39;https://access.line.me/oauth2/v2.1/authorize?&#39;;
                link += &#39;response_type=code&#39;;
                link += &#39;&amp;amp;client_id=&#39; + client_id;
                link += &#39;&amp;amp;redirect_uri=&#39; + redirect_uri;
                link += &#39;&amp;amp;state=login&#39;;
                link += &#39;&amp;amp;scope=openid%20profile%20email&#39;;
                window.location.href = link;
            });

            var url = new URL(window.location.href);
            var code = url.searchParams.get(&quot;code&quot;); 
            if(code != null) document.write(&#39;&amp;lt;br / &amp;gt; code : &#39; + code + &#39;&amp;lt;br / &amp;gt;&#39;); 
        &amp;lt;/script&amp;gt;
    &amp;lt;/body&amp;gt;
    &amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcYMhitjsS_MlZrGpZyq_UZMhUJYYIApXgfkunbGcl9Dq6ZJBQf2KJNNzQMwsq2dJ8s6mtLIP2FIMyuVsNtaXoJ-vERX1z191cWukvkeSfCDFGWZnbiq84OE47dwplwpW7Kxnqe1w2JhU/s1533/20210220-17.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;987&quot; data-original-width=&quot;1533&quot; height=&quot;258&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcYMhitjsS_MlZrGpZyq_UZMhUJYYIApXgfkunbGcl9Dq6ZJBQf2KJNNzQMwsq2dJ8s6mtLIP2FIMyuVsNtaXoJ-vERX1z191cWukvkeSfCDFGWZnbiq84OE47dwplwpW7Kxnqe1w2JhU/w400-h258/20210220-17.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAunG_i3KshFu7z0cLrM4Ni49O6kb6ObKAj3kEZcLJ-D85u4-FzuVsbjR5YVEcQ19YP8Q5kP3HOcept-lsWqOZY35zvbTvUmFJUO0xSrFkWEeVE6jxkzdFr_rh4jUUyWxNeTojKyR244c/s623/20210220-18.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;432&quot; data-original-width=&quot;623&quot; height=&quot;278&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAunG_i3KshFu7z0cLrM4Ni49O6kb6ObKAj3kEZcLJ-D85u4-FzuVsbjR5YVEcQ19YP8Q5kP3HOcept-lsWqOZY35zvbTvUmFJUO0xSrFkWEeVE6jxkzdFr_rh4jUUyWxNeTojKyR244c/w400-h278/20210220-18.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟16：在 Chrome 瀏覽器的新分面上開啟「Callback URL」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1VYa6BbOaR0GPusP_qDoG2GfysQduYm7nI075SXZ4mdgqDB7oyWaIEPW6it3SKJTwu6hu3leuri5e4nlAMpTvYU-Wd1w1KFgea6ZUqMKNR9Z4gL6VhStmXNINHB2qaI43_GKZsGZOes4/s798/20210220-19.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;703&quot; data-original-width=&quot;798&quot; height=&quot;353&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1VYa6BbOaR0GPusP_qDoG2GfysQduYm7nI075SXZ4mdgqDB7oyWaIEPW6it3SKJTwu6hu3leuri5e4nlAMpTvYU-Wd1w1KFgea6ZUqMKNR9Z4gL6VhStmXNINHB2qaI43_GKZsGZOes4/w400-h353/20210220-19.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;步驟17：點擊「LINE login」按鈕，即可見到「LINE」登入畫面，點擊「登入」按鈕。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiojfFZ-mDiz_opm_n1bBxI2zu8PNGGe_E2C8atH9TwolZCtzrqI-Ig-yYoiKdWpfEgwOREeMFmoURIUgMj9jdb2XgbWDMfUt6uaHPJM5R92RaU9iZQGTCytPrZ1sNmIxeRo3SQwnbub7k/s798/20210220-20.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;703&quot; data-original-width=&quot;798&quot; height=&quot;353&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiojfFZ-mDiz_opm_n1bBxI2zu8PNGGe_E2C8atH9TwolZCtzrqI-Ig-yYoiKdWpfEgwOREeMFmoURIUgMj9jdb2XgbWDMfUt6uaHPJM5R92RaU9iZQGTCytPrZ1sNmIxeRo3SQwnbub7k/w400-h353/20210220-20.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;接著出現授權許可的畫面，點擊「許可」按鈕。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFUybV07debRynmbSbYOgZ_JsmbPlPOJ46bg1j69FkT4T3UQnGt_VId8IRYoCxF70ZNJh_rZl5eOXiH6DscDRXzaoKyX6i2HGDQKE5LRki28Ac0UkMDKkZi19N-kiPVRDPMmodoxA1tdk/s1010/20210220-21.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1010&quot; data-original-width=&quot;785&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFUybV07debRynmbSbYOgZ_JsmbPlPOJ46bg1j69FkT4T3UQnGt_VId8IRYoCxF70ZNJh_rZl5eOXiH6DscDRXzaoKyX6i2HGDQKE5LRki28Ac0UkMDKkZi19N-kiPVRDPMmodoxA1tdk/w311-h400/20210220-21.png&quot; width=&quot;311&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
最後回到原本的網頁，在網址中的「code」就是我的要取得的內容。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh62CguBVZzFHDYFMCblZ8WTpTtpu9XIGKZdgUaBiMZxQkL4TUiQ4QfYO9Qsg_JOL2tNlYBXg9lDlT8HeBeA4PNi-Zls67KUoFQUnvuzZDYBa-PwuaaHeCF9-VpvGb_WBtO0ZuTSHpNI2Y/s1013/20210220-22.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;252&quot; data-original-width=&quot;1013&quot; height=&quot;100&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh62CguBVZzFHDYFMCblZ8WTpTtpu9XIGKZdgUaBiMZxQkL4TUiQ4QfYO9Qsg_JOL2tNlYBXg9lDlT8HeBeA4PNi-Zls67KUoFQUnvuzZDYBa-PwuaaHeCF9-VpvGb_WBtO0ZuTSHpNI2Y/w400-h100/20210220-22.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟18：將以下程式碼再加入 linelogin.html，再執行一次登入授權，取回token。&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt;var result = $(&quot;.result&quot;);
var id_token = &quot;&quot;;
$.ajax({
  method: &quot;POST&quot;,
  dataType : &#39;json&#39;,
  url: &quot;https://api.line.me/oauth2/v2.1/token&quot;,
  async : false,              
  data: { grant_type    : &quot;authorization_code&quot;, 
          code          : code,
          redirect_uri  : uri,
          client_id     : channel_id,
          client_secret : channel_secret},
  success: function(data) {
    id_token = data.id_token;                 
  }
});            
if(id_token.length != 0)  document.write(&#39;&amp;lt;br / &amp;gt;id_token : &#39; + id_token + &#39;&amp;lt;br / &amp;gt;&#39;);
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9m8H3OAT0C2er02bIgLYRqyte_TuOtTqKAS447TikLP8LGHYelM_Gryb6IVaosOmOPc-DGa4EFcRB48NYCCFii7T_z7ShbigeDOBHoqzzQEwu0UwfrKytonoiwJIEKw_QpWIxa2nTQmQ/s1003/20210220-23.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;315&quot; data-original-width=&quot;1003&quot; height=&quot;125&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9m8H3OAT0C2er02bIgLYRqyte_TuOtTqKAS447TikLP8LGHYelM_Gryb6IVaosOmOPc-DGa4EFcRB48NYCCFii7T_z7ShbigeDOBHoqzzQEwu0UwfrKytonoiwJIEKw_QpWIxa2nTQmQ/w400-h125/20210220-23.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟19：將以下程式碼再加入 linelogin.html，再執行一次登入授權，拿token呼API取得使用者的公開資料。&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt;$.ajax({
  method: &quot;POST&quot;,
  dataType : &#39;json&#39;,
  url: &quot;https://api.line.me/oauth2/v2.1/verify&quot;,
  async : false,              
  data: { client_id     : channel_id,
          id_token      : id_token },
  success: function(data) {
    document.write(&#39;&amp;lt;br / &amp;gt;&amp;lt;br / &amp;gt;&#39; + JSON.stringify(data));
  }
});
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4PaGTfand3BHF2T5upWWz02egBH6DswrWzVWqf58QxSVcXIfe4A79ZvBKiHn0oBrdhCPx4hdgNoSyZ_bkTBdCTfcqDma2VSanImqA2BZMS4fVeNs6Z4tlqJRyZlKXiRlAeTZfGb0oFQk/s1003/20210220-24.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;365&quot; data-original-width=&quot;1003&quot; height=&quot;145&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4PaGTfand3BHF2T5upWWz02egBH6DswrWzVWqf58QxSVcXIfe4A79ZvBKiHn0oBrdhCPx4hdgNoSyZ_bkTBdCTfcqDma2VSanImqA2BZMS4fVeNs6Z4tlqJRyZlKXiRlAeTZfGb0oFQk/w400-h145/20210220-24.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;將上面所有程式碼整合起來。&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt; &amp;lt;!DOCTYPE html&amp;gt;
    &amp;lt;html lang=&quot;en&quot;&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
        &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&amp;gt;
        &amp;lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&amp;gt;
        &amp;lt;title&amp;gt;LINE Login Demo&amp;lt;/title&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;button id=&quot;lineLoginBtn&quot;&amp;gt;LINE login&amp;lt;/button&amp;gt;
        &amp;lt;script src=&#39;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js&#39;&amp;gt;&amp;lt;/script&amp;gt;
        &amp;lt;script&amp;gt;
            var channel_id = &quot;channel id&quot;;
            var channel_secret = &quot;channel secret&quot;;
            var uri = &quot;Https網址&quot;;

            $(&#39;#lineLoginBtn&#39;).on(&#39;click&#39;, function(e) {
                let client_id = channel_id;
                let redirect_uri = uri;
                let link = &#39;https://access.line.me/oauth2/v2.1/authorize?&#39;;
                link += &#39;response_type=code&#39;;
                link += &#39;&amp;amp;client_id=&#39; + client_id;
                link += &#39;&amp;amp;redirect_uri=&#39; + redirect_uri;
                link += &#39;&amp;amp;state=login&#39;;
                link += &#39;&amp;amp;scope=openid%20profile%20email&#39;;
                window.location.href = link;
            });

            var url = new URL(window.location.href);
            var code = url.searchParams.get(&quot;code&quot;); 
            if(code != null) document.write(&#39;&amp;lt;br / &amp;gt; code : &#39; + code + &#39;&amp;lt;br / &amp;gt;&#39;);
            
            var result = $(&quot;.result&quot;);
            var id_token = &quot;&quot;;
            $.ajax({
              method: &quot;POST&quot;,
              dataType : &#39;json&#39;,
              url: &quot;https://api.line.me/oauth2/v2.1/token&quot;,
              async : false,              
              data: { grant_type    : &quot;authorization_code&quot;, 
                      code          : code,
                      redirect_uri  : uri,
                      client_id     : channel_id,
                      client_secret : channel_secret},
              success: function(data) {
                id_token = data.id_token;                 
              }
            });            
            if(id_token.length != 0)  document.write(&#39;&amp;lt;br / &amp;gt;id_token : &#39; + id_token + &#39;&amp;lt;br / &amp;gt;&#39;);
            
            $.ajax({
              method: &quot;POST&quot;,
              dataType : &#39;json&#39;,
              url: &quot;https://api.line.me/oauth2/v2.1/verify&quot;,
              async : false,              
              data: { client_id     : channel_id,
                      id_token      : id_token },
              success: function(data) {
                document.write(&#39;&amp;lt;br / &amp;gt;&amp;lt;br / &amp;gt;&#39; + JSON.stringify(data));
              }
            });
        &amp;lt;/script&amp;gt;
    &amp;lt;/body&amp;gt;
    &amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;到了這裡就完成透過LINE Login的認證達成登入的操作。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/4827446623317947109/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2021/02/openid-googlefacebookline-line-login.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/4827446623317947109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/4827446623317947109'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2021/02/openid-googlefacebookline-line-login.html' title='Google、Facebook、Line OAuth 實做登入操作 (1) - Line Login'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigEllFPKl6QUvd2Vft3VNHGxVeNterAQmR8C35Mj01CeOKB7GXvwvoXYrh5cTgmE-mkU9dE5zla0n17Xx78-PsrVuBIawRwlaFIiPqGtMX2mB2WUGeCTfwOjva8ZYBBp6xbVIVvJa0v70/s72-w400-h275-c/20210220-1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-7461466633887863988</id><published>2020-06-04T00:26:00.001-07:00</published><updated>2020-06-04T00:26:55.689-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Excel"/><category scheme="http://www.blogger.com/atom/ns#" term="VBA"/><title type='text'>Excel VBA 用for + array + Run 取代判別式執行函數</title><content type='html'>早上遇到群有問的一個問題，希望在能不用判別式的方式就能做到判別並執行程式，這樣的方式之前就有寫過，但這次被人提出來就簡單做一下，下圖是原本就由判別式的作法。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeXDmwoBPDsjnV5Wreqw9brzUw6N2rJPvzDZxxGvz5Ifwawbt05QU_VdcRO5Mqly2fP3FZiJ15Vgj0K47S8OHf7YE4dBNUIkG0SEbGpgiDotxpyuO7ZbZGcEdFjJ8Oh1m1APjv_LL1e_k/s831/20200604-1.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;487&quot; data-original-width=&quot;831&quot; height=&quot;235&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeXDmwoBPDsjnV5Wreqw9brzUw6N2rJPvzDZxxGvz5Ifwawbt05QU_VdcRO5Mqly2fP3FZiJ15Vgj0K47S8OHf7YE4dBNUIkG0SEbGpgiDotxpyuO7ZbZGcEdFjJ8Oh1m1APjv_LL1e_k/w400-h235/20200604-1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;div&gt;透過以下程式做法來做切換，以for回傳搭配亂數來運作。&lt;br /&gt;&lt;pre class=&quot;brush:vb&quot;&gt;Sub aa(a As Integer, b As String)
    Debug.Print &quot;a&quot;, a, b
End Sub

Sub bb(a As Integer, b As String)
    Debug.Print &quot;b&quot;, a, b
End Sub

Sub cc(a As Integer, b As String)
    Debug.Print &quot;c&quot;, a, b
End Sub

Sub main()
    Dim a
    a = Array(&quot;aa&quot;, &quot;bb&quot;, &quot;cc&quot;)
    Randomize
    Run a(Int(Rnd() * (UBound(a) + 1))), Int(Rnd() * 100) + 1, &quot;abc&quot;
End Sub&lt;/pre&gt;
執行畫面。&lt;br /&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNQdwb2L6OdG9j_h1VSB8UsXFlwZihczbCFPL9mBZ1L2nHuAyiACQXdaioadwtGj3jCWUdewhhDKK7aMlHj2urHE2Afnnw8FgbFqaLOf2oQNHqrAZzjczP-zQlwHWjcSwKUoq38k5MAWs/s1043/20200604-1.gif&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;838&quot; data-original-width=&quot;1043&quot; height=&quot;321&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNQdwb2L6OdG9j_h1VSB8UsXFlwZihczbCFPL9mBZ1L2nHuAyiACQXdaioadwtGj3jCWUdewhhDKK7aMlHj2urHE2Afnnw8FgbFqaLOf2oQNHqrAZzjczP-zQlwHWjcSwKUoq38k5MAWs/w400-h321/20200604-1.gif&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/7461466633887863988/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2020/06/excel-vba-for-array-run.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/7461466633887863988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/7461466633887863988'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2020/06/excel-vba-for-array-run.html' title='Excel VBA 用for + array + Run 取代判別式執行函數'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeXDmwoBPDsjnV5Wreqw9brzUw6N2rJPvzDZxxGvz5Ifwawbt05QU_VdcRO5Mqly2fP3FZiJ15Vgj0K47S8OHf7YE4dBNUIkG0SEbGpgiDotxpyuO7ZbZGcEdFjJ8Oh1m1APjv_LL1e_k/s72-w400-h235-c/20200604-1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-6624762163706200064</id><published>2020-03-19T17:50:00.000-07:00</published><updated>2020-03-19T17:50:52.342-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Excel"/><category scheme="http://www.blogger.com/atom/ns#" term="VBA"/><title type='text'>Excel VBA 下拉選單切換連動 (2)</title><content type='html'>繼前一篇&amp;nbsp;Excel VBA 下拉選單切換連動 (1)，內容一樣是Excel VBA下拉選單選的連動，只是這是要用資料驗證中的清單功能來做，這次的功能是第一個combobox選擇年月，第二個combobox將以選到的年月顯示當年度到年底剩下的月份，依舊使用 篩選 + 事件來組合。
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;在ThisWorkbooks加入&lt;br /&gt;
&lt;pre class=&quot;brush:vb&quot;&gt;Private Sub Workbook_Open()
    日期產生
    第一層清單產生
End Sub

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
    If Sh.Name = &quot;資料顯示&quot; Then
        If Target.Address = &quot;$A$1&quot; Then
            第二層清單產生
        ElseIf Target.Address = &quot;$F:$F&quot; Then
            If Workbooks(1).Sheets(1).Cells(Rows.count, &quot;F&quot;).End(xlUp).Row = 1 Then
                Workbooks(1).Sheets(1).Cells(1, 2).Value = &quot;&quot;
            End If
        End If
        Debug.Print Target.Address
    End If
End Sub
&lt;/pre&gt;
在Module1中加入&lt;br /&gt;
&lt;pre class=&quot;brush:vb&quot;&gt;Sub 日期產生()
    Sheets(2).Cells(1, 1) = &quot;日期&quot;

    For i = 2 To 13
        Sheets(2).Cells(i, 1) = Format(DateAdd(&quot;m&quot;, i - 1, DateSerial(Year(Date), 0, 1)), &quot;ee/mm&quot;)
    Next
End Sub

Sub 第一層清單產生()
    Dim listcount1 As Integer
    
    Workbooks(1).Sheets(1).Columns(5).Clear
    
    With Workbooks(1).Sheets(2)
        .Range(&quot;A:A&quot;).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Workbooks(1).Sheets(1).Range(&quot;E1&quot;), Unique:=True
    End With

    With Workbooks(1).Sheets(2)
        .Range(.Cells(2, &quot;A&quot;).Address, .Cells(Rows.count, &quot;A&quot;).End(xlUp).Address).Name = &quot;日期1&quot;
    End With
    
    &#39;設定&quot;資料驗證&quot;中的清單
    With Workbooks(1).Sheets(1).Range(&quot;A1&quot;).Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
             Operator:=xlBetween, Formula1:=&quot;=日期1&quot;
    End With
    Workbooks(1).Sheets(1).Cells(1, 1).Value = Workbooks(1).Sheets(2).Cells(2, &quot;A&quot;).Value
    Workbooks(1).Sheets(1).Cells(1, 2).Value = Workbooks(1).Sheets(1).Cells(2, &quot;F&quot;).Value
End Sub

Sub 第二層清單產生()
    Dim listcount1 As Integer
    
    Workbooks(1).Sheets(1).Columns(6).Clear
    
    過濾日期

    With Workbooks(1).Sheets(1)
        .Range(.Cells(2, &quot;F&quot;).Address, .Cells(Rows.count, &quot;F&quot;).End(xlUp).Address).Name = &quot;日期2&quot;
    End With
    
    &#39;設定&quot;資料驗證&quot;中的清單
    With Workbooks(1).Sheets(1).Range(&quot;B1&quot;)
        .Clear
        With .Validation
            .Delete
            .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
                 Operator:=xlBetween, Formula1:=&quot;=日期2&quot;
        End With
        Workbooks(1).Sheets(1).Cells(1, 2).Value = Workbooks(1).Sheets(1).Cells(2, &quot;F&quot;).Value
    End With
End Sub

Sub 過濾日期()
    Dim tmp, line
    Dim i As Integer, j As Integer, count As Integer, column As Integer
    
    With Workbooks(1).Sheets(2)
        column = .Cells(1, Columns.count).End(xlToLeft).column
        With .UsedRange
  
            .AutoFilter Field:=.Cells(1, &quot;A&quot;).column, Criteria1:=&quot;&amp;gt;=&quot; &amp;amp; Sheets(1).Cells(1, 1)
            
            &#39;選出符合條件的資料
            Set tmp = .Resize(.Rows.count).SpecialCells(xlCellTypeVisible)
            count = 1
            For Each line In tmp.Areas
                For i = 1 To line.Rows.count
                    For j = 1 To 1
                        &#39;Debug.Print line(i, j).Value
                        Sheets(1).Cells(count, &quot;F&quot;).Value = line(i, j).Value
                    Next
                    count = count + 1
                Next
            Next
        End With
        
        &#39;關閉篩選
        .AutoFilterMode = False
    End With
End Sub
&lt;/pre&gt;
畫面。
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNJpM2jq40SWRmOUwlJUIhgWbTCKm6wUjrKC14ivdk10xGMN6Ioald3l8E1tfkChqNkJJGiJWXlzF3Worfik1FLSJNkp8uglpE3jerCYNZmmVW_sx3uPTcUMLF5mXTtcnQ8tLwqEBe4Sk/s1600/20200317-2.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;580&quot; data-original-width=&quot;714&quot; height=&quot;323&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNJpM2jq40SWRmOUwlJUIhgWbTCKm6wUjrKC14ivdk10xGMN6Ioald3l8E1tfkChqNkJJGiJWXlzF3Worfik1FLSJNkp8uglpE3jerCYNZmmVW_sx3uPTcUMLF5mXTtcnQ8tLwqEBe4Sk/s400/20200317-2.gif&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a href=&quot;https://drive.google.com/file/d/18EHKxnTKqhFNEuL7AZhbBrhZPWPEF1cN/view?usp=sharing&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;檔案連結&lt;/a&gt;。&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/6624762163706200064/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2020/03/excel-vba-2.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/6624762163706200064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/6624762163706200064'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2020/03/excel-vba-2.html' title='Excel VBA 下拉選單切換連動 (2)'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNJpM2jq40SWRmOUwlJUIhgWbTCKm6wUjrKC14ivdk10xGMN6Ioald3l8E1tfkChqNkJJGiJWXlzF3Worfik1FLSJNkp8uglpE3jerCYNZmmVW_sx3uPTcUMLF5mXTtcnQ8tLwqEBe4Sk/s72-c/20200317-2.gif" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-2567700359641368733</id><published>2020-03-18T02:19:00.000-07:00</published><updated>2020-03-19T17:40:21.055-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Excel"/><category scheme="http://www.blogger.com/atom/ns#" term="VBA"/><title type='text'>Excel VBA 下拉選單切換連動 (1)</title><content type='html'>近期遇到網友想要Excel VBA的表單介面做下拉選單選的連動，主要功能從第一個combobox選擇縣市，依顯示名稱過濾出鄉鎮市區，再填到第二個combobox，原生的下拉選單combobox沒連動功能，所以需要想辦法組合出這樣的功能，因此藉由內部既有的功能 篩選 + 事件來組合。
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;在表單上加入兩個combobox元件，並使用以下程式碼完成下拉選單的連動。&lt;br /&gt;
在ThisWorkbooks加入&lt;br /&gt;
&lt;pre class=&quot;brush:vb&quot;&gt;Private Sub Workbook_Open()
    UserForm1.Show
End Sub
&lt;/pre&gt;
在表單中加入&lt;br /&gt;
&lt;pre class=&quot;brush:vb&quot;&gt;Private Sub ComboBox1_Change()
    ComboBox2.Clear
    第二層清單產生 ComboBox1.text
    additem2
    ComboBox2.text = ComboBox2.List(0)
End Sub

Private Sub UserForm_Activate()
    郵遞區號取得
    第一層清單產生
    additem1
    ComboBox1.text = ComboBox1.List(0)    
End Sub

Sub additem1()
    Dim row As Integer, i  As Integer
    
    row = Sheets(3).Cells(Rows.count, 1).End(xlUp).row
    For i = 2 To row
        ComboBox1.additem Sheets(3).Cells(i, 1)
    Next
End Sub

Sub additem2()
    Dim row As Integer, i  As Integer
    
    row = Sheets(3).Cells(Rows.count, 2).End(xlUp).row
    For i = 2 To row
        ComboBox2.additem Sheets(3).Cells(i, 2)
    Next
End Sub&lt;/pre&gt;
在Module1中加入&lt;br /&gt;
&lt;pre class=&quot;brush:vb&quot;&gt;Sub 郵遞區號取得()

    Dim row As Integer
    
    With Sheets(2).QueryTables.Add(Connection:= _
        &quot;URL;http://campus4.ncku.edu.tw/wwwmenu/program/net/zip.htm&quot;, Destination:=Sheets(2).Range(&quot;$A$1&quot;))
        .RefreshStyle = xlOverwriteCells
        .WebFormatting = xlWebFormattingNone
        .WebTables = 1
        .Refresh BackgroundQuery:=False
        row = .ResultRange.Rows.count
        .Delete
    End With
    
    Sheets(2).Cells(1, 3) = &quot;縣市&quot;
    Sheets(2).Cells(1, 4) = &quot;鄉鎮市區&quot;
    For i = 2 To row
        Sheets(2).Cells(i, 3) = Mid(Sheets(2).Cells(i, 2), 1, 3)
        Sheets(2).Cells(i, 4) = Mid(Sheets(2).Cells(i, 2), 4, 3)
    Next

End Sub

Sub 第一層清單產生()
    Dim listcount1 As Integer
    
    Workbooks(1).Sheets(3).Cells.Clear
    &#39;進階過濾篩選出不重複的鄉鎮市
    With Workbooks(1).Sheets(2)
        .Range(&quot;C:C&quot;).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Workbooks(1).Sheets(3).Range(&quot;A1&quot;), Unique:=True
    End With

End Sub

Sub 第二層清單產生(text As String)
    Dim tmp, line
    Dim i As Integer, count As Integer
    
    With Workbooks(1).Sheets(2)
        With .UsedRange
            &#39;鄉鎮市篩選
            .AutoFilter Field:=.Cells(1, &quot;C&quot;).Column, Criteria1:=&quot;=&quot; &amp;amp; text
            
            &#39;選出符合條件的資料
            Set tmp = .Resize(.Rows.count - 1).SpecialCells(xlCellTypeVisible)
            count = 1
            For Each line In tmp.Areas
                For i = 1 To line.Rows.count
                    Sheets(3).Cells(count, 2).Value = line(i, 4).Value
                    count = count + 1
                Next
            Next
        End With
        
        &#39;關閉篩選
        .AutoFilterMode = False
    End With
End Sub&lt;/pre&gt;
&lt;br /&gt;
畫面。
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQPmBsYfbKd6Aqvo5jPjucxWQC5js2jF-GHwokS3-bjy73QvPZG9d3KlLI19wQ6ej4YVpIBjK10NFZu1T8ZLEQb2lqAso4OoQFVbCU9V04yD5FLmuhzlyMtzjDWLmEboXotdfGzLWbJfI/s1600/20200314-1.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;813&quot; data-original-width=&quot;945&quot; height=&quot;343&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQPmBsYfbKd6Aqvo5jPjucxWQC5js2jF-GHwokS3-bjy73QvPZG9d3KlLI19wQ6ej4YVpIBjK10NFZu1T8ZLEQb2lqAso4OoQFVbCU9V04yD5FLmuhzlyMtzjDWLmEboXotdfGzLWbJfI/s400/20200314-1.gif&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1F0cG58sFJx7Gu-cDNbARuWv8xlYBfVsl/view?usp=sharing&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;檔案連結&lt;/a&gt;。</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/2567700359641368733/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2020/03/excel-vba-1.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/2567700359641368733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/2567700359641368733'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2020/03/excel-vba-1.html' title='Excel VBA 下拉選單切換連動 (1)'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQPmBsYfbKd6Aqvo5jPjucxWQC5js2jF-GHwokS3-bjy73QvPZG9d3KlLI19wQ6ej4YVpIBjK10NFZu1T8ZLEQb2lqAso4OoQFVbCU9V04yD5FLmuhzlyMtzjDWLmEboXotdfGzLWbJfI/s72-c/20200314-1.gif" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-2489124422235006509</id><published>2020-03-15T06:01:00.001-07:00</published><updated>2020-03-15T06:03:23.522-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Heroku"/><category scheme="http://www.blogger.com/atom/ns#" term="Line"/><category scheme="http://www.blogger.com/atom/ns#" term="Line Bot"/><category scheme="http://www.blogger.com/atom/ns#" term="Line Messaging API"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Heroku + Flask + Python應用(3)：快速建立Line Bot，至Heroku佈署</title><content type='html'>前一篇&amp;nbsp;&lt;a href=&quot;http://white5168.blogspot.com/2020/03/heroku-flask-python2herokuline-bot.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Heroku + Flask + Python應用(2)：VSCode建置Line Bot，上傳Heroku佈署&lt;/a&gt;&amp;nbsp;的操作看起來很複雜，因此換一種方式來進行Line Bot建置，環境一樣是在Heroku上執行。
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;b&gt;步驟 1&lt;/b&gt;：本機端佈屬環境軟體。&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;請至 Heroku&amp;nbsp; &lt;a href=&quot;https://id.heroku.com/login&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://id.heroku.com/login&lt;/a&gt; 註冊一個帳號。&lt;/li&gt;
&lt;li&gt;下載安裝 Heroku CLI &lt;a href=&quot;https://devcenter.heroku.com/articles/heroku-cli&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://devcenter.heroku.com/articles/heroku-cli&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;下載安裝 Git &lt;a href=&quot;https://git-scm.com/downloads&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://git-scm.com/downloads&lt;/a&gt;，上傳檔案到 Heroku 使用。&lt;/li&gt;
&lt;li&gt;下載安裝VSCode &lt;a href=&quot;https://code.visualstudio.com/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://code.visualstudio.com/&lt;/a&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;b&gt;步驟 2&lt;/b&gt;：開啟「命令提示字元」輸入以下指令，建立Code資料夾，用 conda 建立「iinfo7」虛擬環境。
&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;cd /
mkdir Code
cd Code
conda create -n iinfo7 python=3.6.2
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQYBsmnduMfLsYaR_XCaJfJua9cQbir0jTRn__wLfORfDuEmMa1xu7LTdQp4-6m84kunkFTjb-MFGpPvLA4ZojudCWlYlXAIAqqPs7wX8jG9oAn48g_FkpJTk8a3E83thmctxkG2HKUuM/s1600/20200315-001.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;506&quot; data-original-width=&quot;677&quot; height=&quot;298&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQYBsmnduMfLsYaR_XCaJfJua9cQbir0jTRn__wLfORfDuEmMa1xu7LTdQp4-6m84kunkFTjb-MFGpPvLA4ZojudCWlYlXAIAqqPs7wX8jG9oAn48g_FkpJTk8a3E83thmctxkG2HKUuM/s400/20200315-001.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 3&lt;/b&gt;：完成建立「linebot」虛擬環境後，進入「linebot」環境。
&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;activate iinfo7
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3qlUXcz7AEiqMkLCZFrLzZi_cn5zNKoqAFJRD5SbcysM_73W1_N67saSOaH5I-KZoh5vsyBBC26qQraw0QTqIJCy9vprynVPJ_-2XSt0ZUPDgg0ce6TMWizo3xf3kytW4XvNfVYu5190/s1600/20200315-002.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;506&quot; data-original-width=&quot;677&quot; height=&quot;298&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3qlUXcz7AEiqMkLCZFrLzZi_cn5zNKoqAFJRD5SbcysM_73W1_N67saSOaH5I-KZoh5vsyBBC26qQraw0QTqIJCy9vprynVPJ_-2XSt0ZUPDgg0ce6TMWizo3xf3kytW4XvNfVYu5190/s400/20200315-002.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
若要退出虛擬環境，輸入以下指令。&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;deactivate
&lt;/pre&gt;
或
&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;activate root
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0AjpSTOuEQUfVive1NU9BgQIt25E_pSNg0C1ggXJp1a-kjBWr504fYZGO3PdGmeIcR253yVfCUVMyrwZzqJijbAEgcV9B8SeWvklG6OHMgGu6U-B0WU2sTd6deeCVpSzOPdkQ1KQE5Ho/s1600/20200315-003.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;506&quot; data-original-width=&quot;677&quot; height=&quot;298&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0AjpSTOuEQUfVive1NU9BgQIt25E_pSNg0C1ggXJp1a-kjBWr504fYZGO3PdGmeIcR253yVfCUVMyrwZzqJijbAEgcV9B8SeWvklG6OHMgGu6U-B0WU2sTd6deeCVpSzOPdkQ1KQE5Ho/s400/20200315-003.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 4&lt;/b&gt;：在「命令提示字元」輸入「git init」，產生「.git」資料夾，讓Git開始對「Code」資料夾所有檔案進行版本控管。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0S74Sf0yvVaRiBOeT1EH8gIN9kf9y3SkdsGnbTDzkWqxnmdJ9uqd9d6BJscMyXpOjD2gAyetUMcNYe0DcP09ZayTPbrlV2mI2ZiXiWtZzQTdhgQkt9uFQ1J0rLZDr7TBALAD-yWYXTf4/s1600/20200315-004.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;506&quot; data-original-width=&quot;677&quot; height=&quot;298&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0S74Sf0yvVaRiBOeT1EH8gIN9kf9y3SkdsGnbTDzkWqxnmdJ9uqd9d6BJscMyXpOjD2gAyetUMcNYe0DcP09ZayTPbrlV2mI2ZiXiWtZzQTdhgQkt9uFQ1J0rLZDr7TBALAD-yWYXTf4/s400/20200315-004.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 5&lt;/b&gt;：安裝「flask」、「gunicorn」到「iinfo7」環境中，後面操作時會使用到。&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;pip install flask gunicorn
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTgFkk3QF15_xqp2Z9aL_RvFsNNQ1X4EtJKh2hCYdILHdHOUcn9_Z5g6HquJ4cDrAbqN4IvTK3m87IauCU4FE0ySPxl_okeodAEw5-Y5JYHvqylUS8dlOUt03Z08RqjOdTJTPCCjbEgx4/s1600/20200315-005.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;506&quot; data-original-width=&quot;677&quot; height=&quot;298&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTgFkk3QF15_xqp2Z9aL_RvFsNNQ1X4EtJKh2hCYdILHdHOUcn9_Z5g6HquJ4cDrAbqN4IvTK3m87IauCU4FE0ySPxl_okeodAEw5-Y5JYHvqylUS8dlOUt03Z08RqjOdTJTPCCjbEgx4/s400/20200315-005.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 6&lt;/b&gt;：在「命令提示字元」輸入「pip list」查詢在虛擬環境「iinfo7」已安裝的套件與版本。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4-MdcjP4USEnk1GKX1OLYOIjcyA5gmcrw6y_FyKClQstXq7Cp78eXmV64PyaWnrey6uMwjt9FZmzJt7MhTWeCSiGklZ0IyDQ_e2aWOoEO7UMPgdMFGeAeSQGh0EzxU8PKAlQDD3pkrDg/s1600/20200315-006.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;506&quot; data-original-width=&quot;677&quot; height=&quot;298&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4-MdcjP4USEnk1GKX1OLYOIjcyA5gmcrw6y_FyKClQstXq7Cp78eXmV64PyaWnrey6uMwjt9FZmzJt7MhTWeCSiGklZ0IyDQ_e2aWOoEO7UMPgdMFGeAeSQGh0EzxU8PKAlQDD3pkrDg/s400/20200315-006.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 7&lt;/b&gt;：在「命令提示字元」輸入「code .」開啟 VSCode。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqBXhM_Z1dP3K8L16H_yyL_G5W0XadJhgpMwzdrio3JAGcThPhIjZ8ZLCgzJ5Ne3_LUmtqwAuzULqisjLNpR7APYVgOPxoufXx9ASmuYPUYTX_OqdE_8qcwB-m5DqmaavfNYGSczJ4tyw/s1600/20200315-007.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;506&quot; data-original-width=&quot;677&quot; height=&quot;298&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqBXhM_Z1dP3K8L16H_yyL_G5W0XadJhgpMwzdrio3JAGcThPhIjZ8ZLCgzJ5Ne3_LUmtqwAuzULqisjLNpR7APYVgOPxoufXx9ASmuYPUYTX_OqdE_8qcwB-m5DqmaavfNYGSczJ4tyw/s400/20200315-007.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 8&lt;/b&gt;：在VSCode 建立Python 檔案，並輸入以下程式碼，存成app.py。&lt;br /&gt;
&lt;pre class=&quot;brush:py&quot;&gt;import os

from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)

from linebot.exceptions import (
    InvalidSignatureError
)

from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)

app = Flask(__name__)

LINE_CHANNEL_ACCESS_TOKEN = os.environ.get(&#39;LINE_CHANNEL_ACCESS_TOKEN&#39;)
LINE_CHANNEL_SECRET = os.environ.get(&#39;LINE_CHANNEL_SECRET&#39;)
line_bot_api = LineBotApi(LINE_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(LINE_CHANNEL_SECRET)

@app.route(&quot;/&quot;, methods=[&#39;GET&#39;])
def hello():
    return &#39;hello heroku&#39;

@app.route(&quot;/callback&quot;, methods=[&#39;POST&#39;])
def callback():
    signature = request.headers[&#39;X-Line-Signature&#39;]
    body = request.get_data(as_text=True)

    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        print(&quot;Invalid signature. Please check your channel access token/channel secret.&quot;)
        abort(400)

    return &#39;OK&#39;

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=event.message.text))

if __name__ == &quot;__main__&quot;:
    app.run()
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-CZITh46DRin5S7CNH9uy5xQzUh7yKwaUd1cYEjZSBNrnKZeP12690ArUPVC80Ioh8KhMKkGQJNiggNSPINmjS5WacNFnQvhFnsaDuQB7cgk9vOZQi6olDjCEHiTNprNpBerLVux47Nw/s1600/20200315-008.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;917&quot; data-original-width=&quot;1299&quot; height=&quot;281&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-CZITh46DRin5S7CNH9uy5xQzUh7yKwaUd1cYEjZSBNrnKZeP12690ArUPVC80Ioh8KhMKkGQJNiggNSPINmjS5WacNFnQvhFnsaDuQB7cgk9vOZQi6olDjCEHiTNprNpBerLVux47Nw/s400/20200315-008.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 9&lt;/b&gt;：切換「iinfo7」虛擬環境，由於VSCode會自動偵測與載入虛擬環境，故可直接在VSCode進行切換虛擬環境操作。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfgvIJIx_DEQbwFFdYAoaFl4BulwNViTrSNkcufXZLKAD-egjT-l-vxIhg-wLIiQUXHqTdd8LOM1g-WeB-K2Kf2uPLo5tN_KJq6-KIrX_dMnLMT9tweA58YQOSuOJLMGbo7LTNKzACX7Y/s1600/20200315-009.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;789&quot; data-original-width=&quot;1255&quot; height=&quot;251&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfgvIJIx_DEQbwFFdYAoaFl4BulwNViTrSNkcufXZLKAD-egjT-l-vxIhg-wLIiQUXHqTdd8LOM1g-WeB-K2Kf2uPLo5tN_KJq6-KIrX_dMnLMT9tweA58YQOSuOJLMGbo7LTNKzACX7Y/s400/20200315-009.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 10&lt;/b&gt;：開啟終端機畫面。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigKipMyWk92BABW19VcjPXFcZRwZJZSggnmtDrDYTriRe__-x2_eHTzKWp-I0zO3bjhn3XA6RVPxgNw_NnT0-rhtqKK-VAKBri4cAWNI8qMlQR5y7FWzjn61kXr28tigCQYQqCEvRyw_s/s1600/20200315-010.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;789&quot; data-original-width=&quot;1084&quot; height=&quot;290&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigKipMyWk92BABW19VcjPXFcZRwZJZSggnmtDrDYTriRe__-x2_eHTzKWp-I0zO3bjhn3XA6RVPxgNw_NnT0-rhtqKK-VAKBri4cAWNI8qMlQR5y7FWzjn61kXr28tigCQYQqCEvRyw_s/s400/20200315-010.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 11&lt;/b&gt;：安裝line-bot-sdk v1.16.0，可使用以下兩種方法操作(任選一種即可)。&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;在「VSCode終端機」輸入指令安裝。&lt;/li&gt;
&lt;li&gt;在「命令提示字元」輸入指令安裝。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;brush:text&quot;&gt;pip install line-bot-sdk==1.16.0 
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDSs-VaAXJzeUH2IicNJOeBPpIbRZKFBekEXl4P7muG83vyXpAvtVow1_id9RGSd0kvs1QKvnhjFQLGYGpGbiXmCBiEpS-eZkLEDIjljaHav9eG5BI_jPxLK3rsjdgOa5MtTiJqktlexE/s1600/20200315-011.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;789&quot; data-original-width=&quot;1084&quot; height=&quot;290&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDSs-VaAXJzeUH2IicNJOeBPpIbRZKFBekEXl4P7muG83vyXpAvtVow1_id9RGSd0kvs1QKvnhjFQLGYGpGbiXmCBiEpS-eZkLEDIjljaHav9eG5BI_jPxLK3rsjdgOa5MtTiJqktlexE/s400/20200315-011.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 12&lt;/b&gt;：建立上傳至Heroku建置執行環境的文件。

&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;runtime.txt：指定Python版本。&lt;/li&gt;
&lt;li&gt;Procfile：在Heroku環境指定要執行的檔案。&lt;/li&gt;
&lt;li&gt;requirements.txt：將環境操作所需的套件與版本打包起來。&lt;/li&gt;
&lt;/ol&gt;
runtime.txt，輸入Heroku需要使用Python版本 python-3.6.2。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEis2IRhLTOfGNBEl4JpRKmGL1DKPBi1ZIKLzsCdYlJhB8b4EbcWR1p5M8FXM6MzfwdOEaRcO0-wJszKZSNb80OQH60FsQ94vB4yH7gzesGiWT5FDtMoGuHYgVP67ZpnnmBxYhR53GUPUME/s1600/20200315-012.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;789&quot; data-original-width=&quot;1084&quot; height=&quot;290&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEis2IRhLTOfGNBEl4JpRKmGL1DKPBi1ZIKLzsCdYlJhB8b4EbcWR1p5M8FXM6MzfwdOEaRcO0-wJszKZSNb80OQH60FsQ94vB4yH7gzesGiWT5FDtMoGuHYgVP67ZpnnmBxYhR53GUPUME/s400/20200315-012.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Procfile，輸入「web: gunicorn app:app –log-file -」，–log-file - 為打開顯示除錯訊息，若不想顯示除錯訊息可以使用「web: gunicorn app:app」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeWZZ5dn-Sm1Eyh8Ajtcd3CDngqKbgHGFuCwQmRgBsoNidOwdzAWs_8dZxHUo9OirV-GbRB-f4unshNUjEmwbuMFpSkaaphcjT0G4zAIFK7BIm7OsyxXA2HykFjGEVISxk4SBS8xh1DJs/s1600/20200315-013.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;789&quot; data-original-width=&quot;1084&quot; height=&quot;290&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeWZZ5dn-Sm1Eyh8Ajtcd3CDngqKbgHGFuCwQmRgBsoNidOwdzAWs_8dZxHUo9OirV-GbRB-f4unshNUjEmwbuMFpSkaaphcjT0G4zAIFK7BIm7OsyxXA2HykFjGEVISxk4SBS8xh1DJs/s400/20200315-013.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
requirements.txt，將虛擬環境「linebot」安裝的套件版本儲存起來，用來在 Heroku 雲端上安裝的套件佈署用，在「VSCode終端機」輸入。&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;pip freeze &amp;gt; requirements.txt
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHEFW2_yNwG_GA_LiXLy__Jo5wUVtZQoWCY6M74-ZbA6fAZImHNDRk3Erq8B2j008lq4Y4y66Ve-Y-jMyfokm8R_UOtsXvPiWaI1LxGuMhyphenhyphenVeKrP9-o-6-6-0MrLF0UwSZTlb44Mk_DSc/s1600/20200315-014.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;789&quot; data-original-width=&quot;1084&quot; height=&quot;290&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHEFW2_yNwG_GA_LiXLy__Jo5wUVtZQoWCY6M74-ZbA6fAZImHNDRk3Erq8B2j008lq4Y4y66Ve-Y-jMyfokm8R_UOtsXvPiWaI1LxGuMhyphenhyphenVeKrP9-o-6-6-0MrLF0UwSZTlb44Mk_DSc/s400/20200315-014.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 13&lt;/b&gt;：將新增文件加入到「 git 暫存區（Staging Area）」做檔案管理，可使用以下兩種方法操作(任選一種即可)。&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;在「VSCode終端機」輸入「git add .」，最後在「原始檔控制」頁籤，點擊「認可(Commit)」按鈕與加入「新增檔案」訊息，最後按下「Enter」。&lt;/li&gt;
&lt;li&gt;在「命令提示字元」輸入「git add .」，最後再輸入「git commit -a -m &quot;新增檔案&quot;」。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNC3X6jElrD3R8A7RPFsdK6oiGaIQ8uTiHZ_PPD21DU7snckH3bP_c_Gin8FiT4JQ8g4TQhYSJqti5XeND6PwLB8_5ADsj8TxESEny8GpTiG2MiQyolPlD8hWdz_M43obXOYUaqX17DVc/s1600/20200315-015.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;789&quot; data-original-width=&quot;1084&quot; height=&quot;290&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNC3X6jElrD3R8A7RPFsdK6oiGaIQ8uTiHZ_PPD21DU7snckH3bP_c_Gin8FiT4JQ8g4TQhYSJqti5XeND6PwLB8_5ADsj8TxESEny8GpTiG2MiQyolPlD8hWdz_M43obXOYUaqX17DVc/s400/20200315-015.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 14&lt;/b&gt;：到Heroku後台新增一個有效的app。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQcSIH3RsDNWRywJgVdl7z6juYCelET-I8CB_vFGgx578SaqssjlHIvlEFbwYe0DhMbFiY7_V4Iua2dqJcoEdzroiKT6naGYH_8v3BC-vvcLC_oKgS_AdDtbDNtsvVPGYRovJ5EASXuB0/s1600/20200315-016.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;639&quot; data-original-width=&quot;716&quot; height=&quot;356&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQcSIH3RsDNWRywJgVdl7z6juYCelET-I8CB_vFGgx578SaqssjlHIvlEFbwYe0DhMbFiY7_V4Iua2dqJcoEdzroiKT6naGYH_8v3BC-vvcLC_oKgS_AdDtbDNtsvVPGYRovJ5EASXuB0/s400/20200315-016.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvV2Ohgy8JtEZAdWxMZDCZpwVTC6VsGTj1zQOh6Aq-M_CEjSpHmR53b62_RVqeB_GM_rft4UD4px5_5-GXUpvRuoWROdvOZH7qLFt-aOD7UYtiARLEWUAhJwmo4-YFHbLBVmTQilJjksM/s1600/20200315-017.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;639&quot; data-original-width=&quot;716&quot; height=&quot;356&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvV2Ohgy8JtEZAdWxMZDCZpwVTC6VsGTj1zQOh6Aq-M_CEjSpHmR53b62_RVqeB_GM_rft4UD4px5_5-GXUpvRuoWROdvOZH7qLFt-aOD7UYtiARLEWUAhJwmo4-YFHbLBVmTQilJjksM/s400/20200315-017.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjugt5X2PElNV1A1KQH1mqEB9X6k49CikddF_AKTcXlIoBLnKFV2znB6l8CCjKPcK4ZsNbLqR1ZspG-BHqusNGWVo6EIcMcG6Pnn5btRzAD4ozM1BJWmOqUx1u9kk7XwMWv_5hfp8J58BY/s1600/20200315-018.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;902&quot; data-original-width=&quot;831&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjugt5X2PElNV1A1KQH1mqEB9X6k49CikddF_AKTcXlIoBLnKFV2znB6l8CCjKPcK4ZsNbLqR1ZspG-BHqusNGWVo6EIcMcG6Pnn5btRzAD4ozM1BJWmOqUx1u9kk7XwMWv_5hfp8J58BY/s400/20200315-018.png&quot; width=&quot;367&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 15&lt;/b&gt;：登入Heroku，可使用以下兩種方法操作(任選一種即可)。&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;在「VSCode終端機」輸入以下指令，再輸入登入「Heroku」帳密。&lt;/li&gt;
&lt;li&gt;在「命令提示字元」輸入以下指令，再輸入登入「Heroku」帳密。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;brush:text&quot;&gt;heroku login -i
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAqlX4W8PqHX0Ww8sHtQC5iaMz9V5PsLsn0eodZjqHvOp5Vfk3Gc2vG3wqUbhWti_xQe3gCvr2oB6SguLLq1YG34i2q_YqLgNHX1_qsQhwOn2iMV1JPX956sBGAovoYEFdd8SeixozAW0/s1600/20200315-019.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;789&quot; data-original-width=&quot;1084&quot; height=&quot;290&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAqlX4W8PqHX0Ww8sHtQC5iaMz9V5PsLsn0eodZjqHvOp5Vfk3Gc2vG3wqUbhWti_xQe3gCvr2oB6SguLLq1YG34i2q_YqLgNHX1_qsQhwOn2iMV1JPX956sBGAovoYEFdd8SeixozAW0/s400/20200315-019.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 16&lt;/b&gt;：切換在 Heroku 新建的app，可使用以下兩種方法操作(任選一種即可)。&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;在「VSCode終端機」輸入以下指令。&lt;/li&gt;
&lt;li&gt;在「命令提示字元」輸入以下指令。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;brush:text&quot;&gt;heroku git:remote -a [app名稱]
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-2H7aeRoetQWLKxAiwzaP3nlb42ZXQ3NA8HGzM0i9HDI7K0yjvYfB4YDgBypcAXo42Blr61emP7vFX5jRITWXjw5Jcy36Mzg59ep6OmMTZgaopb5mj8kWwMUhuXKzx8Ce_lOjqy8Oj_k/s1600/20200315-020.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;789&quot; data-original-width=&quot;1084&quot; height=&quot;290&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-2H7aeRoetQWLKxAiwzaP3nlb42ZXQ3NA8HGzM0i9HDI7K0yjvYfB4YDgBypcAXo42Blr61emP7vFX5jRITWXjw5Jcy36Mzg59ep6OmMTZgaopb5mj8kWwMUhuXKzx8Ce_lOjqy8Oj_k/s400/20200315-020.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 17&lt;/b&gt;：將虛擬環境「iinfo7」所有的檔案推上至 Heroku進行佈署，可使用以下兩種方法操作(任選一種即可)。&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;在「VSCode終端機」輸入以下指令。&lt;/li&gt;
&lt;li&gt;在「命令提示字元」輸入以下指令。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;brush:text&quot;&gt;git push heroku master
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjezArVbpnZmkwHHV9AeQjsPE4qA1Nc03xoC82eabRjnf3Pe1pZrEpJqrpg-KvdbMov69S7za7nbKNhQ5s-ydxoU7eaakQDBkk9Txei3cueEVwoe_aKyCUEvTYT0S7jmZsz78A26wtS4bc/s1600/20200315-021.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;789&quot; data-original-width=&quot;1084&quot; height=&quot;290&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjezArVbpnZmkwHHV9AeQjsPE4qA1Nc03xoC82eabRjnf3Pe1pZrEpJqrpg-KvdbMov69S7za7nbKNhQ5s-ydxoU7eaakQDBkk9Txei3cueEVwoe_aKyCUEvTYT0S7jmZsz78A26wtS4bc/s400/20200315-021.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGzHcSS_FukZX89jWY0D8HvafA2iUl8fCqbRFjsDStzcOFP_GX1vcAUpFg6RZc0GaMQUhXpThNEaPWztKWEjnQDfTzmZ87xc89i75LGS76SmiVEuKgkadWVcasF4k2Q5UK-PgZI6f7uJQ/s1600/20200315-022.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;789&quot; data-original-width=&quot;1084&quot; height=&quot;290&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGzHcSS_FukZX89jWY0D8HvafA2iUl8fCqbRFjsDStzcOFP_GX1vcAUpFg6RZc0GaMQUhXpThNEaPWztKWEjnQDfTzmZ87xc89i75LGS76SmiVEuKgkadWVcasF4k2Q5UK-PgZI6f7uJQ/s400/20200315-022.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 18&lt;/b&gt;：在&amp;nbsp;&lt;a href=&quot;https://developers.line.biz/zh-hant/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Line Developers&lt;/a&gt;&amp;nbsp;後台，設定「Webhook URL」與取得「Channel secret」、「Channel access token」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNdfm_ynnl81zGb-6PdRfyRSpn34i3TDLoCIogvXzTTaYZ9EnH-rZM-cki0CQ1RrmqDRDuP7uDzbMlC1adi11p659dQcCyBmvUr8cxsGM9rlOgO-gHqxaEOzepVGSFOUlF5XdKsUKTMno/s1600/20200315-023.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;373&quot; data-original-width=&quot;640&quot; height=&quot;232&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNdfm_ynnl81zGb-6PdRfyRSpn34i3TDLoCIogvXzTTaYZ9EnH-rZM-cki0CQ1RrmqDRDuP7uDzbMlC1adi11p659dQcCyBmvUr8cxsGM9rlOgO-gHqxaEOzepVGSFOUlF5XdKsUKTMno/s400/20200315-023.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟19&lt;/b&gt;：&amp;nbsp;&lt;a href=&quot;https://developers.line.biz/zh-hant/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Line Developers&lt;/a&gt;&amp;nbsp;後台取得「Channel secret」、「Channel access token」，到 heroku 後台帳號的「Settings」頁籤的「Config Vars」進行「LINE_CHANNEL_ACCESS_TOKEN」、「LINE_CHANNEL_SECRET」設定。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGKuU8jrRir_rhYOuJJDnBrR2fZOXO8Z0olsE_84WGBp2jUcDMaMuR_3LOi7MSYBQBdFMO_VteXX1LAxeo46EMXKCoSJ242ZvDrBIw8emxDc0f_UAsOanaKigQtGbi6ahsDcw2CrzdrL8/s1600/20200315-024.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;256&quot; data-original-width=&quot;956&quot; height=&quot;106&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGKuU8jrRir_rhYOuJJDnBrR2fZOXO8Z0olsE_84WGBp2jUcDMaMuR_3LOi7MSYBQBdFMO_VteXX1LAxeo46EMXKCoSJ242ZvDrBIw8emxDc0f_UAsOanaKigQtGbi6ahsDcw2CrzdrL8/s400/20200315-024.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟20&lt;/b&gt;：最後將Line Bot加入進行測試。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCukPEBAL71TgYFuAo3gnE9-97DuMV8aSuOvLtTr939WqCePThQK-S6FPbJRsrI5X7MbDEcGI8Vye-GGWyQRgrqanAH8BN-R73gkJLQfSXkT8bCeF6O4hwJE9H6RHTwCL40iaKguP1Q7I/s1600/20200315-2.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;879&quot; data-original-width=&quot;1439&quot; height=&quot;243&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCukPEBAL71TgYFuAo3gnE9-97DuMV8aSuOvLtTr939WqCePThQK-S6FPbJRsrI5X7MbDEcGI8Vye-GGWyQRgrqanAH8BN-R73gkJLQfSXkT8bCeF6O4hwJE9H6RHTwCL40iaKguP1Q7I/s400/20200315-2.gif&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
測試不成功的原因與注意事項：&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;測試「Webhook URL」，建議先將41~45行的程式碼移除，重新推code到Heroku上，再進行驗證，待「Webhook URL」驗證成功後，再還原程式碼，並且重新再一次推code至Heroku。&lt;/li&gt;
&lt;li&gt;「Webhook URL」在測試成功之前，「Use webhook」都會是關閉狀態，若「Webhook URL」測試成功後，「Use webhook」開起才能順利。&lt;/li&gt;
&lt;li&gt;「Webhook URL」在測試成功之前，每次填入的URL都不會被儲存起來，所以要先讓「Webhook URL」測試可以成功。&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/2489124422235006509/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2020/03/heroku-flask-python3line-botheroku.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/2489124422235006509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/2489124422235006509'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2020/03/heroku-flask-python3line-botheroku.html' title='Heroku + Flask + Python應用(3)：快速建立Line Bot，至Heroku佈署'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQYBsmnduMfLsYaR_XCaJfJua9cQbir0jTRn__wLfORfDuEmMa1xu7LTdQp4-6m84kunkFTjb-MFGpPvLA4ZojudCWlYlXAIAqqPs7wX8jG9oAn48g_FkpJTk8a3E83thmctxkG2HKUuM/s72-c/20200315-001.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-8130482869696479700</id><published>2020-03-12T18:54:00.000-07:00</published><updated>2020-03-15T03:20:32.450-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Flask"/><category scheme="http://www.blogger.com/atom/ns#" term="Heroku"/><category scheme="http://www.blogger.com/atom/ns#" term="Line"/><category scheme="http://www.blogger.com/atom/ns#" term="Line Bot"/><category scheme="http://www.blogger.com/atom/ns#" term="Line Messaging API"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Heroku + Flask + Python應用(2)：VSCode建置Line Bot，上傳Heroku佈署</title><content type='html'>距離前一篇&amp;nbsp;&lt;a href=&quot;http://white5168.blogspot.com/2019/06/vscodepythonflaskheroku.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Heroku + Flask + Python應用(1)：Heroku上執行Flask 網站&lt;/a&gt; 文章發佈到現在約9個月多的時間，今在以相同的操作方式建置 Line Bot 在 Heroku 進行介紹佈署方式。
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;b&gt;步驟 1&lt;/b&gt;：在本機端佈屬環境。&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;請至 Heroku&amp;nbsp; &lt;a href=&quot;https://id.heroku.com/login&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://id.heroku.com/login&lt;/a&gt; 註冊一個帳號。&lt;/li&gt;
&lt;li&gt;下載安裝 Heroku CLI &lt;a href=&quot;https://devcenter.heroku.com/articles/heroku-cli&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://devcenter.heroku.com/articles/heroku-cli&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;下載安裝 Git &lt;a href=&quot;https://git-scm.com/downloads&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://git-scm.com/downloads&lt;/a&gt;，上傳檔案到 Heroku 使用。&lt;/li&gt;
&lt;li&gt;下載安裝VSCode &lt;a href=&quot;https://code.visualstudio.com/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://code.visualstudio.com/&lt;/a&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;b&gt;步驟 2&lt;/b&gt;：開啟「命令提示字元」輸入以下指令，建立Code資料夾，用 conda 建立「linebot」虛擬環境。
&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;cd /
mkdir Code
cd Code
conda create -n linebot python=3.6.2
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHfIATEu_hQJ2ZYO8gu01fNdZaXc_EVhJDr1T46rifXLKvXnZOHjYDzKFScrCaArqwjnDPVWLbkA9Azn_POwFyHPO1MjyvolvX-2X2IJ3owuMlH4oH4ReuwJ-tKRTj0mzItqh2HgeL3Wk/s1600/20200313-001.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;515&quot; data-original-width=&quot;669&quot; height=&quot;307&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHfIATEu_hQJ2ZYO8gu01fNdZaXc_EVhJDr1T46rifXLKvXnZOHjYDzKFScrCaArqwjnDPVWLbkA9Azn_POwFyHPO1MjyvolvX-2X2IJ3owuMlH4oH4ReuwJ-tKRTj0mzItqh2HgeL3Wk/s400/20200313-001.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9_hcFsIGNtEzwVYIdBcr4CmRFEUnwqDoSAwKXgvVHYVtqvYaLjhUYJKqepyUDG-LkM2AwslAMr3ogSRh1cexpMV40rRbR9XISQCBei7PhHnAust2Yah67KL_Yvsd3WTbuveq8pdWtAOA/s1600/20200313-002.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;675&quot; data-original-width=&quot;669&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9_hcFsIGNtEzwVYIdBcr4CmRFEUnwqDoSAwKXgvVHYVtqvYaLjhUYJKqepyUDG-LkM2AwslAMr3ogSRh1cexpMV40rRbR9XISQCBei7PhHnAust2Yah67KL_Yvsd3WTbuveq8pdWtAOA/s400/20200313-002.png&quot; width=&quot;396&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 3&lt;/b&gt;：完成建立「linebot」虛擬環境後，進入「linebot」環境。

&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;activate linebot
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-ZYfGH1IME4ZKApf6u-n7gQLHy34vlcEvpTjgOm9fDRxvrOYmPYTUVAAXOKCG6VZ6KRb3_J8Nbh8WTjf0GmxLRt18I5-xjI-Dxmxa8YLYaaKUB3Jl22IIZPkhGUo9xzyRslT7OBh3Mlw/s1600/20200313-003.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;435&quot; data-original-width=&quot;669&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-ZYfGH1IME4ZKApf6u-n7gQLHy34vlcEvpTjgOm9fDRxvrOYmPYTUVAAXOKCG6VZ6KRb3_J8Nbh8WTjf0GmxLRt18I5-xjI-Dxmxa8YLYaaKUB3Jl22IIZPkhGUo9xzyRslT7OBh3Mlw/s400/20200313-003.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 4&lt;/b&gt;：在「命令提示字元」輸入「git init」，產生「.git」資料夾，「Code」資料夾所有檔案用git做管理。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcDeeNZu3e-nFNipDcmg1CAZIi1rTCvh-Wyj1YHkpx5m3slFLN4cH5_G9v93rR0Jzj3aLJ8tsst3_j4HM2XNFDJD4Ugs2EiIgiWj3bnSGYNkPXHeuQzF-OmAuZYxY0FMDL2ijzzf_l6Yk/s1600/20200313-004.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;435&quot; data-original-width=&quot;669&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcDeeNZu3e-nFNipDcmg1CAZIi1rTCvh-Wyj1YHkpx5m3slFLN4cH5_G9v93rR0Jzj3aLJ8tsst3_j4HM2XNFDJD4Ugs2EiIgiWj3bnSGYNkPXHeuQzF-OmAuZYxY0FMDL2ijzzf_l6Yk/s400/20200313-004.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzGscDVlUSsMvg82JWM8XbMIXYVF088g2PlXYUyCTKHv36dUMB8QIWQWJcPqg1mPdvwYdmh_2dIIcPSfYRahw_Jo0FvA0dZdoyc7OzzDD7dKXCriebfFDJT7qe3BG1Cx5RDS_xBJfSCe8/s1600/20200313-005.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;435&quot; data-original-width=&quot;669&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzGscDVlUSsMvg82JWM8XbMIXYVF088g2PlXYUyCTKHv36dUMB8QIWQWJcPqg1mPdvwYdmh_2dIIcPSfYRahw_Jo0FvA0dZdoyc7OzzDD7dKXCriebfFDJT7qe3BG1Cx5RDS_xBJfSCe8/s400/20200313-005.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 5&lt;/b&gt;：在「命令提示字元」輸入「pip list」查詢在虛擬環境「linebot」中，有已安裝的套件與其版本。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEio_er-uq9fNr4t2AaE6X8E6ak9TgxBSyNfKcFRhpU6eDsDVSyQcUQRI5w6NBso-8lJqTtJ2sSu_49O9-FNIszJhiH_Wv7JmES3kgsJyQERPfaXm29M_nnT41p7onh2vQZFnbrMJQyvc0g/s1600/20200313-006.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;435&quot; data-original-width=&quot;669&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEio_er-uq9fNr4t2AaE6X8E6ak9TgxBSyNfKcFRhpU6eDsDVSyQcUQRI5w6NBso-8lJqTtJ2sSu_49O9-FNIszJhiH_Wv7JmES3kgsJyQERPfaXm29M_nnT41p7onh2vQZFnbrMJQyvc0g/s400/20200313-006.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 6&lt;/b&gt;：安裝「flask」、「gunicorn」到「linebot」環境中，後面操作時會使用到。
&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;pip install flask gunicorn
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn3nbU13dzo_puhdAi8rNhjfeRhOiym3Xn4ejbpwYIv8mLz12hpJnaNUS4a0B1eXmwPAL9BhPcnIXRQ43sez7b_GFoIkWAJ0ziAsmJF1DHxsKL0ErwyGM7A5cr11UNIP3nWhj3S3-o1sQ/s1600/20200313-007.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;435&quot; data-original-width=&quot;669&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn3nbU13dzo_puhdAi8rNhjfeRhOiym3Xn4ejbpwYIv8mLz12hpJnaNUS4a0B1eXmwPAL9BhPcnIXRQ43sez7b_GFoIkWAJ0ziAsmJF1DHxsKL0ErwyGM7A5cr11UNIP3nWhj3S3-o1sQ/s400/20200313-007.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizj9-gRAORheLRtQ7oOF2-zcQF1KUQlUkKNMt4ciAlf6AESVn0bnHjqQzuhzGp0ZTyellJGLMnvX_qxoo0EBtwORS0woBzs7RE_Ml3lT2bYfuhPtc910XKQTqPa_iXgZSrj0Wlw7lXEQ8/s1600/20200313-008.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;435&quot; data-original-width=&quot;669&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizj9-gRAORheLRtQ7oOF2-zcQF1KUQlUkKNMt4ciAlf6AESVn0bnHjqQzuhzGp0ZTyellJGLMnvX_qxoo0EBtwORS0woBzs7RE_Ml3lT2bYfuhPtc910XKQTqPa_iXgZSrj0Wlw7lXEQ8/s400/20200313-008.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 7&lt;/b&gt;：在「命令提示字元」輸入「code .」開啟 VSCode。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLHXAw9uJzyNVY2wk-FKUN_3e-n75X-ZSHV9EmRcNFPC-Mcat_DXvcI2MYR9GiJ2btyiqkapSI20W4WrQBL1pjmDT9H_3cBlsTRFOkbWNLItDL9Eq-tVTuMlNUlqXEfp0ALyZLHaL37vM/s1600/20200313-009.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;435&quot; data-original-width=&quot;669&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLHXAw9uJzyNVY2wk-FKUN_3e-n75X-ZSHV9EmRcNFPC-Mcat_DXvcI2MYR9GiJ2btyiqkapSI20W4WrQBL1pjmDT9H_3cBlsTRFOkbWNLItDL9Eq-tVTuMlNUlqXEfp0ALyZLHaL37vM/s400/20200313-009.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 8&lt;/b&gt;：在 VScode 安裝 Python外掛套件，用來讓VSCode能做 Python。
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;點擊「Extensions」。&lt;/li&gt;
&lt;li&gt;輸入「Python」尋找。&lt;/li&gt;
&lt;li&gt;點擊「Install」安裝。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGCbNjKiY0ZnhQh8vHCgFkmdqUBENLN1WKc_phNZPD41iypu9s0e475OQN2RAHExqGkC_CxR6wL8NvNHaKro0rjIogN4IGIfOBbtgEm9o730AfFUjKOXcnVGP9PP-_uscGBi4T2PDd1rM/s1600/20200313-010.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;731&quot; data-original-width=&quot;992&quot; height=&quot;293&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGCbNjKiY0ZnhQh8vHCgFkmdqUBENLN1WKc_phNZPD41iypu9s0e475OQN2RAHExqGkC_CxR6wL8NvNHaKro0rjIogN4IGIfOBbtgEm9o730AfFUjKOXcnVGP9PP-_uscGBi4T2PDd1rM/s400/20200313-010.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 9&lt;/b&gt;：透過VSCode 建立Python 檔案。
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;切換「檔案總管」頁籤。&lt;/li&gt;
&lt;li&gt;點擊「檔案」。&lt;/li&gt;
&lt;li&gt;點擊「新增檔案」。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi622mgPjqvRbNo6q2-32EqwTdrr1aI1dq9ulpmqGSpDrg1zAZYOS5GMOaMxLFahq8o3RvepnfzEE0JiVA_9Qnqr2VRyk4gwOi7e4h0C1VVdYLzAqyGuAAkz8qntT_PnlhaFDttv9Y2I2k/s1600/20200313-011.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;731&quot; data-original-width=&quot;992&quot; height=&quot;293&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi622mgPjqvRbNo6q2-32EqwTdrr1aI1dq9ulpmqGSpDrg1zAZYOS5GMOaMxLFahq8o3RvepnfzEE0JiVA_9Qnqr2VRyk4gwOi7e4h0C1VVdYLzAqyGuAAkz8qntT_PnlhaFDttv9Y2I2k/s400/20200313-011.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 10&lt;/b&gt;：切換成Python開發環境。
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;修改直譯器。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbRV2CPZXDXIZrXSh_Zbt94xtdgcQoQllB1rGLcQ6Vi1JB12ofdtEzCturePPkV3U_6JUFEwlG2uKMzX27_omrlkZFfxgtz6yFKMwdXlDlX2xh3xJWoP1M7oJlzxpfVlddAwupN1TNLCs/s1600/20200313-013.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;759&quot; data-original-width=&quot;995&quot; height=&quot;305&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbRV2CPZXDXIZrXSh_Zbt94xtdgcQoQllB1rGLcQ6Vi1JB12ofdtEzCturePPkV3U_6JUFEwlG2uKMzX27_omrlkZFfxgtz6yFKMwdXlDlX2xh3xJWoP1M7oJlzxpfVlddAwupN1TNLCs/s400/20200313-013.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;切換成虛擬環境「linebot」。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9OrpMgBZ-dW8uC5-yq3o2LAm3IQqAK2O6Y3FGUs8g5qpKwyFvaWXZyU6-70_jKopb17JT2FSrWkLIbmmJv1X51GyMCJKWK0VlEp2k78mB59flMO6enUA3Pm8IVz7ljZSxZiJcff08VnY/s1600/20200313-015.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;783&quot; data-original-width=&quot;995&quot; height=&quot;313&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9OrpMgBZ-dW8uC5-yq3o2LAm3IQqAK2O6Y3FGUs8g5qpKwyFvaWXZyU6-70_jKopb17JT2FSrWkLIbmmJv1X51GyMCJKWK0VlEp2k78mB59flMO6enUA3Pm8IVz7ljZSxZiJcff08VnY/s400/20200313-015.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
修改檔案編輯使用的程式。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcOyp8mj-0-tCI4_la3oj2bKO1YmpRghjo6vm1VQXhrHlCYJZQ2OZgF9vMljujuI7fhuRjtyEy08-seE_BHhUNZ_97EJILhWn2hFhpCclMr98AkKFLsmn2Rn9AiHv0VllAWqh-fRdC7bw/s1600/20200313-012.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;731&quot; data-original-width=&quot;992&quot; height=&quot;293&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcOyp8mj-0-tCI4_la3oj2bKO1YmpRghjo6vm1VQXhrHlCYJZQ2OZgF9vMljujuI7fhuRjtyEy08-seE_BHhUNZ_97EJILhWn2hFhpCclMr98AkKFLsmn2Rn9AiHv0VllAWqh-fRdC7bw/s400/20200313-012.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 11&lt;/b&gt;：輸入以下程式碼，存成 app.py。
&lt;br /&gt;
&lt;pre class=&quot;brush:py&quot;&gt;import os

from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)

from linebot.exceptions import (
    InvalidSignatureError
)

from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)

app = Flask(__name__)

LINE_CHANNEL_ACCESS_TOKEN = os.environ.get(&#39;LINE_CHANNEL_ACCESS_TOKEN&#39;)
LINE_CHANNEL_SECRET = os.environ.get(&#39;LINE_CHANNEL_SECRET&#39;)
line_bot_api = LineBotApi(LINE_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(LINE_CHANNEL_SECRET)

@app.route(&quot;/&quot;, methods=[&#39;GET&#39;])
def hello():
    return &#39;hello heroku&#39;

@app.route(&quot;/callback&quot;, methods=[&#39;POST&#39;])
def callback():
    signature = request.headers[&#39;X-Line-Signature&#39;]
    body = request.get_data(as_text=True)

    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        print(&quot;Invalid signature. Please check your channel access token/channel secret.&quot;)
        abort(400)

    return &#39;OK&#39;

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=event.message.text))

if __name__ == &quot;__main__&quot;:
    app.run()
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhb4fhEgi2-ZH6OO9yxwm_o3roDcSNOA8T1QkRSrSFGiyoEieWXD2idwCjYe4ZfbwoefP4lNL6Xi8__VaK636-WuE3iUfTDJkVXGYjMsBbrUigELD_F1FWqylpkHLQnBArgOP1YVzr5LgI/s1600/20200313-014.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1040&quot; data-original-width=&quot;995&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhb4fhEgi2-ZH6OO9yxwm_o3roDcSNOA8T1QkRSrSFGiyoEieWXD2idwCjYe4ZfbwoefP4lNL6Xi8__VaK636-WuE3iUfTDJkVXGYjMsBbrUigELD_F1FWqylpkHLQnBArgOP1YVzr5LgI/s400/20200313-014.png&quot; width=&quot;382&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 12&lt;/b&gt;：由於資料夾中有新增檔案，且這些檔案未被git列入管理，因此在VSCode上會顯示&amp;nbsp;「U」，代表檔案處於「Untracked」的狀態，將檔案加入local repository，後續再加入 github 中。&lt;br /&gt;
在VSCode終端機中輸入「git add .」，將檔案加入管理。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFBvFbAguqShaU17Kchz6qhMIsaRbDVzt1-dHE3unAJUz4nEkSNKC3INL36BBa_LyQfN3fwOXwYKX5AhoxP-4cHOo39q1Jj9Ggt1WCjkPaqe5vmnqSJjGvaeNU6R2yhI_xW42Y4MQvoYU/s1600/20200313-016.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;783&quot; data-original-width=&quot;995&quot; height=&quot;313&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFBvFbAguqShaU17Kchz6qhMIsaRbDVzt1-dHE3unAJUz4nEkSNKC3INL36BBa_LyQfN3fwOXwYKX5AhoxP-4cHOo39q1Jj9Ggt1WCjkPaqe5vmnqSJjGvaeNU6R2yhI_xW42Y4MQvoYU/s400/20200313-016.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
檔案加入管理後，VSCode的狀態會從「U」變成「A」，代表檔案「被新增」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyIRzlQxGra2E0oakDnwWsSB5hAGmaJ6P67-YTBqj6RhPblY3nXqTrOb4jynU13soBuvv3bAx3LKW5ypKBlzLrEs1uMSpgAD-4jH6i7FubkJjB5LFr2FbVHwqeBFl7ypxlRrIhubFsIrc/s1600/20200313-017.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;783&quot; data-original-width=&quot;995&quot; height=&quot;313&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyIRzlQxGra2E0oakDnwWsSB5hAGmaJ6P67-YTBqj6RhPblY3nXqTrOb4jynU13soBuvv3bAx3LKW5ypKBlzLrEs1uMSpgAD-4jH6i7FubkJjB5LFr2FbVHwqeBFl7ypxlRrIhubFsIrc/s400/20200313-017.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
除了上述兩個狀態，VSCode的其他狀態。&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;M是Modified，檔案狀態是「有做修改的」。&lt;/li&gt;
&lt;li&gt;D是Deleted，檔案狀態是「被刪除的」。&lt;/li&gt;
&lt;/ol&gt;
&lt;b&gt;步驟 13&lt;/b&gt;：檔案存入local repository中。&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;最後點擊「打勾」完成「認可(Commit)Commit」。&lt;/li&gt;
&lt;li&gt;輸入「認可(Commit)」訊息。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8cnUSJqy0JKYEE5P9RtBIT7SiBqGJg8GZkZSrdnFVyMg4aXtUuBdSCyamykJdPd40wSScF0SJ7-SapBVPW9gqOVAUo66kKExjHk20dY45KsFzfoeh0dMNZBCJt7qMwtKl9OEk3Ya_UrM/s1600/20200313-018.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;783&quot; data-original-width=&quot;1152&quot; height=&quot;271&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8cnUSJqy0JKYEE5P9RtBIT7SiBqGJg8GZkZSrdnFVyMg4aXtUuBdSCyamykJdPd40wSScF0SJ7-SapBVPW9gqOVAUo66kKExjHk20dY45KsFzfoeh0dMNZBCJt7qMwtKl9OEk3Ya_UrM/s400/20200313-018.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
注意，若未登入Git使用者操作資訊，將出現以下提示。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOSTpLCXlUIJlIxuEPewGshGBVvIFyF5w2CIlqVYPxLiNSe4PABCYVSMN8fASKlyN3o_523WnpG_RoAXeRG5EaSERPeS_AN_iH3HZn5XkPOi7SDGTkUhTldxvOcOfnSUWPkJ-pIYiD7cs/s1600/20190603-10.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;145&quot; data-original-width=&quot;527&quot; height=&quot;110&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOSTpLCXlUIJlIxuEPewGshGBVvIFyF5w2CIlqVYPxLiNSe4PABCYVSMN8fASKlyN3o_523WnpG_RoAXeRG5EaSERPeS_AN_iH3HZn5XkPOi7SDGTkUhTldxvOcOfnSUWPkJ-pIYiD7cs/s400/20190603-10.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
請在「命令提示字元」下輸入 git所需相關資訊。&lt;br /&gt;
git config --global user.email &quot;you@example.com&quot;&lt;br /&gt;
git config --global user.name &quot;Your Name&quot;&lt;br /&gt;
&lt;br /&gt;
完成「認可(Commit)」後，VSCode左側畫面就會顯示剛剛輸入的程式碼，這表示app.py的檔案已存進local repository中。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0Pg-XLJTQ5nr9yr4bqH-o_9_aSqIKbPbFQloPD2o2bRxHoCKz3hrsqvwrRWjruwfqKGLSF-_d4oC7ztP9XiDdUo16iJ1gf7ZhlgJslBn6wzPaYZzdJyrBL1PcB1kL_-patWVLKTPeg0o/s1600/20200313-019.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;783&quot; data-original-width=&quot;1152&quot; height=&quot;271&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0Pg-XLJTQ5nr9yr4bqH-o_9_aSqIKbPbFQloPD2o2bRxHoCKz3hrsqvwrRWjruwfqKGLSF-_d4oC7ztP9XiDdUo16iJ1gf7ZhlgJslBn6wzPaYZzdJyrBL1PcB1kL_-patWVLKTPeg0o/s400/20200313-019.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 14&lt;/b&gt;：在「命令提示字元」輸入指令，安裝line-bot-sdk v1.16.0 套件。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj70NCMZhjEJnpRYzBQrXh8CUYgxRSqdl9Hx4kVT5oubQs7p_r_zZDc-kLUmNXEfvgZaByAEpB8dciEgk3LZ-6tPtfTRDPaskN-muIxghaBRz9s0aJWfMuKNlJIYUQvLD5_Sjyoen09lQc/s1600/20200313-020.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;435&quot; data-original-width=&quot;669&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj70NCMZhjEJnpRYzBQrXh8CUYgxRSqdl9Hx4kVT5oubQs7p_r_zZDc-kLUmNXEfvgZaByAEpB8dciEgk3LZ-6tPtfTRDPaskN-muIxghaBRz9s0aJWfMuKNlJIYUQvLD5_Sjyoen09lQc/s400/20200313-020.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGumFBeIghkq0DWmEY9UmsUAUmEs3glIVKORLzSZ1sEsXM__zNXjpH_qVAdWgbrwVGqlnwJ-IZVCVTLpSnTjSxFxNa6KojWVZpal_O3B_zF1MuNrEAMcWnpgnj0RbKwCGiMbKyUZkwfwY/s1600/20200313-021.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;435&quot; data-original-width=&quot;669&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGumFBeIghkq0DWmEY9UmsUAUmEs3glIVKORLzSZ1sEsXM__zNXjpH_qVAdWgbrwVGqlnwJ-IZVCVTLpSnTjSxFxNa6KojWVZpal_O3B_zF1MuNrEAMcWnpgnj0RbKwCGiMbKyUZkwfwY/s400/20200313-021.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 15&lt;/b&gt;：執行程式碼，將程式第19、20行暫時做修改調整(為了測試使用)，接著在程式碼空白處點擊滑鼠右鍵，選擇「在終端機執行Python檔案」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6lLv9wfcLNk3UE6JGo7UjR36Y2T1gdwqnt2WHEIrXf8m7UzIGNT8GH6JrP9YvtNMfvWrjIBxvHnxxGh9FdZpHVMsur-CzxvaH5hT2dvYOMKck28c-qBfb7FB2w7Gkfr-55FC-xX9uCgM/s1600/20200313-022.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;783&quot; data-original-width=&quot;1168&quot; height=&quot;267&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6lLv9wfcLNk3UE6JGo7UjR36Y2T1gdwqnt2WHEIrXf8m7UzIGNT8GH6JrP9YvtNMfvWrjIBxvHnxxGh9FdZpHVMsur-CzxvaH5hT2dvYOMKck28c-qBfb7FB2w7Gkfr-55FC-xX9uCgM/s400/20200313-022.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
注意：若遇到無法成功執行，顯示「ModuleNotFoundError: No module named &#39;flask&#39;」，請回到步驟6安裝 Flask 套件。&lt;br /&gt;
若正常執行，會提示網頁開啟的URL位置 http://127.0.0.1:5000/，Port 5000 是 flask 預設。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIup4KcvCyPEwObUemU8e01fJjc7tTzFoeBKozwQWZ7cKPDkf1WU37FKHwg5Y8Fo9den3u-NEmp17hm81OrMGG48YIkW-01JzLuu7nmJYuhpfzsbH1H4DIQnGaG0yu0NQQtXW6TbE9fOU/s1600/20200313-023.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;783&quot; data-original-width=&quot;1168&quot; height=&quot;267&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIup4KcvCyPEwObUemU8e01fJjc7tTzFoeBKozwQWZ7cKPDkf1WU37FKHwg5Y8Fo9den3u-NEmp17hm81OrMGG48YIkW-01JzLuu7nmJYuhpfzsbH1H4DIQnGaG0yu0NQQtXW6TbE9fOU/s400/20200313-023.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
開啟瀏覽器輸入 http://127.0.0.1:5000/ 可見到成功畫面，測試成功後，準備建立上傳Heroku的文件。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8Tv8oxZl4KtMrI4jc45W6ZA93fgF_lXrDCRPp2Wtmr7ZlzSoLXJxxhrzZ8QGfQvV9-M3AsgENvuue1yLmW-yf8tojnWt60DltvY3bBC_0_Qi2vrO8qdJAXlu-ZhRBNKtRsN9qc9eMoD0/s1600/20200313-024.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;420&quot; data-original-width=&quot;573&quot; height=&quot;292&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8Tv8oxZl4KtMrI4jc45W6ZA93fgF_lXrDCRPp2Wtmr7ZlzSoLXJxxhrzZ8QGfQvV9-M3AsgENvuue1yLmW-yf8tojnWt60DltvY3bBC_0_Qi2vrO8qdJAXlu-ZhRBNKtRsN9qc9eMoD0/s400/20200313-024.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 16&lt;/b&gt;：建立上傳至Heroku建置執行環境的文件。&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;runtime.txt：指定Python版本。&lt;/li&gt;
&lt;li&gt;Procfile：在Heroku環境指定要執行的檔案。&lt;/li&gt;
&lt;li&gt;requirements.txt：將環境操作所需的套件與版本打包起來。&lt;/li&gt;
&lt;/ol&gt;
runtime.txt，輸入Heroku需要使用Python版本 python-3.6.2。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWgSOTY3AhfITwrkBK7W_Uk_AzxmNGFyzHd2-fRzMavR4-ob5dk9EMIh1FPtFdYQwTBUPmR6mSiyiHK-Kh5jF1DaZwnFU9fec8LRFiHrkaOWHbRdBgmQkE9Sqcp_IT-8HxSAn_qmxdTAM/s1600/20200313-025.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;377&quot; data-original-width=&quot;887&quot; height=&quot;170&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWgSOTY3AhfITwrkBK7W_Uk_AzxmNGFyzHd2-fRzMavR4-ob5dk9EMIh1FPtFdYQwTBUPmR6mSiyiHK-Kh5jF1DaZwnFU9fec8LRFiHrkaOWHbRdBgmQkE9Sqcp_IT-8HxSAn_qmxdTAM/s400/20200313-025.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsRXlIJFdPb60HQcBeZfOvgb_fsetxDQkpCYeuIXFjW-ZDNbGYAyuzlY8np_MPPK9nDHPy-PutoppNq6HcpYkaeXMvw6xBysL3tLTqLwL15weeBsdIIyFSDOWMqtReKE6xjic6cv-DQ4Q/s1600/20200313-026.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;254&quot; data-original-width=&quot;590&quot; height=&quot;171&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsRXlIJFdPb60HQcBeZfOvgb_fsetxDQkpCYeuIXFjW-ZDNbGYAyuzlY8np_MPPK9nDHPy-PutoppNq6HcpYkaeXMvw6xBysL3tLTqLwL15weeBsdIIyFSDOWMqtReKE6xjic6cv-DQ4Q/s400/20200313-026.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Procfile，輸入「web: gunicorn app:app –log-file -」，–log-file - 為打開顯示除錯訊息，若不想顯示除錯訊息可以使用「web: gunicorn app:app」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj41_BsIzZARfB4oUTeb2HYlv_cuoF1CFUrVc8IfUl3PPhMbrtqpVH-Y_fJhJo0qE8rG_8AUIQn67ktIxoGuUQrsPX6ilMG4GVck6rtxvtfpdTXnwzznfL9GWb1L7P8rISVWY0GNLxnIhk/s1600/20200313-027.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;236&quot; data-original-width=&quot;581&quot; height=&quot;161&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj41_BsIzZARfB4oUTeb2HYlv_cuoF1CFUrVc8IfUl3PPhMbrtqpVH-Y_fJhJo0qE8rG_8AUIQn67ktIxoGuUQrsPX6ilMG4GVck6rtxvtfpdTXnwzznfL9GWb1L7P8rISVWY0GNLxnIhk/s400/20200313-027.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
requirements.txt，將虛擬環境「linebot」安裝的套件版本儲存起來，用來在 Heroku 雲端上安裝的套件佈署用，在VSCode「終端機」輸入。&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;pip freeze &amp;gt; requirements.txt
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhtqcpmeF-i-upGPvwDIP454QOQ97V3EbtZJbLLQM6tU-NgO4oGoHS4eMlOdZMAST1Vu0LaLwdhgDqbg0JyP9_wKkk2uDd2psdOnnyh49Gm3VnMpJMkldql2HUKg4K7Ep_LNoKDF7jRCc/s1600/20200313-028.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;783&quot; data-original-width=&quot;1066&quot; height=&quot;293&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhtqcpmeF-i-upGPvwDIP454QOQ97V3EbtZJbLLQM6tU-NgO4oGoHS4eMlOdZMAST1Vu0LaLwdhgDqbg0JyP9_wKkk2uDd2psdOnnyh49Gm3VnMpJMkldql2HUKg4K7Ep_LNoKDF7jRCc/s400/20200313-028.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 17&lt;/b&gt;：將新增文件加入到「 git 暫存區（Staging Area）」做檔案管理，「VSCode終端機」輸入「git add .」，最後在「原始檔控制」頁籤，點擊「認可(Commit)」按鈕與加入「認可(Commit)」訊息。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitOgJvijpFrYIcYohk9eM6cC7augMe_5fJY9jr9pXNwlM-xaIgLQ230lYX9LbxWhOmbVcbVQJZGcG_jNjgcBvym7THXLuqNgPKm3edjYY5yYQrQwdzVUMD-u6w8JHXlesni9MgcGAWCHE/s1600/20200313-029.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;783&quot; data-original-width=&quot;1066&quot; height=&quot;293&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitOgJvijpFrYIcYohk9eM6cC7augMe_5fJY9jr9pXNwlM-xaIgLQ230lYX9LbxWhOmbVcbVQJZGcG_jNjgcBvym7THXLuqNgPKm3edjYY5yYQrQwdzVUMD-u6w8JHXlesni9MgcGAWCHE/s400/20200313-029.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 18&lt;/b&gt;：透過「VSCode終端機」做登入Heroku，在終端機輸入「heroku login -i」，最後輸入帳密。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3wUwxjg7_XH3TNgK3roLCXStjdTFAtCDhf8sgoh28ZdEIyaOuqTNm8OZZOwQ0me70h4gpB-G-fp3sIGSXg3op5qYEDq8Nu2SZkFOPeXblLQ1nB_Mzt9N63JMs0F3-mnAeBqVJEEfLXqA/s1600/20200313-030.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;783&quot; data-original-width=&quot;1066&quot; height=&quot;293&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3wUwxjg7_XH3TNgK3roLCXStjdTFAtCDhf8sgoh28ZdEIyaOuqTNm8OZZOwQ0me70h4gpB-G-fp3sIGSXg3op5qYEDq8Nu2SZkFOPeXblLQ1nB_Mzt9N63JMs0F3-mnAeBqVJEEfLXqA/s400/20200313-030.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 19&lt;/b&gt;：輸入「heroku create」，在 Heroku 建立&amp;nbsp;app與資料夾，如果成功建立，將回傳一個網址與一個檔案上傳連結。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsoKhcbOMbQ4ZcNwXXwvd5MLM9FtF8gcV5itDEc6eKgrPwgMkLnLGdB74jGm9gJ2bjVKCT8uRH28CGSIy_AhPHP4-TL6LGBB_KWAXocmAJBGKLtigacsCnfvNuXfLB8BMYu-d1GiKrND4/s1600/20200313-031.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;415&quot; data-original-width=&quot;818&quot; height=&quot;202&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsoKhcbOMbQ4ZcNwXXwvd5MLM9FtF8gcV5itDEc6eKgrPwgMkLnLGdB74jGm9gJ2bjVKCT8uRH28CGSIy_AhPHP4-TL6LGBB_KWAXocmAJBGKLtigacsCnfvNuXfLB8BMYu-d1GiKrND4/s400/20200313-031.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 20&lt;/b&gt;：最後將虛擬環境「linebot」中所有建置的檔案推上至 Heroku，在「VSCode終端機」上輸入「git push heroku master」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8Wo27md10DR6LepMTozqO7OcErcLxJ4it9U0oerUKHGXKXG2MGCd7qSWSp31Tp5hkhg3n_E-Oa7PGO_8VVBU58KoAQtgz6ZFIMHi_TeHBMk242rcpctCs9oWu_4Am9yWsuSEDLY-RJ3I/s1600/20200313-032.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;475&quot; data-original-width=&quot;823&quot; height=&quot;230&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8Wo27md10DR6LepMTozqO7OcErcLxJ4it9U0oerUKHGXKXG2MGCd7qSWSp31Tp5hkhg3n_E-Oa7PGO_8VVBU58KoAQtgz6ZFIMHi_TeHBMk242rcpctCs9oWu_4Am9yWsuSEDLY-RJ3I/s400/20200313-032.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhayuoZty4WQ5q7wFPyhQyzV6lHwG93ZtHFgXmvyfHMMrNlMBZiv5DxOcM2dQTkpG1qZxCnk-dvb6tUTVgicgz2Ce05xCwgGb6JqjNluO6u_uICGdAQvqdYhekvdA5rxaHp3oXfhj1fXqY/s1600/20200313-033.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;478&quot; data-original-width=&quot;820&quot; height=&quot;232&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhayuoZty4WQ5q7wFPyhQyzV6lHwG93ZtHFgXmvyfHMMrNlMBZiv5DxOcM2dQTkpG1qZxCnk-dvb6tUTVgicgz2Ce05xCwgGb6JqjNluO6u_uICGdAQvqdYhekvdA5rxaHp3oXfhj1fXqY/s400/20200313-033.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 21&lt;/b&gt;：將步驟19得到的網址，填入Line Developers後台，「Webhook settings」設定的「Webhook URL」，在網址最後加上「/callback」，並開啟「Use webhook」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0r4ASXgxhL3LuDRJ6N4ioK8yOQM3AKY2zlgS3yME1YOeq9qNA4IK4dvZXo2WqynLNq8Px5p4lD2S2bWaYmiZyFLBcsf8FbkEg1fwtI6V_pmkhxRazmWE0f8QNg-ZwBfNMBhDTYtMseG4/s1600/20200313-034.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;403&quot; data-original-width=&quot;658&quot; height=&quot;195&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0r4ASXgxhL3LuDRJ6N4ioK8yOQM3AKY2zlgS3yME1YOeq9qNA4IK4dvZXo2WqynLNq8Px5p4lD2S2bWaYmiZyFLBcsf8FbkEg1fwtI6V_pmkhxRazmWE0f8QNg-ZwBfNMBhDTYtMseG4/s320/20200313-034.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 22&lt;/b&gt;：在&lt;a href=&quot;https://developers.line.biz/zh-hant/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Line Developers&lt;/a&gt;後台取得「Channel secret」、「Channel access token」，到 heroku 後台帳號的「Settings」頁籤，在「Config Vars」設定，點擊「Reveal Config Vars」按鈕，分別在「KEY」填入「LINE_CHANNEL_ACCESS_TOKEN」、「LINE_CHANNEL_SECRET」，「VALUE」填入Channel secret、Channel access token。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhInESjzdd0Co0VhYCWFIOJkltb3aLtE9TyKOUXleKoIXtZocUAGMlF2TeV6FgO5aVylhYzMrnVGMmkqVBOx8dcgp_hl5dy-wYAwi4sPtWzukEAVYAQM3lAH44IW4ZyMfTP1C0G7KY0iqY/s1600/20200313-035.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;780&quot; data-original-width=&quot;938&quot; height=&quot;332&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhInESjzdd0Co0VhYCWFIOJkltb3aLtE9TyKOUXleKoIXtZocUAGMlF2TeV6FgO5aVylhYzMrnVGMmkqVBOx8dcgp_hl5dy-wYAwi4sPtWzukEAVYAQM3lAH44IW4ZyMfTP1C0G7KY0iqY/s400/20200313-035.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYbRi5NwxZR9kXHiNxhFKNeYwlwXjkctnE_cM5iMoLDDVFzxpW4Clj1JtjjHkc_ekfW034cyVtd3i6lyUtIlt9RsI2OV7KRKTJHtbmsaRuVyPzGTNddLg3mHA6KEvLngFGZICgbd5EKn8/s1600/20200313-036.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;439&quot; data-original-width=&quot;938&quot; height=&quot;186&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYbRi5NwxZR9kXHiNxhFKNeYwlwXjkctnE_cM5iMoLDDVFzxpW4Clj1JtjjHkc_ekfW034cyVtd3i6lyUtIlt9RsI2OV7KRKTJHtbmsaRuVyPzGTNddLg3mHA6KEvLngFGZICgbd5EKn8/s400/20200313-036.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;步驟 23&lt;/b&gt;：點擊「Settings」頁籤右上角「Open app」按鈕，確認程式碼中可以執行在Heroku上網頁的訊息。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9LVBLcJjTAK0HkNTevL-gfkPNdF0dsxmEG0nP6SqcTeOJeRInIT02nYdGdMH8-kcAujBkVmQb0iRZKpx3Q4xI7luJv1tr3zDb56GqzQjMIhwrENX_FGApzS8EIWpAONdkXhMc5Y-EHdU/s1600/20200313-038.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;267&quot; data-original-width=&quot;781&quot; height=&quot;136&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9LVBLcJjTAK0HkNTevL-gfkPNdF0dsxmEG0nP6SqcTeOJeRInIT02nYdGdMH8-kcAujBkVmQb0iRZKpx3Q4xI7luJv1tr3zDb56GqzQjMIhwrENX_FGApzS8EIWpAONdkXhMc5Y-EHdU/s400/20200313-038.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
最後透過Heroku提供的log view查看，在Line Bot上輸訊息的回應狀態。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7sBhUBkVBZWxmr4Vy_jZaBLzhHbIp_WE-A1kB-t-kntdLpRkujoepa0O20zFpzyy4l51Ut9bKndU_jA7EKtQlcBJHN673mSO4i1-fOMnpvwE8dxF9p9UsFD2bBoEe4kVLRCFSuShg4-0/s1600/20200313-2.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;945&quot; data-original-width=&quot;1501&quot; height=&quot;251&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7sBhUBkVBZWxmr4Vy_jZaBLzhHbIp_WE-A1kB-t-kntdLpRkujoepa0O20zFpzyy4l51Ut9bKndU_jA7EKtQlcBJHN673mSO4i1-fOMnpvwE8dxF9p9UsFD2bBoEe4kVLRCFSuShg4-0/s400/20200313-2.gif&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/8130482869696479700/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2020/03/heroku-flask-python2herokuline-bot.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/8130482869696479700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/8130482869696479700'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2020/03/heroku-flask-python2herokuline-bot.html' title='Heroku + Flask + Python應用(2)：VSCode建置Line Bot，上傳Heroku佈署'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHfIATEu_hQJ2ZYO8gu01fNdZaXc_EVhJDr1T46rifXLKvXnZOHjYDzKFScrCaArqwjnDPVWLbkA9Azn_POwFyHPO1MjyvolvX-2X2IJ3owuMlH4oH4ReuwJ-tKRTj0mzItqh2HgeL3Wk/s72-c/20200313-001.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-6225008251398229636</id><published>2020-03-12T06:54:00.002-07:00</published><updated>2020-03-12T06:54:20.283-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Line"/><category scheme="http://www.blogger.com/atom/ns#" term="Line Bot"/><category scheme="http://www.blogger.com/atom/ns#" term="Line Messaging API"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Python 在 repl.it 建立Line Bot (3) - 加入圖文選單</title><content type='html'>繼前面兩篇&amp;nbsp;Python 在 repl.it 建立Line Bot 介紹後，再以原本的機器人加入圖文選單，讓機器人操作介面可以更方便。&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;以 &lt;a href=&quot;http://white5168.blogspot.com/2020/03/python-replit-line-bot-2.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Python 在 repl.it 建立Line Bot (2) - 加入指令選項&lt;/a&gt;&amp;nbsp;程式碼為主，且無須修改，再到&amp;nbsp;&amp;nbsp;&lt;a href=&quot;https://manager.line.biz/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;LINE Official Account Manager &lt;/a&gt;後台進行圖文選單的設定，選擇要加入的圖文選單的機器人。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYiDT475G904AYUiH-paYrT2cNYpmHb5No1sdlj28PETwsGBoMoKYo4MZrCvo5MqC__uGUdL8oZztlxMF6YgbXqG7pUI7WCaj0xZ7RsBU0gdXwLSnhu5cA84ro5mVAqpE-L5G-F1YGDIc/s1600/20200312-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;974&quot; data-original-width=&quot;1280&quot; height=&quot;303&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYiDT475G904AYUiH-paYrT2cNYpmHb5No1sdlj28PETwsGBoMoKYo4MZrCvo5MqC__uGUdL8oZztlxMF6YgbXqG7pUI7WCaj0xZ7RsBU0gdXwLSnhu5cA84ro5mVAqpE-L5G-F1YGDIc/s400/20200312-1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
點擊「圖文選單」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT-83I4SPranj_lHVq4amztCdS-yA7K06ioTozuHnggn8WHGV8KFOk8mwlXXKVUMCcOwPz4jcVFOMkiAyVs757Gz7dRyAEHxdy1PJo-_UuJDcN8yrSZtqfpN5P8XU7x2DWm9vpE2DFhzQ/s1600/20200312-2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;794&quot; data-original-width=&quot;1307&quot; height=&quot;242&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT-83I4SPranj_lHVq4amztCdS-yA7K06ioTozuHnggn8WHGV8KFOk8mwlXXKVUMCcOwPz4jcVFOMkiAyVs757Gz7dRyAEHxdy1PJo-_UuJDcN8yrSZtqfpN5P8XU7x2DWm9vpE2DFhzQ/s400/20200312-2.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
點擊右上角「建立」按鈕。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7ZWMeggbXVwjXL2PFNhbtnF-vNF4M3KDsIwng4do6KBm9KZVdNVsVXBHbaoYUFgI_zgkYxxnzLREL8aXfXK8Zgf_O5MzgaQEMbbTDdeN4rtGFP8hidMh9Q-V3M0-3i3ERk1y_4G8LVeY/s1600/20200312-3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;812&quot; data-original-width=&quot;1307&quot; height=&quot;247&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7ZWMeggbXVwjXL2PFNhbtnF-vNF4M3KDsIwng4do6KBm9KZVdNVsVXBHbaoYUFgI_zgkYxxnzLREL8aXfXK8Zgf_O5MzgaQEMbbTDdeN4rtGFP8hidMh9Q-V3M0-3i3ERk1y_4G8LVeY/s400/20200312-3.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
設定「標題」、「使用期間」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitE04zdp016YPsBNrNx0tAYhkTNrNtty3QGB-x9DueW99wyKn_HumKG3PInIOuKXdqmQjRNNyZJjgqpQPB3SfIHRTKdV6EjtB8ZtFzYrAAHw9MSc_S63aTs8ACY-uD1IAHgGVOXUOhg7g/s1600/20200312-4.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;698&quot; data-original-width=&quot;948&quot; height=&quot;293&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitE04zdp016YPsBNrNx0tAYhkTNrNtty3QGB-x9DueW99wyKn_HumKG3PInIOuKXdqmQjRNNyZJjgqpQPB3SfIHRTKdV6EjtB8ZtFzYrAAHw9MSc_S63aTs8ACY-uD1IAHgGVOXUOhg7g/s400/20200312-4.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
點擊「選擇版型」按鈕。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnVXer4WCkczj_2ahsXSqv97GhWDzzrE377ldD6f-66n9Vjjb_7_reH415qCv4P_8kH0sPyiYXKo8-IszVyIa-EcL_8QXDXgk9HQwR1007lL-Lt5dsRY05Q7bi4rSfQEYdjddPuTSu3hE/s1600/20200312-5.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;589&quot; data-original-width=&quot;969&quot; height=&quot;242&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnVXer4WCkczj_2ahsXSqv97GhWDzzrE377ldD6f-66n9Vjjb_7_reH415qCv4P_8kH0sPyiYXKo8-IszVyIa-EcL_8QXDXgk9HQwR1007lL-Lt5dsRY05Q7bi4rSfQEYdjddPuTSu3hE/s400/20200312-5.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
選擇「兩欄式」，點擊「套用」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEDIXWMOM501ON8dz9XJtGsanvrSpVWDuZ7CKElDrEK6UzYFV5YCOSINaEWyY9TZiIpZdCbFnl8lQreCczOY8M0PghvZc8RUyFztxCvKyL-PzQQls9dm86FGo8KSP2A0SsZkhf254teBA/s1600/20200312-6.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;615&quot; data-original-width=&quot;601&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEDIXWMOM501ON8dz9XJtGsanvrSpVWDuZ7CKElDrEK6UzYFV5YCOSINaEWyY9TZiIpZdCbFnl8lQreCczOY8M0PghvZc8RUyFztxCvKyL-PzQQls9dm86FGo8KSP2A0SsZkhf254teBA/s400/20200312-6.png&quot; width=&quot;390&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
點擊「建立圖片」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMUJYCz_siw4IITftClQmeEh8ha2LrN_KWpjMV1zwJsoGcEx8D8k2JbXJdCRg1nxFJzB0FK4oRelKdhXAZBozMplMTsz6pa9ezYy2BkNn2Tcgkv7u-LTrTxf2OdyNtGh7UcsUphT4cxB8/s1600/20200312-7.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;439&quot; data-original-width=&quot;938&quot; height=&quot;186&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMUJYCz_siw4IITftClQmeEh8ha2LrN_KWpjMV1zwJsoGcEx8D8k2JbXJdCRg1nxFJzB0FK4oRelKdhXAZBozMplMTsz6pa9ezYy2BkNn2Tcgkv7u-LTrTxf2OdyNtGh7UcsUphT4cxB8/s400/20200312-7.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
點擊「左側」畫面，在點擊「上傳圖片」按鈕，並上傳一張代表「圖片」的圖片。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEget07w-8TIoI9sd5tGukNumVUazfHVysacPe8nD3oh5dAztXRKbthhnF2UXvkrR6J11kZsJTH4UkOz2kYYSCAfnriKX4SZXoplkrnTE6rki7QwnMnKI7hOO_wsPlW9wHQyqhVmK0tSPOg/s1600/20200312-8.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;603&quot; data-original-width=&quot;879&quot; height=&quot;219&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEget07w-8TIoI9sd5tGukNumVUazfHVysacPe8nD3oh5dAztXRKbthhnF2UXvkrR6J11kZsJTH4UkOz2kYYSCAfnriKX4SZXoplkrnTE6rki7QwnMnKI7hOO_wsPlW9wHQyqhVmK0tSPOg/s320/20200312-8.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
點擊「右側」畫面，在點擊「加入文字」按鈕。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmpzQh3MNrjV3hjD902tnezTeLMP8xTezvjaq4ovUah6mCeW6gI9jswIivXEI9306g9lXFyIkFpwGzdQWlT5Rq4G8TPQFtsx5xt386bBPjuxHLtjlTpbhyphenhyphen58IGUuhq4HTVK3vaOc8ArsI/s1600/20200312-9.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;602&quot; data-original-width=&quot;878&quot; height=&quot;273&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmpzQh3MNrjV3hjD902tnezTeLMP8xTezvjaq4ovUah6mCeW6gI9jswIivXEI9306g9lXFyIkFpwGzdQWlT5Rq4G8TPQFtsx5xt386bBPjuxHLtjlTpbhyphenhyphen58IGUuhq4HTVK3vaOc8ArsI/s400/20200312-9.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
輸入「貼圖」兩字，點擊右上角「套用」按鈕。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBwwl4yw58Gg3p3-KLt6I-VvSll57BRzPrdvrx_227edudYTJhy6FAHvCycw6d_yUxF9Cw7u7_iUOFgvuOSleEOBzUoZp1UxPADgWuq8V2HT1HJDKU89Ya-up-sKYdEnWjx3GjLI3myjs/s1600/20200312-10.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;602&quot; data-original-width=&quot;879&quot; height=&quot;273&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBwwl4yw58Gg3p3-KLt6I-VvSll57BRzPrdvrx_227edudYTJhy6FAHvCycw6d_yUxF9Cw7u7_iUOFgvuOSleEOBzUoZp1UxPADgWuq8V2HT1HJDKU89Ya-up-sKYdEnWjx3GjLI3myjs/s400/20200312-10.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
點擊「套用」按鈕。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXprfPLKcFHyzIY3xWyNklowA1D-yC_9IT8j73MwEoZtgNtAgc91CRrNb1MAQtHkRj6-xnGqrm2KgCdM3-IN_buUOu58HmpLgw3DYf4MoTmixdl4TF2uqAnb46khCqx7C0Mfg8slUauE8/s1600/20200312-11.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;603&quot; data-original-width=&quot;880&quot; height=&quot;273&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXprfPLKcFHyzIY3xWyNklowA1D-yC_9IT8j73MwEoZtgNtAgc91CRrNb1MAQtHkRj6-xnGqrm2KgCdM3-IN_buUOu58HmpLgw3DYf4MoTmixdl4TF2uqAnb46khCqx7C0Mfg8slUauE8/s400/20200312-11.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
設定A畫面在觸碰後的動作，點擊下拉選單，選擇「文字」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiElAsyNQNXZRYUr3r6aIiWzzfKGK68Rr5A4lrEudlOQFwmcPwfHRPlxPmeO3Q1bnbIS2s762IpVE5L_xs7Dl1HRr3ac7CGA-ct1J-Uc3r84CFVbZmbpVy4nn3pMbylgGyq007kYVzzpQc/s1600/20200312-12.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;573&quot; data-original-width=&quot;1039&quot; height=&quot;220&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiElAsyNQNXZRYUr3r6aIiWzzfKGK68Rr5A4lrEudlOQFwmcPwfHRPlxPmeO3Q1bnbIS2s762IpVE5L_xs7Dl1HRr3ac7CGA-ct1J-Uc3r84CFVbZmbpVy4nn3pMbylgGyq007kYVzzpQc/s400/20200312-12.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
在關鍵字回應欄位中，輸入「圖片」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCtItxvsWMUNI5RNCD7eUvQFpTij7dWcoaYXk0PSvhJ0fe7u8MySTDoM07CUHT5w4uNZFwxZsfTdU93W9wEeU85h1Mx1gK5WtLGTf6udmkY0lChY5TYbCpwi6xHfEvbsWNtSrGO4UvbDc/s1600/20200312-13.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;569&quot; data-original-width=&quot;1018&quot; height=&quot;222&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCtItxvsWMUNI5RNCD7eUvQFpTij7dWcoaYXk0PSvhJ0fe7u8MySTDoM07CUHT5w4uNZFwxZsfTdU93W9wEeU85h1Mx1gK5WtLGTf6udmkY0lChY5TYbCpwi6xHfEvbsWNtSrGO4UvbDc/s400/20200312-13.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
依照上述動作，設定B畫面觸碰動作，最後點擊「儲存」按鈕。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTUq3ozsyJGgJewsKS-TENaUQJUQrWQ4Vb-8BVfV-tkYuQLPW-EmUPES1f3braPtarmYIfAlwjg_dQbQYUUQBxcWVBDou3jDM-fFNPJX-7JedGLdpiQnqIejQsrBXJuCLdASwLBQHU1Xw/s1600/20200312-14.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;774&quot; data-original-width=&quot;1038&quot; height=&quot;298&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTUq3ozsyJGgJewsKS-TENaUQJUQrWQ4Vb-8BVfV-tkYuQLPW-EmUPES1f3braPtarmYIfAlwjg_dQbQYUUQBxcWVBDou3jDM-fFNPJX-7JedGLdpiQnqIejQsrBXJuCLdASwLBQHU1Xw/s400/20200312-14.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
最後完成圖文選單設定的畫面，此值的狀態為「已就緒」，表示「圖文選單」正在運作。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjxZRUEibaoG3c-pJTgD5RajGMrX_gRywDrjjxwQC-I8q_2rV8_919d-zipOIav2bLqNDewH0oNC91oc6lMp698Xgl5fT06-CtV7qccZLd8mztUJSdEuBNzSwuGz8Gg9vXxx5pG0bVE44/s1600/20200312-15.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;775&quot; data-original-width=&quot;1304&quot; height=&quot;237&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjxZRUEibaoG3c-pJTgD5RajGMrX_gRywDrjjxwQC-I8q_2rV8_919d-zipOIav2bLqNDewH0oNC91oc6lMp698Xgl5fT06-CtV7qccZLd8mztUJSdEuBNzSwuGz8Gg9vXxx5pG0bVE44/s400/20200312-15.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
執行畫面。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIyiwpnReubTsmh6YBvGPnaIn0BoUvYOGsTjvUit6HeJ_A7I1UVKzqHMLU2sRj24d0jmKgwX_B2Bnya8e42qOUc7rBwCI5IS6pLMDB01ONOYaHoH9mR27z4AewKKA3kIjevwOgnDNya-Q/s1600/20200312-1.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;932&quot; data-original-width=&quot;1600&quot; height=&quot;232&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIyiwpnReubTsmh6YBvGPnaIn0BoUvYOGsTjvUit6HeJ_A7I1UVKzqHMLU2sRj24d0jmKgwX_B2Bnya8e42qOUc7rBwCI5IS6pLMDB01ONOYaHoH9mR27z4AewKKA3kIjevwOgnDNya-Q/s400/20200312-1.gif&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/6225008251398229636/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2020/03/python-replit-line-bot-3.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/6225008251398229636'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/6225008251398229636'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2020/03/python-replit-line-bot-3.html' title='Python 在 repl.it 建立Line Bot (3) - 加入圖文選單'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYiDT475G904AYUiH-paYrT2cNYpmHb5No1sdlj28PETwsGBoMoKYo4MZrCvo5MqC__uGUdL8oZztlxMF6YgbXqG7pUI7WCaj0xZ7RsBU0gdXwLSnhu5cA84ro5mVAqpE-L5G-F1YGDIc/s72-c/20200312-1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-6602316284912589809</id><published>2020-03-09T07:16:00.000-07:00</published><updated>2020-03-12T02:07:16.830-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Flask"/><category scheme="http://www.blogger.com/atom/ns#" term="Line"/><category scheme="http://www.blogger.com/atom/ns#" term="Line Bot"/><category scheme="http://www.blogger.com/atom/ns#" term="Line Messaging API"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Python 在 repl.it 建立Line Bot (2) - 加入指令選項</title><content type='html'>前一篇&amp;nbsp;&lt;a href=&quot;http://white5168.blogspot.com/2020/03/python-replit-line-bot-1.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Python 在 repl.it 建立Line Bot (1) - 與Line機器人簡易對談&lt;/a&gt; 介紹如何在repl.it上建立Lne Bot 簡易對談，在實際使用上Line Bot功能不指簡易對談，接下來加入指令選項讓Line Bot可以依據訂定好的指令完成所需的回覆。
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;除了文字對談，Line Bot 還可回應圖片、貼圖、影片、聲音、位置、影像圖、模板選單等，更多的詳細的說明可洽&amp;nbsp;&lt;a href=&quot;https://developers.line.biz/en/docs/messaging-api/message-types/#text-messages&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Line Bot官網&lt;/a&gt;&amp;nbsp;查詢。&lt;br /&gt;
以前一篇文章的 Line Bot 為基礎，加入圖片、貼圖、影片回應功能，藉由修改「handle_message」函數，添加處理接收到圖片、貼圖、影片的程式碼，如程如下功能。
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;圖片指令，回傳家扶娃娃照片。&lt;/li&gt;
&lt;li&gt;貼圖指令，隨機回傳Line的貼圖。&lt;/li&gt;
&lt;li&gt;影片指令，回傳海賊王片段影片。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;brush:py&quot;&gt;from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)

from linebot.exceptions import (
    InvalidSignatureError
)

from linebot.models import *

import os
import numpy as np

app = Flask(__name__)

token = os.environ.get(&quot;CHANNEL_ACCESS_TOKEN&quot;)
secret= os.environ.get(&quot;CHANNEL_SECRET&quot;)
line_bot_api = LineBotApi(token)
handler = WebhookHandler(secret)

totalid = {
            1:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,21,100,101,102,103,104,105,106,107,108,109,110,111,
               112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,
               135,136,137,138,139,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,
               419,420,421,422,423,424,425,426,427,428,429,430],
            2:[18,19,20,22,23,24,258,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,48,141,
               142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,
               165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,501,502,503,504,505,506,507,508,
               509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527],
            3:[180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,
               203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,
               226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,
               249,250,251,252,253,254,255,256,257,258,259],
            4:[260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,
               283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,
               306,307,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,
               622,623,624,625,626,627,628,629,630,631,632]
           } 

@app.route(&#39;/callback&#39;, methods=[&#39;POST&#39;])
def callback():
    signature = request.headers[&#39;X-Line-Signature&#39;]
    body = request.get_data(as_text=True)
    app.logger.info(&quot;Request body: &quot; + body)

    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        print(&quot;Invalid signature. Please check your channel access token/channel secret.&quot;)
        abort(400)

    return &#39;OK&#39;

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    msg = event.message.text    
    print(msg)
    if msg == &quot;文字&quot;:
        line_bot_api.reply_message(
            event.reply_token,
            TextSendMessage(text=event.message.text))
    elif msg == &quot;貼圖&quot;:
        packageid = np.random.randint(1, 5)
        stkpkgid = totalid[packageid]
        stickerid = stkpkgid[np.random.randint(len(stkpkgid))]
        line_bot_api.reply_message(event.reply_token, StickerSendMessage(package_id=packageid, sticker_id=stickerid))
    elif msg == &quot;圖片&quot;:
        line_bot_api.reply_message(event.reply_token,ImageSendMessage(original_content_url=&#39;https://image.peoplenews.tw/news/e48b8810-3b75-46dc-8e00-b64945335bef.jpg&#39;, preview_image_url=&#39;https://image.peoplenews.tw/news/e48b8810-3b75-46dc-8e00-b64945335bef.jpg&#39;))
    elif msg == &quot;影片&quot;:
        line_bot_api.reply_message(event.reply_token,VideoSendMessage(original_content_url=&#39;https://video.ftpe3-2.fna.fbcdn.net/v/t42.9040-2/87072388_196826851385614_8294431350157475840_n.mp4?_nc_cat=107&amp;amp;_nc_sid=985c63&amp;amp;efg=eyJybHIiOjQ4NCwicmxhIjoxMTE2LCJ2ZW5jb2RlX3RhZyI6InN2ZV9zZCJ9&amp;amp;_nc_ohc=Dno5wcM5hCoAX9wNCXP&amp;amp;rl=484&amp;amp;vabr=269&amp;amp;_nc_ht=video.ftpe3-2.fna&amp;amp;oh=970be2c547d63b58d9eeeddb50798c78&amp;amp;oe=5E6677B1&#39;, preview_image_url=&#39;https://scontent.ftpe3-2.fna.fbcdn.net/v/t15.5256-10/p200x200/82227458_520753612181601_8138286452606763008_n.jpg?_nc_cat=101&amp;amp;_nc_sid=f2c4d5&amp;amp;_nc_ohc=lsC6y4SY6jEAX91aBTf&amp;amp;_nc_ht=scontent.ftpe3-2.fna&amp;amp;_nc_tp=6&amp;amp;oh=2b331d81175b9e740ca02479e5e21db0&amp;amp;oe=5E926DE0&#39;))
    else:
        line_bot_api.reply_message(
            event.reply_token,
            TextSendMessage(text=event.message.text))
        
app.run(host=&#39;0.0.0.0&#39;, port=8080)
&lt;/pre&gt;
&lt;br /&gt;
執行畫面：&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9_d0bcagv-Hp3dLsSlK7fxMWQlQgLcj0b-qGQymlf9POxH-ko1PjvfXQvtDqS9CNTIF5oYWqBwWprbjNbQXjzkvkAfQxUTSn8wje_uDNVrCX4hWhuqdcmVy2t3ut44HgmCISOcimjB8w/s1600/20200309-1.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;945&quot; data-original-width=&quot;1387&quot; height=&quot;436&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9_d0bcagv-Hp3dLsSlK7fxMWQlQgLcj0b-qGQymlf9POxH-ko1PjvfXQvtDqS9CNTIF5oYWqBwWprbjNbQXjzkvkAfQxUTSn8wje_uDNVrCX4hWhuqdcmVy2t3ut44HgmCISOcimjB8w/s640/20200309-1.gif&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/6602316284912589809/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2020/03/python-replit-line-bot-2.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/6602316284912589809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/6602316284912589809'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2020/03/python-replit-line-bot-2.html' title='Python 在 repl.it 建立Line Bot (2) - 加入指令選項'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9_d0bcagv-Hp3dLsSlK7fxMWQlQgLcj0b-qGQymlf9POxH-ko1PjvfXQvtDqS9CNTIF5oYWqBwWprbjNbQXjzkvkAfQxUTSn8wje_uDNVrCX4hWhuqdcmVy2t3ut44HgmCISOcimjB8w/s72-c/20200309-1.gif" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-525564344213763321</id><published>2020-03-08T01:30:00.000-08:00</published><updated>2020-03-08T18:58:06.656-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Flask"/><category scheme="http://www.blogger.com/atom/ns#" term="Line"/><category scheme="http://www.blogger.com/atom/ns#" term="Line Bot"/><category scheme="http://www.blogger.com/atom/ns#" term="Line Messaging API"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Python 在 repl.it 建立Line Bot (1)  - 與Line機器人簡易對談</title><content type='html'>repl.it 提供線上程式開發環境，你只要選擇所需開發語言就可以使用相關環境進行程式開發編輯與測試，repl.it 支援多種&lt;a href=&quot;https://repl.it/languages&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;程式語言&lt;/a&gt;，包括 Python3、JAVA、C++ ... 等，有需要的朋友可至&lt;a href=&quot;https://repl.it/languages&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;網站&lt;/a&gt;上了解
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;以Python3做為開發Line Bot 的操作環境。&lt;br /&gt;
步驟1：在repl.it 選擇Python3建立「test」開發專案。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeP2vY-bQo0R0Axkwm4GH99LQsZwB_TaimDg7WFxVc4IWIr7e8PdCD9lCdZqZ1BSs-L3uAEETnridcyJl4HmQI1Jjv0vtfjPX8UHhH5616WSSY29ImDbMr0xtzcvIFOkmao7UrCfTZrZs/s1600/20200308-001.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;753&quot; data-original-width=&quot;896&quot; height=&quot;335&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeP2vY-bQo0R0Axkwm4GH99LQsZwB_TaimDg7WFxVc4IWIr7e8PdCD9lCdZqZ1BSs-L3uAEETnridcyJl4HmQI1Jjv0vtfjPX8UHhH5616WSSY29ImDbMr0xtzcvIFOkmao7UrCfTZrZs/s400/20200308-001.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm8exG8QgGEhD93B6THezfCsGS5UAZL-h-Vcdrsmnxx2GuDAzfLNci97qabAs59yCKI-y5SynzOn8-YiL9cG-sAC9vstMp4qXtOGs9aGX0cRMJ0m5sBjvK1Y5LHiQOrHA55PBkueOvjvM/s1600/20200308-002.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;753&quot; data-original-width=&quot;896&quot; height=&quot;335&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm8exG8QgGEhD93B6THezfCsGS5UAZL-h-Vcdrsmnxx2GuDAzfLNci97qabAs59yCKI-y5SynzOn8-YiL9cG-sAC9vstMp4qXtOGs9aGX0cRMJ0m5sBjvK1Y5LHiQOrHA55PBkueOvjvM/s400/20200308-002.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟2：輸入程式碼&lt;br /&gt;
&lt;pre class=&quot;brush:py&quot;&gt;from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)

from linebot.exceptions import (
    InvalidSignatureError
)

from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)

import os
app = Flask(__name__)

token = os.environ.get(&quot;CHANNEL_ACCESS_TOKEN&quot;)
secret= os.environ.get(&quot;CHANNEL_SECRET&quot;)
line_bot_api = LineBotApi(token)
handler = WebhookHandler(secret)

@app.route(&#39;/callback&#39;, methods=[&#39;POST&#39;])
def callback():
    signature = request.headers[&#39;X-Line-Signature&#39;]
    body = request.get_data(as_text=True)
    app.logger.info(&quot;Request body: &quot; + body)

    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        print(&quot;Invalid signature. Please check your channel access token/channel secret.&quot;)
        abort(400)

    return &#39;OK&#39;

app.run(host=&#39;0.0.0.0&#39;, port=8080)
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfrBsP2uzrk2s1AHPYLTfNOhL1zIDKw6szIZu4oPRRsWAKjzIEba3t7mcnVfGO3PfB1aqVMWLYtrP6krUG-YFGib8Ne0_80-Vu2iMONUjgI_q-WVdpzVxg2380___OZ5C5Dg8LOrzRv1I/s1600/20200308-003.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;994&quot; data-original-width=&quot;1120&quot; height=&quot;355&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfrBsP2uzrk2s1AHPYLTfNOhL1zIDKw6szIZu4oPRRsWAKjzIEba3t7mcnVfGO3PfB1aqVMWLYtrP6krUG-YFGib8Ne0_80-Vu2iMONUjgI_q-WVdpzVxg2380___OZ5C5Dg8LOrzRv1I/s400/20200308-003.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟3：登入&amp;nbsp;&lt;a href=&quot;https://developers.line.biz/zh-hant/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;LINE Developers&lt;/a&gt; 後台建立Line Bot帳號。&lt;br /&gt;
(1) 點擊&amp;nbsp;「Create a new channel」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjscObPUQnE84th1aZHf0d_sGj3_alrYrmF467F3RIZ8Qugoc9i0d46vDMUJ98aeMNqPynOu39swF3bNpOciWQ-uwf176flJ38FGudT2aOlflOlZNF84VqFkb4RQqExFh65wWhE82Y2sZk/s1600/20200308-004.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;982&quot; data-original-width=&quot;1102&quot; height=&quot;356&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjscObPUQnE84th1aZHf0d_sGj3_alrYrmF467F3RIZ8Qugoc9i0d46vDMUJ98aeMNqPynOu39swF3bNpOciWQ-uwf176flJ38FGudT2aOlflOlZNF84VqFkb4RQqExFh65wWhE82Y2sZk/s400/20200308-004.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
(2) 點擊「Message API」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeWzLpn4cmmpwe4Kg-7ITT410xvyxMX3wCTTgT11lB_5Sq6jV0eZ7_hISVMivsk6x7MiABbbv-E2qQxGdaAB7SXGpzSozxaIUhgtcytuoVAOORHVcBnSzvZeO_Pm20VL4glhG4A-rYD4c/s1600/20200308-005.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;315&quot; data-original-width=&quot;604&quot; height=&quot;207&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeWzLpn4cmmpwe4Kg-7ITT410xvyxMX3wCTTgT11lB_5Sq6jV0eZ7_hISVMivsk6x7MiABbbv-E2qQxGdaAB7SXGpzSozxaIUhgtcytuoVAOORHVcBnSzvZeO_Pm20VL4glhG4A-rYD4c/s400/20200308-005.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
(3) 輸入必要資訊。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6IN7cg3fk7YeplosjJAN3zoq7jAIUzz0su66paArP1gdxfljsGWQxOSyre6bHcEY4QpdoTUZdGbhhHdBZkvy6dofl4zPW2Tz4oaRb4gBocjm4jyRymBDixlxKCl0GzEal6caDBD1PuRY/s1600/20200308-006.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;995&quot; data-original-width=&quot;1030&quot; height=&quot;386&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6IN7cg3fk7YeplosjJAN3zoq7jAIUzz0su66paArP1gdxfljsGWQxOSyre6bHcEY4QpdoTUZdGbhhHdBZkvy6dofl4zPW2Tz4oaRb4gBocjm4jyRymBDixlxKCl0GzEal6caDBD1PuRY/s400/20200308-006.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
(4) 勾選與建立帳號。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-XsdT6lKfPnIGrI3CA9MlK_ehY36KwsPVVValPxaKTm7p8QPG673SZCOhCzT6NWwIcBzX0LplPdwPRC9WYkVKdP55XkkoP9EnI2CN9BXU7TY-WC0n8MwmtDgk90uPVDcgxsTiDtj0AZc/s1600/20200308-007.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;995&quot; data-original-width=&quot;1030&quot; height=&quot;386&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-XsdT6lKfPnIGrI3CA9MlK_ehY36KwsPVVValPxaKTm7p8QPG673SZCOhCzT6NWwIcBzX0LplPdwPRC9WYkVKdP55XkkoP9EnI2CN9BXU7TY-WC0n8MwmtDgk90uPVDcgxsTiDtj0AZc/s400/20200308-007.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
(5) 點擊「同意」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEid2tyDdXdEP9O8CpVxjTAXX4j5COqxzliZq9iSc6iSKK_8g_RqMsC9GH23YEqCRrKxHUNzeaJBZ-PPDAaCSSl9s2pSjq9vhOQAC-kxLL9vlbk3BRgGegJj1UJEBYJ6P1lU4rPPNmqupu0/s1600/20200308-008.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;995&quot; data-original-width=&quot;1030&quot; height=&quot;386&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEid2tyDdXdEP9O8CpVxjTAXX4j5COqxzliZq9iSc6iSKK_8g_RqMsC9GH23YEqCRrKxHUNzeaJBZ-PPDAaCSSl9s2pSjq9vhOQAC-kxLL9vlbk3BRgGegJj1UJEBYJ6P1lU4rPPNmqupu0/s400/20200308-008.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟5：取得「Channel access token」。&lt;br /&gt;
(1) 切換頁籤至「Message API」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4PbUEwYxQt3sspC7lj6aY9Vjyf6lmwFg-V2AJfOqLfneSrihYjvZzxuekDoVeiUuj06fdqEqG9ZkQJZYylPc99fPl-2MvikEdSmhY9TikxhSUp6lqt3FldCJ3AJZ2GJyt6mgqvceWC38/s1600/20200308-009.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;429&quot; data-original-width=&quot;737&quot; height=&quot;232&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4PbUEwYxQt3sspC7lj6aY9Vjyf6lmwFg-V2AJfOqLfneSrihYjvZzxuekDoVeiUuj06fdqEqG9ZkQJZYylPc99fPl-2MvikEdSmhY9TikxhSUp6lqt3FldCJ3AJZ2GJyt6mgqvceWC38/s400/20200308-009.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
(2) 點擊「issue」產生Token。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjbbBTjsOhZtxCa9oerTebN5K5gxgwt3BIAWUMuyFyQExvRHQgPdWpKlui-rk5RnKndeeq20ZWVxPqOB1cgNYR_Eyr46bTEqH1fxdGWAw5SekZ_R4KjfjKYc4mcM3fG6wPjNI_nhL4wiQ/s1600/20200308-010.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;995&quot; data-original-width=&quot;1030&quot; height=&quot;386&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjbbBTjsOhZtxCa9oerTebN5K5gxgwt3BIAWUMuyFyQExvRHQgPdWpKlui-rk5RnKndeeq20ZWVxPqOB1cgNYR_Eyr46bTEqH1fxdGWAw5SekZ_R4KjfjKYc4mcM3fG6wPjNI_nhL4wiQ/s400/20200308-010.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
(3) 將Token複製存好。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhotUx9rpPGIkFHUhwg-lZ6CiQ9xYEktpjUAWcCP5X7CO8PXpEn1J_dYej_rMoJeoBbGluHfbta8Sey40PYqIl6aOIuVWa_f3ax-zJQXQvZ_i9ocjEcrSsVAQyQ_o9l4k5UhzdqQjX7eio/s1600/20200308-011.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;269&quot; data-original-width=&quot;1003&quot; height=&quot;106&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhotUx9rpPGIkFHUhwg-lZ6CiQ9xYEktpjUAWcCP5X7CO8PXpEn1J_dYej_rMoJeoBbGluHfbta8Sey40PYqIl6aOIuVWa_f3ax-zJQXQvZ_i9ocjEcrSsVAQyQ_o9l4k5UhzdqQjX7eio/s400/20200308-011.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟6：取得「Channel secret」。&lt;br /&gt;
(1) 切換頁籤至「Basic settings」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg37r6UoCKNdHGKqUCPyTRnCsYy1gk8eeytLtgkwM0wk9TM9Hd3A1IOwZK2W7Q2LzaE0swWW1W10rvwgucl6Si2lpVjT9cSkNOyx0D60hNQDe5hZ8OuGdQg6P8DiJqpmYs7_x7GHj92F44/s1600/20200308-012.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;392&quot; data-original-width=&quot;731&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg37r6UoCKNdHGKqUCPyTRnCsYy1gk8eeytLtgkwM0wk9TM9Hd3A1IOwZK2W7Q2LzaE0swWW1W10rvwgucl6Si2lpVjT9cSkNOyx0D60hNQDe5hZ8OuGdQg6P8DiJqpmYs7_x7GHj92F44/s400/20200308-012.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
(2) 複製存好「Channel secret」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsWQAPDidqXDnIkhsHviSUC2FT_byIShND95rZVEQ0zXwhnJ4XBIKNktFwb-RBT40ChY-NyVaSzpezImQiXh2PEt5GnSQzv4qMTrBWEr6l2SdsrT352JRRJd5S27IBwoT9RrOeHZxpHL4/s1600/20200308-013.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;299&quot; data-original-width=&quot;813&quot; height=&quot;146&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsWQAPDidqXDnIkhsHviSUC2FT_byIShND95rZVEQ0zXwhnJ4XBIKNktFwb-RBT40ChY-NyVaSzpezImQiXh2PEt5GnSQzv4qMTrBWEr6l2SdsrT352JRRJd5S27IBwoT9RrOeHZxpHL4/s400/20200308-013.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟7：在repl.it 的「test」開發專案下新增「.env」檔案，輸入剛剛保存的「Channel access token」跟「Channel secret」。&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;CHANNEL_ACCESS_TOKEN=「Channel access token」
CHANNEL_SECRET=「Channel secret」
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjvrcZewnGISlNNCZLEsgAIU9TeChrFhyphenhyphenGLPODy7jaAQFKOCoJAQNwmvfeEnzJX5kTD8sWcS9t7B4csn643MVE6rwbmiu2f7gp9P-Of8ssvLTCvNA8i3LgiwSiXSyNnAyswAR5m4jAo68/s1600/20200308-014.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;145&quot; data-original-width=&quot;939&quot; height=&quot;61&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjvrcZewnGISlNNCZLEsgAIU9TeChrFhyphenhyphenGLPODy7jaAQFKOCoJAQNwmvfeEnzJX5kTD8sWcS9t7B4csn643MVE6rwbmiu2f7gp9P-Of8ssvLTCvNA8i3LgiwSiXSyNnAyswAR5m4jAo68/s400/20200308-014.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
步驟8：執行「test」開發專案，並取得URL。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm4PqyAHJGl_Ti34QmcII5iBvYDrkp1v5TcVsOBBKLMi1tMN0d1TymQHSmiWsMcwLMtMU8W3WzwhIaigVmGSbMdbl8nknkzZrZ36lIgZOBGI4z2gJ4-I7J1VG1r62Q-p64CvPoXsEs_Lc/s1600/20200308-015.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;975&quot; data-original-width=&quot;1233&quot; height=&quot;316&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm4PqyAHJGl_Ti34QmcII5iBvYDrkp1v5TcVsOBBKLMi1tMN0d1TymQHSmiWsMcwLMtMU8W3WzwhIaigVmGSbMdbl8nknkzZrZ36lIgZOBGI4z2gJ4-I7J1VG1r62Q-p64CvPoXsEs_Lc/s400/20200308-015.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟9：回到&amp;nbsp;&lt;a href=&quot;https://developers.line.biz/zh-hant/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;LINE Developers&lt;/a&gt;&amp;nbsp;後台，切換至「Message API」頁籤測試「Webhook URL」。&lt;br /&gt;
(1) 點擊「Edit」按鈕。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7gdsb33rJS3YzffQLqAEPYW0HOhkhO2FX9aLBV1ae6o5kE4JMi9AoOom8gMbtb_renFZEe7A965nGr_CB5sJD9ItkRir_VYSaLGdIpQJJKe7uVG6EEKbDG6qKDtRgHvKtpoaP1R-7FRY/s1600/20200308-016.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;242&quot; data-original-width=&quot;615&quot; height=&quot;156&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7gdsb33rJS3YzffQLqAEPYW0HOhkhO2FX9aLBV1ae6o5kE4JMi9AoOom8gMbtb_renFZEe7A965nGr_CB5sJD9ItkRir_VYSaLGdIpQJJKe7uVG6EEKbDG6qKDtRgHvKtpoaP1R-7FRY/s400/20200308-016.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
(2) 輸入剛剛取得URL，並在URL後加上「/callback」，點擊「Update」按鈕。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtnILLhU3nNTtPCBU0PV44joTLjIAMzblwyJLL6isAGZkyOObUWySdgS0Y_HvqALOkMOqRn_YCU_LfGZ5KykY1aIofazrP9RohZQv-Y9WCdf5hQdF3rW1LdYXMyqgtq_iaWqcu6zXFGuA/s1600/20200308-017.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;192&quot; data-original-width=&quot;474&quot; height=&quot;161&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtnILLhU3nNTtPCBU0PV44joTLjIAMzblwyJLL6isAGZkyOObUWySdgS0Y_HvqALOkMOqRn_YCU_LfGZ5KykY1aIofazrP9RohZQv-Y9WCdf5hQdF3rW1LdYXMyqgtq_iaWqcu6zXFGuA/s400/20200308-017.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
(3) 點擊「Verify」按鈕，確認連結成功。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn15BIOzw3t1XgSL76xo1_u7illS0hivtOvIKpYs8w1Nrhu4iYJ9DHZ9XaXGqr4dJvQpM5sa9mxj5u88Qo3K-7xp_33Y0Qmhy1anW4aXO8IeYl3kzk5YhITlMEnvxoVHjq-ZyqjzWBO98/s1600/20200308-018.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;369&quot; data-original-width=&quot;625&quot; height=&quot;235&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn15BIOzw3t1XgSL76xo1_u7illS0hivtOvIKpYs8w1Nrhu4iYJ9DHZ9XaXGqr4dJvQpM5sa9mxj5u88Qo3K-7xp_33Y0Qmhy1anW4aXO8IeYl3kzk5YhITlMEnvxoVHjq-ZyqjzWBO98/s400/20200308-018.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
(4) 掃描QR code加入Line Bot帳號到Line中，並啟動與Line的連結&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQLemn2Xk7q5dlLolnBZ1EddCdXs1iQPU9hK7I8p85xhjyWOG0jKZiOI2AUzTWZSdxWvMo8rJJhpTl_coUuFrSz97n_GOl9QZ9qYa4cPu4q_fg2M0vk8KEKvuxLIdTZ3QWiCvkOKrEfh4/s1600/20200308-019.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;486&quot; data-original-width=&quot;742&quot; height=&quot;261&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQLemn2Xk7q5dlLolnBZ1EddCdXs1iQPU9hK7I8p85xhjyWOG0jKZiOI2AUzTWZSdxWvMo8rJJhpTl_coUuFrSz97n_GOl9QZ9qYa4cPu4q_fg2M0vk8KEKvuxLIdTZ3QWiCvkOKrEfh4/s400/20200308-019.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟10：加入回應的程式碼到「test」開發專案，並重新啟動專案執行。&lt;br /&gt;
&lt;pre class=&quot;brush:py&quot;&gt;@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=event.message.text))
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7P3Kv5QIJzW8gHJtC0lmEr3lSinjjF_1CnnulB-CCMMZ78DZgFVWx1EnXgYDt6S1q-iLKN2hgMuhy7kxbjWWspZjxr97O_vvVHI5qjB21DvN6357K6iusbU1QyEzED_qz65yIY4ERWkk/s1600/20200308-020.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;975&quot; data-original-width=&quot;1413&quot; height=&quot;275&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7P3Kv5QIJzW8gHJtC0lmEr3lSinjjF_1CnnulB-CCMMZ78DZgFVWx1EnXgYDt6S1q-iLKN2hgMuhy7kxbjWWspZjxr97O_vvVHI5qjB21DvN6357K6iusbU1QyEzED_qz65yIY4ERWkk/s400/20200308-020.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟11：在Line Bot輸入任意字，看結果。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOhwroMDGKPrxugsdtkfbmxXfSsK2Kfo7VLA0C8rryLXQOGB3alBrwobEwzYuOAlO_w68RdqA2h81hJgWvTB2KyFOfgb7gDaTj3LC0GZ2AKXGY0Sj2knwf1Clp2-YNsO0_PECtokiVVHA/s1600/20200308-021.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;857&quot; data-original-width=&quot;353&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOhwroMDGKPrxugsdtkfbmxXfSsK2Kfo7VLA0C8rryLXQOGB3alBrwobEwzYuOAlO_w68RdqA2h81hJgWvTB2KyFOfgb7gDaTj3LC0GZ2AKXGY0Sj2knwf1Clp2-YNsO0_PECtokiVVHA/s400/20200308-021.png&quot; width=&quot;163&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
步驟12：若不想見到期他由系統回的訊息，到回到&amp;nbsp;&lt;a href=&quot;https://developers.line.biz/zh-hant/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;LINE Developers&lt;/a&gt;&amp;nbsp;後台，切換至「Message API」頁籤，關閉自動回應。&lt;br /&gt;
(1) 在「Auto-reply messages」後面，點擊「Edit」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy6-Ttb20uA8go1MVKvy_mO8ryBsuYdx8xUBY44UJK7v3cvgQJseni5SUcKZqV7ssg9k58yGpybbUuQ5ikrAZkdiEtd3ll9aypMMdjM6tFd4PzGnSZtOe9_LvMeQ7ne57jC8zBsW35R2k/s1600/20200308-022.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;311&quot; data-original-width=&quot;825&quot; height=&quot;150&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy6-Ttb20uA8go1MVKvy_mO8ryBsuYdx8xUBY44UJK7v3cvgQJseni5SUcKZqV7ssg9k58yGpybbUuQ5ikrAZkdiEtd3ll9aypMMdjM6tFd4PzGnSZtOe9_LvMeQ7ne57jC8zBsW35R2k/s400/20200308-022.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
(3) 在「自動回應訊息」的設定中，點擊「停用」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8Pig0FOPHw0ngacNONYmBWK95LEahGUzgpQJ3FlpvRGgLQ27tu5tyHaPbm7WNCkBwJR-2DF0eJ7wlDTRYAPZkkdYqMG7MXyny3_Zo5urokVIPfAFeZlL8jfMm51aYmE3STGO6L6eCL18/s1600/20200308-023.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;993&quot; data-original-width=&quot;1023&quot; height=&quot;387&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8Pig0FOPHw0ngacNONYmBWK95LEahGUzgpQJ3FlpvRGgLQ27tu5tyHaPbm7WNCkBwJR-2DF0eJ7wlDTRYAPZkkdYqMG7MXyny3_Zo5urokVIPfAFeZlL8jfMm51aYmE3STGO6L6eCL18/s400/20200308-023.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟13：回頭再測試最後結果。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMKwzIMkE1AuNdycLLyd3RAjEp0QfEgNq5ZKnA3T16xNIYonyDvFGp7HXFhx2QJIWvDFW-WtpZYLdXeL5cWuG8cq9doaFiqFcoIeRFgdhhImZcZax7M08vlQeSXJNndLfmMFcJaittX04/s1600/20200308-024.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;857&quot; data-original-width=&quot;353&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMKwzIMkE1AuNdycLLyd3RAjEp0QfEgNq5ZKnA3T16xNIYonyDvFGp7HXFhx2QJIWvDFW-WtpZYLdXeL5cWuG8cq9doaFiqFcoIeRFgdhhImZcZax7M08vlQeSXJNndLfmMFcJaittX04/s400/20200308-024.png&quot; width=&quot;163&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
到這裡已經完成所有的Line Bot的基本設定了。&lt;br /&gt;
&lt;br /&gt;
幾個地方需注意：&lt;br /&gt;
1.步驟7的「Channel access token」跟「Channel secret」一定要先設定，如此步驟9才能順利驗證成功。&lt;br /&gt;
2. 步驟9的「Webhook URL」需要從步驟7中取得，在repl.it 的專案執行後才能產生URL。&lt;br /&gt;
3.步驟10的程式碼，需等步驟9完成驗後，再輸入置專案，不然執行驗證URL將無法驗證成功。&lt;br /&gt;
4.在步驟9的URL，「/callback」與步驟2程式碼中第23行相關。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/525564344213763321/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2020/03/python-replit-line-bot-1.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/525564344213763321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/525564344213763321'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2020/03/python-replit-line-bot-1.html' title='Python 在 repl.it 建立Line Bot (1)  - 與Line機器人簡易對談'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeP2vY-bQo0R0Axkwm4GH99LQsZwB_TaimDg7WFxVc4IWIr7e8PdCD9lCdZqZ1BSs-L3uAEETnridcyJl4HmQI1Jjv0vtfjPX8UHhH5616WSSY29ImDbMr0xtzcvIFOkmao7UrCfTZrZs/s72-c/20200308-001.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-1965003297748117912</id><published>2020-03-07T10:00:00.001-08:00</published><updated>2020-03-07T10:36:40.086-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Flask"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Python + Flask 在本機端電腦上開發網路應用程式</title><content type='html'>Flask 是一個使用 Python 撰寫的輕量級 Web 應用程式框架，由於其輕量特性，也稱為 micro-framework（微框架），用Flask 在本機端電腦上建立一個簡易的網路應用程式，使用環境為Windows 7 32位元。&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;步驟 1：安裝 Flask，開啟「命令提示字元」，輸入以下指令。
&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;pip install flask&lt;/pre&gt;
若出現以下畫面，請更新pip後再重新安裝flask。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZDtEDw5DvpjycXYMq1cf3WZgis5i84CGiwFQryir4UaGA54ArMqpZ5eBcGko2jIj0PQqKY2B9R2-T7agnRyY6TF9yHPi9paSfFNUuKzXKbEiHv58avLCXQeSV1c-U8V5OWcOodFVPBWA/s1600/20200308-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;554&quot; data-original-width=&quot;677&quot; height=&quot;326&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZDtEDw5DvpjycXYMq1cf3WZgis5i84CGiwFQryir4UaGA54ArMqpZ5eBcGko2jIj0PQqKY2B9R2-T7agnRyY6TF9yHPi9paSfFNUuKzXKbEiHv58avLCXQeSV1c-U8V5OWcOodFVPBWA/s400/20200308-1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2IEht8RIQJuGsRGpQ_uqlugJ83V7a6kIe8qzxqMQrpumoLdJa1liuI6ruDMjVnQtOfsMdAsLVTevY_VA9YwFI-aAif5OF-T0DT8IpTfXItWAamBdb-GanStA_EUy1mO1BNpjKxCOKfGU/s1600/20200308-2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;442&quot; data-original-width=&quot;677&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2IEht8RIQJuGsRGpQ_uqlugJ83V7a6kIe8qzxqMQrpumoLdJa1liuI6ruDMjVnQtOfsMdAsLVTevY_VA9YwFI-aAif5OF-T0DT8IpTfXItWAamBdb-GanStA_EUy1mO1BNpjKxCOKfGU/s400/20200308-2.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟 2： 編寫Python程式，儲存到C:\python資料夾下(資料夾請自行建立)，檔名hello.py，並設定對外服務窗口在8080。
&lt;br /&gt;
&lt;pre class=&quot;brush:py&quot;&gt;from flask import Flask, request

app = Flask(__name__)

@app.route(&#39;/&#39;)
def hello():
    name = request.args.get(&quot;name&quot;, &quot;World&quot;)
    return f&#39;Hello, {name}!&#39;

app.run(host=&#39;0.0.0.0&#39;, port=8080)
&lt;/pre&gt;
&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;注意&lt;/b&gt;&lt;/span&gt;：程式碼010行的port若修改，則後面瀏覽器的連結port也必須同步變更。&lt;br /&gt;
&lt;br /&gt;
步驟 3：設定Flask執行的檔案到環境變數「FLASK_APP」中(大小寫不影響)，在C:\python下，開啟「命令提示字元」，輸入以下指令。&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;set FLASK_APP=hello.py
&lt;/pre&gt;
&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;注意&lt;/b&gt;&lt;/span&gt;：檔案路徑要指定對，可以絕對路徑做為設定，這裡的做法是直接在C:\python執行，所以可直接設定。&lt;br /&gt;
&lt;br /&gt;
步驟 4：執行Flask網路應用程式服務，在「命令提示字元」，輸入以下指令。
&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;python -m flask run
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5tRm6-x9b7PERuYTNxgTFTg21u_kSTnRlg2LlmUkDEDaR5U5fYTfqlOTcN-zUkHISgniiyPdcU950-mTY6NawmnlycEpnQ-lmVX-YpbjvLhPhWbu53Y3oJUKaKWYLDpq-1mI9BKXw7s8/s1600/20200308-3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;442&quot; data-original-width=&quot;677&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5tRm6-x9b7PERuYTNxgTFTg21u_kSTnRlg2LlmUkDEDaR5U5fYTfqlOTcN-zUkHISgniiyPdcU950-mTY6NawmnlycEpnQ-lmVX-YpbjvLhPhWbu53Y3oJUKaKWYLDpq-1mI9BKXw7s8/s400/20200308-3.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟 5：查看結果，開啟瀏覽器，輸入「127.0.0.1:8080」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKHA1W_Dhw-0pKBw72qtOa4oEyzMP-j51axU9UDW9i4u8EcOR4Cpd3h9Q0S0fUzugCbE5ZkxQGhb40-iHZK99oin-j1Qg4t_ZvN95Cjq0lckTDZe-KZiEe5MzBbbzn4knFZukhqSKFCWo/s1600/20200308-4.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;481&quot; data-original-width=&quot;753&quot; height=&quot;255&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKHA1W_Dhw-0pKBw72qtOa4oEyzMP-j51axU9UDW9i4u8EcOR4Cpd3h9Q0S0fUzugCbE5ZkxQGhb40-iHZK99oin-j1Qg4t_ZvN95Cjq0lckTDZe-KZiEe5MzBbbzn4knFZukhqSKFCWo/s400/20200308-4.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
也可以觀察「命令提示字元」顯示的畫面，確認有封包連進來。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifxiAI-f8mwCHRIZR9tOhDp_Z5J38NOYnNsUaiFGJLel2X2BSb8FN5sR4itq-y7fKHIc9_cQhgdvOWAUD_V6m836mvBwqF-mQ4uDwumkBurUszwCqruP_fZ2KlrI8aGB9Tqwp5cHDfodY/s1600/20200308-5.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;442&quot; data-original-width=&quot;677&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifxiAI-f8mwCHRIZR9tOhDp_Z5J38NOYnNsUaiFGJLel2X2BSb8FN5sR4itq-y7fKHIc9_cQhgdvOWAUD_V6m836mvBwqF-mQ4uDwumkBurUszwCqruP_fZ2KlrI8aGB9Tqwp5cHDfodY/s400/20200308-5.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
若要中斷網路應用程式執行可按鍵盤「Ctrl + C」。&lt;br /&gt;
接著在hello.py中多加一個「test」函數，並指定在瀏覽器連結的URL中要多一個hello。&lt;br /&gt;
&lt;pre class=&quot;brush:py&quot;&gt;from flask import Flask, request

app = Flask(__name__)

@app.route(&#39;/&#39;)
def hello():
    name = request.args.get(&quot;name&quot;, &quot;World&quot;)
    return f&#39;Hello, {name}!&#39;
    
@app.route(&#39;/hello&#39;)
def test():
    return &#39;Test Hello, World!&#39;

app.run(host=&#39;0.0.0.0&#39;, port=8080)
&lt;/pre&gt;
&lt;br /&gt;
在重新啟動Flask網路應用程式服務。&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;python -m flask run
&lt;/pre&gt;
&lt;br /&gt;
最後查看瀏覽器與「命令提示字元」。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJF92O9sj8ho-gFhrQVoRotNIeRGoYq7CexUE7nkdSxQzdrSDuMZ_B8G3Tm1KIKOZYrQNUbr6vbVGyej-diVjDwAkMfalxBDTQeePOymnmZ_eW9grgs4PX40mDa7cUVS-jcwncZUeLhpE/s1600/20200308-6.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;657&quot; data-original-width=&quot;753&quot; height=&quot;348&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJF92O9sj8ho-gFhrQVoRotNIeRGoYq7CexUE7nkdSxQzdrSDuMZ_B8G3Tm1KIKOZYrQNUbr6vbVGyej-diVjDwAkMfalxBDTQeePOymnmZ_eW9grgs4PX40mDa7cUVS-jcwncZUeLhpE/s400/20200308-6.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
整個執行操作。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghREMxOG3mWFP0-Q1EEEJT0N7BAF9G6QjvfWQ9__bJOCthpF48EoJ9TU3nuku5p0Rw6ByJYUz0ugI8s5OslKXMXwxb4zsjxGEkdF7c36V-WsBw504XG5TrNbMEBsFCKOuyF0uTPlncqYI/s1600/20200308-1.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;806&quot; data-original-width=&quot;1177&quot; height=&quot;273&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghREMxOG3mWFP0-Q1EEEJT0N7BAF9G6QjvfWQ9__bJOCthpF48EoJ9TU3nuku5p0Rw6ByJYUz0ugI8s5OslKXMXwxb4zsjxGEkdF7c36V-WsBw504XG5TrNbMEBsFCKOuyF0uTPlncqYI/s400/20200308-1.gif&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/1965003297748117912/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2020/03/python-flask.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/1965003297748117912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/1965003297748117912'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2020/03/python-flask.html' title='Python + Flask 在本機端電腦上開發網路應用程式'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZDtEDw5DvpjycXYMq1cf3WZgis5i84CGiwFQryir4UaGA54ArMqpZ5eBcGko2jIj0PQqKY2B9R2-T7agnRyY6TF9yHPi9paSfFNUuKzXKbEiHv58avLCXQeSV1c-U8V5OWcOodFVPBWA/s72-c/20200308-1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-1123481373791458485</id><published>2020-02-04T08:42:00.003-08:00</published><updated>2020-02-05T08:34:38.496-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>健保特約藥局查詢</title><content type='html'>近期肺炎話題很熱，昨天2/3行政院發佈了一則新聞，2/6後口罩只能在健保特約藥局購買，為方便大家可以順利找尋居家附近區域的健保特約藥局所在位置，用Python寫了一個簡單的查詢程式，希望對大家有幫助查尋。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrMWGafgoIo9qqSAYXrcAsQpxuAX3usNPZ4VAbVwEOJOR_CHXmJULiAxj-fl2Cq75903N2-r6ejoCl1qhedrcrznJh-eNhPKf6NcZlPN9_XMZ6GGFA97xSBdWZFhIgAcr46Fz2lfzMP50/s1600/20200204-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1005&quot; data-original-width=&quot;1088&quot; height=&quot;368&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrMWGafgoIo9qqSAYXrcAsQpxuAX3usNPZ4VAbVwEOJOR_CHXmJULiAxj-fl2Cq75903N2-r6ejoCl1qhedrcrznJh-eNhPKf6NcZlPN9_XMZ6GGFA97xSBdWZFhIgAcr46Fz2lfzMP50/s400/20200204-1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
連結：&lt;a href=&quot;http://www.nhi.gov.tw/QueryN/Query3.aspx&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;http://www.nhi.gov.tw/QueryN/Query3.aspx&lt;/a&gt;
&lt;/div&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;Python程式碼。&lt;br /&gt;
&lt;pre class=&quot;brush:py&quot;&gt;import requests
import pandas as pd
from bs4 import BeautifulSoup as bs

url = &quot;http://www.nhi.gov.tw/QueryN/Query3.aspx&quot;
res = requests.get(url)
soup = bs(res.text, &#39;lxml&#39;)

sle = soup.select(&#39;#ctl00_ContentPlaceHolder1_ddlCountyAreaCode option&#39;)
df = []
for val in sle:
    tmp = []
    if len(val[&#39;value&#39;]) &amp;gt; 0:
        tmp.append(val[&#39;value&#39;])
        tmp.append(val.text)
    df.append(tmp)
CountyAreaCode = pd.DataFrame(df)
CountyAreaCode = CountyAreaCode.drop([0])

payload ={
    &#39;ctl00$ContentPlaceHolder1$ddlCountyAreaCode&#39;: &#39;01&#39;
}

for ele in soup.select(&#39;input[type==hidden]&#39;):
    payload[ele[&#39;name&#39;]] = ele[&#39;value&#39;]
    
res = requests.post(url, data=payload)
soup  = bs(res.text, &quot;lxml&quot;)    
sle = soup.select(&#39;#ctl00_ContentPlaceHolder1_ddlTownAreaCode option&#39;)
df = []
for val in sle:
    tmp = []
    if len(val[&#39;value&#39;]) &amp;gt; 0:
        tmp.append(val[&#39;value&#39;])
        tmp.append(val.text)
    df.append(tmp)
TownAreaCode = pd.DataFrame(df)
TownAreaCode = TownAreaCode.drop([0])

df1 = []
for Townid, Town in zip(TownAreaCode[0], TownAreaCode[1]):
    payload[&#39;ctl00$ContentPlaceHolder1$ddlTownAreaCode&#39;] = Townid
    payload[&#39;ctl00$ContentPlaceHolder1$ddlSpecialCode&#39;] = &#39;5&#39;
    payload[&#39;ctl00$ContentPlaceHolder1$tbxPageNum&#39;] = 999
    payload[&#39;ctl00$ContentPlaceHolder1$btnSubmit&#39;] = &#39;開始查詢&#39;
    for ele in soup.select(&#39;input[type==hidden]&#39;):
        payload[ele[&#39;name&#39;]] = ele[&#39;value&#39;]
    res = requests.post(url, data=payload)
    soup  = bs(res.text, &quot;lxml&quot;)
    tb = soup.select(&#39;table&#39;)[2]
    df0 = pd.read_html(tb.prettify(&#39;utf8&#39;), encoding = &#39;utf8&#39;, header = 0)[0]
    df0 = df0[pd.notnull(df0[&#39;地址&#39;])].iloc[:, 0:3]
    df0.insert(0, &#39;行政區&#39;, Town)
    df1.append(df0)
    
pd.set_option(&quot;display.max_rows&quot;, None)
df = pd.concat(df1)
df = df.reset_index(drop=True)
df.to_csv(&quot;健保特約藥局.csv&quot;)
df
&lt;/pre&gt;
執行結果：&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTbwsDEQUfkTW45QIyoJ8bqWJwaceIuphpzCPZelMd_pwSAvVmq6FV1GqHXdv17655DN8LbZ-yHLkJ67VIDi3x-iX6d2HHU2SqR526HKvhXJVNH1N9qLrLtdR9BfCgFz66fca93pVEwqg/s1600/20200204-2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;761&quot; data-original-width=&quot;712&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTbwsDEQUfkTW45QIyoJ8bqWJwaceIuphpzCPZelMd_pwSAvVmq6FV1GqHXdv17655DN8LbZ-yHLkJ67VIDi3x-iX6d2HHU2SqR526HKvhXJVNH1N9qLrLtdR9BfCgFz66fca93pVEwqg/s400/20200204-2.png&quot; width=&quot;373&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
18行：CountyAreaCode為個縣市列表。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXjFHkbJmpnQLx_qocNzd6n2xWPQb58KLco21idewbyiVCHcGC4zwLbTrDv7qUjaPCxRIetfajvJ7RRCZOlq9G07U8RSWyV6c0mjzKDbn5RtJ_f4vnAxbrB9K14YROvtSpnDk0c5q1D-Q/s1600/20200204-3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;595&quot; data-original-width=&quot;234&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXjFHkbJmpnQLx_qocNzd6n2xWPQb58KLco21idewbyiVCHcGC4zwLbTrDv7qUjaPCxRIetfajvJ7RRCZOlq9G07U8RSWyV6c0mjzKDbn5RtJ_f4vnAxbrB9K14YROvtSpnDk0c5q1D-Q/s400/20200204-3.png&quot; width=&quot;156&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
38行：TownAreaCode為行政區列表。&lt;br /&gt;
&lt;br /&gt;
注意：為避免部分Python開發環境無法正常執行，在24行、46行的程式碼 input[type==hidden] 可改為&amp;nbsp;input[type=hidden]&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/1123481373791458485/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2020/02/2326python-httpwww.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/1123481373791458485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/1123481373791458485'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2020/02/2326python-httpwww.html' title='健保特約藥局查詢'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrMWGafgoIo9qqSAYXrcAsQpxuAX3usNPZ4VAbVwEOJOR_CHXmJULiAxj-fl2Cq75903N2-r6ejoCl1qhedrcrznJh-eNhPKf6NcZlPN9_XMZ6GGFA97xSBdWZFhIgAcr46Fz2lfzMP50/s72-c/20200204-1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-2484667354488804036</id><published>2020-01-27T02:18:00.003-08:00</published><updated>2020-01-30T23:08:47.029-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Postman"/><title type='text'>PostMan 開啟程式遇到黑畫面解法</title><content type='html'>最近使用Postman桌機板，遇到開啟程式時會變成黑畫面，而且一直無法順利開啟，這樣的問題困擾我一段時，想說是版本問題，所以不斷的更新版本但始終無法解決問題，終於在今天花一間時間找Google大神幫忙決。
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpsaPfFrNudhOjMypExZG54Qn_z1nKPQqeBtlK9lX4P7XsgatCb12-hQo7JMnLQiwkaoZASOzRrx2jF8Kd1D5MWJVV1FLm0duyXMEZSYi7cJKzda__RT-Ij1nUZLbd0pRgHjWwFxlZ19c/s1600/20200127-0.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;801&quot; data-original-width=&quot;1062&quot; height=&quot;301&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpsaPfFrNudhOjMypExZG54Qn_z1nKPQqeBtlK9lX4P7XsgatCb12-hQo7JMnLQiwkaoZASOzRrx2jF8Kd1D5MWJVV1FLm0duyXMEZSYi7cJKzda__RT-Ij1nUZLbd0pRgHjWwFxlZ19c/s400/20200127-0.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;網路上有很多解決PostMan開啟時會遇到黑畫面的方法，如：&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot; , &amp;quot;serif&amp;quot;; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 新細明體; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;&quot;&gt;移除&lt;/span&gt;PostMan&lt;span style=&quot;font-family: , serif;&quot;&gt;後，刪除&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;%AppData%&lt;/span&gt;&lt;span style=&quot;font-family: , serif;&quot;&gt;下&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;Local&lt;/span&gt;&lt;span style=&quot;font-family: , serif;&quot;&gt;資料夾中的&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;postman&lt;/span&gt;&lt;span style=&quot;font-family: , serif;&quot;&gt;資料夾和&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;Roaming&lt;/span&gt;&lt;span style=&quot;font-family: , serif;&quot;&gt;資料夾下的&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;postman&lt;/span&gt;&lt;span style=&quot;font-family: , serif;&quot;&gt;資料夾，然後重新安裝。&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: , serif;&quot;&gt;以管理員權限方式執行&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
這些方法都無法有效解決PostMan開啟時會遇到黑畫面的問題，最後找到一個可是成功的方法，就是在系統設定新增一環境變數 POSTMAN_DISABLE_GPU = true，即可成功開啟PostMan。&lt;br /&gt;
如下操作步驟。&lt;br /&gt;
步驟1：開啟系統內容。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_sxF3gEUTyvMOiiRz4Qilz3foTDSlGSqpP1wSXlmBthT-zWGa0oex-8C1AbmFLln_bZZHuEpMuB-vymhEgeqgvS1gbgz9bDQYj5wMZkiaUTyIkX-dIE-awjQ9OfoGFslIYrWaIT9Hnos/s1600/20200127-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;457&quot; data-original-width=&quot;420&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_sxF3gEUTyvMOiiRz4Qilz3foTDSlGSqpP1wSXlmBthT-zWGa0oex-8C1AbmFLln_bZZHuEpMuB-vymhEgeqgvS1gbgz9bDQYj5wMZkiaUTyIkX-dIE-awjQ9OfoGFslIYrWaIT9Hnos/s320/20200127-1.png&quot; width=&quot;294&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟2：新增環境變數。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAmf8GkO5VYbo5S01s9BPoqNlLZzVYMMGEt4QHa8DrUm_ON9wzWwKE1HlRru7c0floJ2VoD-sMA9XYkTWh4Lfaa566FOMCAMCbLFCo58yS42MzEoSw4H0R9ka7flaT5a7LWFeUF_cLAqM/s1600/20200127-2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;406&quot; data-original-width=&quot;394&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAmf8GkO5VYbo5S01s9BPoqNlLZzVYMMGEt4QHa8DrUm_ON9wzWwKE1HlRru7c0floJ2VoD-sMA9XYkTWh4Lfaa566FOMCAMCbLFCo58yS42MzEoSw4H0R9ka7flaT5a7LWFeUF_cLAqM/s320/20200127-2.png&quot; width=&quot;310&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟3：輸入變數名稱、變數值。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUnRVpkKJ98MY7c-2geA9e43XF8HUGJbLh09rCHFDFK9_H_ePv7BQpUZe8iHVokP4K1s0oXN9kASqi6sTV5X8cg7UcuDUyfTfAb-PZ7lGyCG-lcCSmFu8gwRGgj4uL2Dx26D2UqghQyNQ/s1600/20200127-3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;145&quot; data-original-width=&quot;357&quot; height=&quot;129&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUnRVpkKJ98MY7c-2geA9e43XF8HUGJbLh09rCHFDFK9_H_ePv7BQpUZe8iHVokP4K1s0oXN9kASqi6sTV5X8cg7UcuDUyfTfAb-PZ7lGyCG-lcCSmFu8gwRGgj4uL2Dx26D2UqghQyNQ/s320/20200127-3.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
步驟4：重新開啟PostMan。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFGEjSSQ1g0g-LNxh5LOB1iEmIBjqShrmFoLBiqt5TWiS7h8DPgHL3pjDNy3munrlNa8w53LbqePMgZyw0T5mVNpZ2EJzQRcFldasxG2ArNypL2vw1u9q0oXyJ-i4DzoIEAVoBlqpnBLA/s1600/20200127-4.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;400&quot; data-original-width=&quot;400&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFGEjSSQ1g0g-LNxh5LOB1iEmIBjqShrmFoLBiqt5TWiS7h8DPgHL3pjDNy3munrlNa8w53LbqePMgZyw0T5mVNpZ2EJzQRcFldasxG2ArNypL2vw1u9q0oXyJ-i4DzoIEAVoBlqpnBLA/s320/20200127-4.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvD4idEyOxUfNeSpkgj6VjjtRQvQA2vQ__8ciF2YDoXLejMqD_7vX4w0P2jeOsqykS7Y4VNxRNhhe-WlRZfKQsZKqxPEBin4TdfR8yaTK7ZWs2WrMBSfJMe43FsUmOyUVq34qDNbsXHc8/s1600/20200127-5.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;800&quot; data-original-width=&quot;1280&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvD4idEyOxUfNeSpkgj6VjjtRQvQA2vQ__8ciF2YDoXLejMqD_7vX4w0P2jeOsqykS7Y4VNxRNhhe-WlRZfKQsZKqxPEBin4TdfR8yaTK7ZWs2WrMBSfJMe43FsUmOyUVq34qDNbsXHc8/s320/20200127-5.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
參考資料：
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.csdn.net/Tonylaoshi/article/details/89340870&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Postman无法正常启动解决办法&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/2484667354488804036/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2020/01/postman.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/2484667354488804036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/2484667354488804036'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2020/01/postman.html' title='PostMan 開啟程式遇到黑畫面解法'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpsaPfFrNudhOjMypExZG54Qn_z1nKPQqeBtlK9lX4P7XsgatCb12-hQo7JMnLQiwkaoZASOzRrx2jF8Kd1D5MWJVV1FLm0duyXMEZSYi7cJKzda__RT-Ij1nUZLbd0pRgHjWwFxlZ19c/s72-c/20200127-0.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-3701203458817125786</id><published>2019-12-13T08:59:00.001-08:00</published><updated>2019-12-13T20:39:31.044-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Python：pyecharts 數據可視覺化套件 v0.1.9.5</title><content type='html'>在查找用於 Python 上繪製儀表板的過程中，偶然見到了一個著名可視覺化、互動式繪圖套件 pyecharts，pyecharts是一個用於產生 Echarts 圖表的類庫，Echarts 是百度開源的一個資料視覺化 JS 函式庫。&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;注意以下二點：&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;pyecharts在開發時分為了 v0.5.X 和 v1 兩個大版本，v0.5.X 和 v1 間並不相容。&lt;/li&gt;
&lt;li&gt;v0.5.X 的版本支持python2.7，3.4+，但不再進行維護，v1的版本僅支持python3.6+。&lt;/li&gt;
&lt;/ol&gt;
基於以上介紹，這裡先以 pyecharts v0.1.9.5版本介紹，後續再另外發文介紹pyecharts v1.X 版本，安裝 pyecharts v0.1.9.5 如以下操作。&lt;br /&gt;
&lt;br /&gt;
在命令提示字元中輸入以下指令&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;pip install pyecharts==0.1.9.5
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPGPKeNNn1DQfb6Of4NW1RXGBOa3eWymvc2lp5EuwCDYOQVjANSoiJHUzV07vVEusIOu0bo7Jo6aAui4wwktKihgenYVXqgoYRrOgBK_okTHdcf9pEBB8Sx2WDJzXxiLrSqRSUc9Ueaxc/s1600/20191213-5.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;634&quot; data-original-width=&quot;677&quot; height=&quot;373&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPGPKeNNn1DQfb6Of4NW1RXGBOa3eWymvc2lp5EuwCDYOQVjANSoiJHUzV07vVEusIOu0bo7Jo6aAui4wwktKihgenYVXqgoYRrOgBK_okTHdcf9pEBB8Sx2WDJzXxiLrSqRSUc9Ueaxc/s400/20191213-5.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
安裝pyecharts v0.1.9.5過程發生錯誤，畫面提示需安裝 jupyter-pip 套件。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOjYhWwb4BlGDusBMJq05fd-MqssouxuhlOGKeqXWIMF_zRrv8fyoBKyQm3VFNQOh7tvYdX8rjU_bVUoWylYGJJ8-zPLLxC4dkfYwx2cn4EGKXVr0uqvzOOvWFqFWzmSHcm6jLK9P07XM/s1600/20191213-6.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;634&quot; data-original-width=&quot;677&quot; height=&quot;373&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOjYhWwb4BlGDusBMJq05fd-MqssouxuhlOGKeqXWIMF_zRrv8fyoBKyQm3VFNQOh7tvYdX8rjU_bVUoWylYGJJ8-zPLLxC4dkfYwx2cn4EGKXVr0uqvzOOvWFqFWzmSHcm6jLK9P07XM/s400/20191213-6.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
安裝 jupyter-pip 套件，輸入以下命令。&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;pip install jupyter-pip
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD84QU7wEBCqigz5VVPPSocVjS72ksXwGQK_jp5xyu2ZsMboaaGQ0Nee54JfEVVZwzhyphenhyphenZcjhr1Pmyo5HFou2Po7ZXa0sED6IBtyZnw94-lMmUDIEILLJzuBx8_2sMzIuI5PV41dbs6qkg/s1600/20191213-7.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;634&quot; data-original-width=&quot;677&quot; height=&quot;373&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD84QU7wEBCqigz5VVPPSocVjS72ksXwGQK_jp5xyu2ZsMboaaGQ0Nee54JfEVVZwzhyphenhyphenZcjhr1Pmyo5HFou2Po7ZXa0sED6IBtyZnw94-lMmUDIEILLJzuBx8_2sMzIuI5PV41dbs6qkg/s400/20191213-7.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
安裝完成後執行安裝 pyecharts v0.1.9.5。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixv4gfVWZWIUdlpBXCN4CI3t3vjIWw8iBm_NOJIYPYH1OAj_0ztNsmOolr7CtYfYMpMCt7Lq6P6gpZytIHJGiTLDTdnodHiXqNQ_kGjFdBLaEy4w2idEWmiYuE-y-M4nELiVJaQmc95DI/s1600/20191213-8.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;746&quot; data-original-width=&quot;677&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixv4gfVWZWIUdlpBXCN4CI3t3vjIWw8iBm_NOJIYPYH1OAj_0ztNsmOolr7CtYfYMpMCt7Lq6P6gpZytIHJGiTLDTdnodHiXqNQ_kGjFdBLaEy4w2idEWmiYuE-y-M4nELiVJaQmc95DI/s400/20191213-8.png&quot; width=&quot;362&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
到此成功安裝 pyecharts v0.1.9.5。&lt;br /&gt;
&lt;br /&gt;
接著開啟 Jupyert notebook，輸入以下程式碼來畫圖。&lt;br /&gt;
&lt;br /&gt;
長條圖&lt;br /&gt;
&lt;pre class=&quot;brush:py&quot;&gt;import pandas as pd
import numpy as np
from pyecharts import Bar

title=&#39;長條圖&#39;
index = pd.date_range(&#39;01/02/2019&#39;, periods = 10, freq = &#39;M&#39;)
df1 = pd.DataFrame(np.random.randn(10), index=index)
df2 = pd.DataFrame(np.random.randn(10), index=index)

seq1 = [&quot;{:.2f}&quot;.format(i[0]*100) for i in df1.values]
seq2 = [&quot;{:.2f}&quot;.format(i[0]*100) for i in df2.values]
_index = [i for i in df1.index.format()]

bar = Bar(title, &quot;每月賺賠&quot;)
bar.add(&#39;獲利&#39;, _index, seq1)
bar.add(&#39;虧損&#39;, _index, seq2)
bar.render(path=&#39;bar.html&#39;)
bar&lt;/pre&gt;
第17行：輸出一個可互動式的網頁。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh68xfIvVdYPrBUMnmIlNZyEieygNdNX1Lvug0tCFHwbjZltqDhJVaXGWPf5dPkl4XkcLieVlyEryhyv8I1iqUomt2ITeTrNVmWm-U4nE56KXjW4GEjGIJRM4Sl0uvTcb-P5ot1MXBT-10/s1600/20191213-9.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;746&quot; data-original-width=&quot;1123&quot; height=&quot;265&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh68xfIvVdYPrBUMnmIlNZyEieygNdNX1Lvug0tCFHwbjZltqDhJVaXGWPf5dPkl4XkcLieVlyEryhyv8I1iqUomt2ITeTrNVmWm-U4nE56KXjW4GEjGIJRM4Sl0uvTcb-P5ot1MXBT-10/s400/20191213-9.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/3701203458817125786/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2019/12/pythonpyecharts-v0195.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/3701203458817125786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/3701203458817125786'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2019/12/pythonpyecharts-v0195.html' title='Python：pyecharts 數據可視覺化套件 v0.1.9.5'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPGPKeNNn1DQfb6Of4NW1RXGBOa3eWymvc2lp5EuwCDYOQVjANSoiJHUzV07vVEusIOu0bo7Jo6aAui4wwktKihgenYVXqgoYRrOgBK_okTHdcf9pEBB8Sx2WDJzXxiLrSqRSUc9Ueaxc/s72-c/20191213-5.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-947112875936710355</id><published>2019-12-12T22:52:00.000-08:00</published><updated>2019-12-12T22:53:58.169-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Python：抓取政府資料開放平台JSON資料存入SQLite</title><content type='html'>Python中抓取 JSON 與解析 JSON 可以很快速，這裡以「&lt;a href=&quot;https://data.gov.tw/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;政府資料開放平台&lt;/a&gt;」的「&lt;a href=&quot;https://data.gov.tw/dataset/42215&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;宜蘭縣加油站資料&lt;/a&gt;」資料為例，將抓取後的JSON存入SQLite中。&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;以 Python 取回資料JSON，資料格式為 List 類型。&lt;br /&gt;
&lt;pre class=&quot;brush:py&quot;&gt;import requests
url = &quot;http://www.ilepb.gov.tw/api/ILEPB01001/format/JSON&quot;
jd = requests.get(url).json()
jd
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOClP0pcK17hS7n0Aae-SSTJviNLxFho6v1PRaTJlUAZRv8uMrypkV6Oefj0mOfHcHMHoo_ZlTHvoiRD5_UjP1BMxIe9d4wHLojr5jsxvi3TVgzJXftzeoExKHkTD9dzAa5oSTCP7Ka3s/s1600/20191213-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;666&quot; data-original-width=&quot;842&quot; height=&quot;316&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOClP0pcK17hS7n0Aae-SSTJviNLxFho6v1PRaTJlUAZRv8uMrypkV6Oefj0mOfHcHMHoo_ZlTHvoiRD5_UjP1BMxIe9d4wHLojr5jsxvi3TVgzJXftzeoExKHkTD9dzAa5oSTCP7Ka3s/s400/20191213-1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
資料格式為List，所以可以直接放到 Pandas 中&lt;br /&gt;
&lt;pre class=&quot;brush:py&quot;&gt;import requests
import pandas as pd

url = &quot;http://www.ilepb.gov.tw/api/ILEPB01001/format/JSON&quot;
jd = requests.get(url).json()
df = pd.DataFrame(jd)
df = df.set_index(&#39;加油站名稱&#39;)
df.head()
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6qC0gerFJcFrBLbK_oDhvtsWKeJ4zccK9Psc1jmtu2WuLQnrWk2FP6dLw2BrltjL2Db0RtD0d2zbhqH3crPdWjLJsYxpNByvGcMDiKtDGUo3HjDesp5vSHHLr4y1Voyqy3zNjZlZAN8o/s1600/20191213-2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;295&quot; data-original-width=&quot;847&quot; height=&quot;138&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6qC0gerFJcFrBLbK_oDhvtsWKeJ4zccK9Psc1jmtu2WuLQnrWk2FP6dLw2BrltjL2Db0RtD0d2zbhqH3crPdWjLJsYxpNByvGcMDiKtDGUo3HjDesp5vSHHLr4y1Voyqy3zNjZlZAN8o/s400/20191213-2.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
最後寫入SQLite中，並取出資料。&lt;br /&gt;
&lt;pre class=&quot;brush:py&quot;&gt;import sqlite3
conn = sqlite3.connect(&quot;gas.sqlite3&quot;)
df.to_sql(&#39;point&#39;, conn, if_exists=&#39;replace&#39;)
df = pd.read_sql(&quot;select * from point&quot;, conn, index_col=[&#39;加油站名稱&#39;])
df.head()
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHyK3mZktVnle0b9Aj7bdFeEe34oogYGPMBmQp_cDVnE8PsuG3V-RSBPLuumFD0yULQwdZdal1ayZE1Xzi5Cq04zA42iATsODAhVCPX1JozOiGcSXdCJnNkBENLjr96GUmhuIMc2CSzlw/s1600/20191213-3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;259&quot; data-original-width=&quot;846&quot; height=&quot;121&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHyK3mZktVnle0b9Aj7bdFeEe34oogYGPMBmQp_cDVnE8PsuG3V-RSBPLuumFD0yULQwdZdal1ayZE1Xzi5Cq04zA42iATsODAhVCPX1JozOiGcSXdCJnNkBENLjr96GUmhuIMc2CSzlw/s400/20191213-3.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
上面兩部分的寫法做一下結合就可以完成抓取資料到SQLite的Python程式碼。&lt;br /&gt;
&lt;br /&gt;
最後提供另一種寫法完成這一回合的介紹，由於資料格式為JSON，而 Pandas 有支援直接讀取JSON，因此我們可直接改用 Pandas 來完成。&lt;br /&gt;
&lt;pre class=&quot;brush:py&quot;&gt;import requests
import pandas as pd
import sqlite3

url = &quot;http://www.ilepb.gov.tw/api/ILEPB01001/format/JSON&quot;
df = pd.read_json(url)
df = df.set_index(&#39;加油站名稱&#39;)
conn = sqlite3.connect(&quot;gas.sqlite3&quot;)
df.to_sql(&#39;point&#39;, conn, if_exists=&#39;replace&#39;)
df = pd.read_sql(&quot;select * from point&quot;, conn, index_col=[&#39;加油站名稱&#39;])
df.head()
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYloDEnx7qn8Oh3dBUB0iXMq9pK1b6W4DdbC1LJo_mdBX4S6SIihef7F9GM5RpcYgKN-uU5Uj5i7Qh1suZMjKMO5MgKfpOglCwFt65ZhYRe6PbaneuFkIX2rJEGTEliBmnGACj0yWoRmk/s1600/20191213-4.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;330&quot; data-original-width=&quot;842&quot; height=&quot;156&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYloDEnx7qn8Oh3dBUB0iXMq9pK1b6W4DdbC1LJo_mdBX4S6SIihef7F9GM5RpcYgKN-uU5Uj5i7Qh1suZMjKMO5MgKfpOglCwFt65ZhYRe6PbaneuFkIX2rJEGTEliBmnGACj0yWoRmk/s400/20191213-4.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/947112875936710355/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2019/12/pythonjsonsqlite.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/947112875936710355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/947112875936710355'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2019/12/pythonjsonsqlite.html' title='Python：抓取政府資料開放平台JSON資料存入SQLite'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOClP0pcK17hS7n0Aae-SSTJviNLxFho6v1PRaTJlUAZRv8uMrypkV6Oefj0mOfHcHMHoo_ZlTHvoiRD5_UjP1BMxIe9d4wHLojr5jsxvi3TVgzJXftzeoExKHkTD9dzAa5oSTCP7Ka3s/s72-c/20191213-1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-991097078106415189</id><published>2019-12-08T18:21:00.003-08:00</published><updated>2019-12-08T18:47:24.391-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Excel"/><category scheme="http://www.blogger.com/atom/ns#" term="VBA"/><title type='text'>Excel VBA：資料篩選、進階篩選</title><content type='html'>假日幫網友處理一個跟保險有關的案例，初步需求是要從資料去篩選出姓名，當使用者用姓名篩選後，找出其他相關的人跟地址，該網友本身有寫VBA程式碼，但每天執行需要40分鐘~1小時，需求是需要能優化過程，目前以網路公開資料來進行操作，資料來源為 &lt;a href=&quot;https://cand.moi.gov.tw/of/index.jsp&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;地方公職人員資訊服務網&lt;/a&gt;，從這裡下載資料在進行修改與模擬該相關需求。&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;由於資料僅有一張表(如：&lt;a href=&quot;https://drive.google.com/file/d/18r4XAD4IKqRsjF45-h8VeQSHO-rPG_Ut/view?usp=sharing&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;檔案連結&lt;/a&gt;中的工作表：「全部資料」)，僅能以此作為查詢依據，至於其真實性這裡將不作考究，只針對需求來做說明。&lt;br /&gt;
需求內容如下：&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;以「姓名」選出相關的「地址」，該「地址」可能會出現於資料中其他行，且會是另一人的「姓名」。&lt;/li&gt;
&lt;li&gt;再以另一人的「姓名」選出其他相關的「地址」，相同方式循環找，直到所有相關「姓名」與「地址」都不在新增為止。&lt;/li&gt;
&lt;/ol&gt;
基於以上需求內容，我將藉由篩選方式來減少迴圈的使用，搭配「高階篩選」、「移除重複」、「資料驗證」等，程式碼來處理。&lt;br /&gt;
&lt;br /&gt;
程式運作流程：
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;檔案開啟時，觸發「Workbook_Open」事件對「鄉鎮市」進行過濾，過濾並移除重複數值，用以建立第一層資料清單。&lt;/li&gt;
&lt;li&gt;當使用者對「鄉鎮市」切換時，觸發「Workbook_SheetChange」事件，在指定工作表與儲存格位置後，可針對「鄉鎮市」挑選出不重複的「姓名」作為清單。&lt;/li&gt;
&lt;li&gt;當使用者對「姓名」切換，觸發「Workbook_SheetChange」事件，在「全部資料」進行篩選查詢。&lt;/li&gt;
&lt;li&gt;選出來後再逐一以「地址」進行查詢其他相關「姓名」。&lt;/li&gt;
&lt;li&gt;「姓名」選出後再以「姓名」查詢「地址」，如此循環直到不在出現新的「姓名」或「地址」為止。&lt;/li&gt;
&lt;/ol&gt;
以下就是檔案中相關的程式碼。&lt;br /&gt;
在VBE的ThisWorkbook中貼上以下程式碼。&lt;br /&gt;
&lt;pre class=&quot;brush:vb&quot;&gt;Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Workbooks(1).Sheets(1).Cells.Clear
    Workbooks(1).Save
End Sub

Private Sub Workbook_Open()
    第一層清單產生
End Sub

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
    If Sh.Name = &quot;資料顯示&quot; Then
        If Target.Address = &quot;$A$1&quot; Then
            第二層清單產生
        ElseIf Target.Address = &quot;$B$1&quot; Then
            If Len(Sh.Range(Target.Address)) Then
                以姓名過濾出地址
                Do
                以地址選出親屬
                Loop While 以親屬姓名選出地址
                
                最後結果傳至第一張工作表
            End If
        End If
    End If
End Sub
&lt;/pre&gt;
&lt;br /&gt;
在VBE添加Module1並貼上以下程式碼。
&lt;br /&gt;
&lt;pre class=&quot;brush:vb&quot;&gt;Sub 第一層清單產生()
    Dim listcount1 As Integer
    
    Workbooks(1).Sheets(3).Columns(1).Clear
    
    &#39;進階過濾篩選出不重複的鄉鎮市
    With Workbooks(1).Sheets(2)
        .Range(&quot;C:C&quot;).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Workbooks(1).Sheets(3).Range(&quot;A1&quot;), Unique:=True
    End With
    
    &#39;賦予資料區域名稱為list1，等於是名稱管理員的設定
    With Workbooks(1).Sheets(3)
        .Range(Cells(2, &quot;A&quot;).Address, .Cells(Rows.count, &quot;A&quot;).End(xlUp).Address).Name = &quot;list1&quot;
    End With
    
    &#39;設定&quot;資料驗證&quot;中的清單
    With Workbooks(1).Sheets(1).Range(&quot;A1&quot;).Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
             Operator:=xlBetween, Formula1:=&quot;=list1&quot;
    End With
End Sub

Sub 第二層清單產生()
    Dim listcount1 As Integer
    
    Workbooks(1).Sheets(3).Columns(2).Clear
    
    以鄉鎮市過濾出姓名
    
    &#39;進階過濾篩選出不重複的姓名
    With Workbooks(1).Sheets(4)
        .Range(&quot;A:A&quot;).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Workbooks(1).Sheets(3).Range(&quot;B1&quot;), Unique:=True
        .Cells.Clear
    End With
    
    &#39;賦予資料區域名稱為list2，等於是名稱管理員的設定
    With Workbooks(1).Sheets(3)
        .Range(Cells(2, &quot;B&quot;).Address, .Cells(Rows.count, &quot;B&quot;).End(xlUp).Address).Name = &quot;list2&quot;
    End With
    
    &#39;設定&quot;資料驗證&quot;中的清單
    With Workbooks(1).Sheets(1).Range(&quot;B1&quot;)
        .Clear
        With .Validation
            .Delete
            .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
                 Operator:=xlBetween, Formula1:=&quot;=list2&quot;
        End With
    End With
End Sub

Sub 以鄉鎮市過濾出姓名()
    Dim tmp, line
    Dim i As Integer, count As Integer
    
    With Workbooks(1).Sheets(2)
        With .UsedRange
            &#39;鄉鎮市篩選
            .AutoFilter Field:=.Cells(1, &quot;C&quot;).column, Criteria1:=&quot;=&quot; &amp;amp; Sheets(1).Cells(1, 1)
            
            &#39;選出符合條件的資料
            Set tmp = .Resize(.Rows.count - 1).SpecialCells(xlCellTypeVisible)
            count = 1
            For Each line In tmp.Areas
                For i = 1 To line.Rows.count
                    Sheets(4).Cells(count, 1).Value = line(i, 5).Value
                    count = count + 1
                Next
            Next
        End With
        
        &#39;關閉篩選
        .AutoFilterMode = False
    End With
End Sub

Sub 以姓名過濾出地址()
    Dim tmp, line
    Dim i As Integer, j As Integer, count As Integer, column As Integer
    
    Workbooks(1).Sheets(4).Cells.Clear
    With Workbooks(1).Sheets(2)
        column = .Cells(1, Columns.count).End(xlToLeft).column
        With .UsedRange
            &#39;姓名篩選
            .AutoFilter Field:=.Cells(1, &quot;E&quot;).column, Criteria1:=&quot;=&quot; &amp;amp; Sheets(1).Cells(1, 2)
            
            &#39;選出符合條件的資料
            Set tmp = .Resize(.Rows.count - 1).SpecialCells(xlCellTypeVisible)
            count = 1
            For Each line In tmp.Areas
                For i = 1 To line.Rows.count
                    For j = 1 To column
                        Sheets(4).Cells(count, j).Value = line(i, j).Value
                    Next
                    
                    &#39;取得符合條件的資料所在列位置
                    Sheets(4).Cells(count, column + 1).Value = line.Rows.row() + i - 1
                    If line.Rows.row() = 1 And Sheets(4).Cells(count, column + 1) = 1 Then
                        Sheets(4).Cells(count, column + 1) = &quot;行號&quot;
                    End If
                    count = count + 1
                Next
            Next
        End With
        
        &#39;關閉篩選
        .AutoFilterMode = False
    End With
End Sub

Sub 以地址選出親屬()
    Dim tmp, line
    Dim i As Integer, j As Integer, k As Integer, count As Integer, column As Integer, row As Integer
    
    With Workbooks(1).Sheets(2)
        column = .Cells(1, Columns.count).End(xlToLeft).column
        With .UsedRange
            row = Sheets(4).Cells(Rows.count, 1).End(xlUp).row
            count = row + 1
            For k = 2 To row
                &#39;地址篩選
                .AutoFilter Field:=.Cells(1, &quot;G&quot;).column, Criteria1:=&quot;=&quot; &amp;amp; Sheets(4).Cells(k, 7)
                
                &#39;選出符合條件的資料
                Set tmp = .Offset(1).Resize(.Rows.count - 1).SpecialCells(xlCellTypeVisible)
                For Each line In tmp.Areas
                    For i = 1 To line.Rows.count
                        For j = 1 To column
                            Sheets(4).Cells(count, j).Value = line(i, j).Value
                        Next
                        
                        &#39;取得符合條件的資料所在列位置
                        Sheets(4).Cells(count, column + 1).Value = line.Rows.row() + i - 1
                        count = count + 1
                    Next
                Next
            Next
        End With
        
        &#39;關閉篩選
        .AutoFilterMode = False
    End With
    
    &#39;針對重複資料進行移除
    row = Workbooks(1).Sheets(4).Cells(Rows.count, 1).End(xlUp).row
    column = Workbooks(1).Sheets(4).Cells(1, Columns.count).End(xlToLeft).column
    
    ReDim col(0 To column - 1)
    For i = 0 To column - 1
        col(i) = i + 1
    Next
    Workbooks(1).Sheets(4).Range(&quot;A1:J&quot; &amp;amp; row).RemoveDuplicates Columns:=(col), Header:=xlYes
    Workbooks(1).Sheets(3).Cells(1, 30) = Workbooks(1).Sheets(4).Cells(Rows.count, 1).End(xlUp).row
End Sub

Function 以親屬姓名選出地址()
    Dim tmp, line
    Dim i As Integer, j As Integer, k As Integer, count As Integer, column As Integer, row As Integer
    
    With Workbooks(1).Sheets(2)
        column = .Cells(1, Columns.count).End(xlToLeft).column
        With .UsedRange
            row = Sheets(4).Cells(Rows.count, 1).End(xlUp).row
            count = row + 1
            For k = 2 To row
                &#39;親屬姓名篩選
                .AutoFilter Field:=.Cells(1, &quot;E&quot;).column, Criteria1:=&quot;=&quot; &amp;amp; Sheets(4).Cells(k, 5)
                
                &#39;選出符合條件的資料
                Set tmp = .Offset(1).Resize(.Rows.count - 1).SpecialCells(xlCellTypeVisible)
                For Each line In tmp.Areas
                    For i = 1 To line.Rows.count
                        For j = 1 To column
                            Sheets(4).Cells(count, j).Value = line(i, j).Value
                        Next
                        
                        &#39;取得符合條件的資料所在列位置
                        Sheets(4).Cells(count, column + 1).Value = line.Rows.row() + i - 1
                        count = count + 1
                    Next
                    
                Next
            Next
        End With
        
        &#39;關閉篩選
        .AutoFilterMode = False
    End With
    
    &#39;針對重複資料進行移除
    row = Workbooks(1).Sheets(4).Cells(Rows.count, 1).End(xlUp).row
    Workbooks(1).Sheets(4).Range(&quot;A1:J&quot; &amp;amp; row).RemoveDuplicates Columns:=Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), Header:=xlYes
    
    以親屬姓名選出地址 = False
    Workbooks(1).Sheets(3).Cells(1, 31) = Workbooks(1).Sheets(4).Cells(Rows.count, 1).End(xlUp).row
    If Workbooks(1).Sheets(3).Cells(1, 30) &amp;lt;&amp;gt; Workbooks(1).Sheets(3).Cells(1, 31) Then
        以親屬姓名選出地址 = True
    End If
End Function

Sub 最後結果傳至第一張工作表()
    Dim row As Integer, column As Integer
    
    With Workbooks(1).Sheets(1)
        row = .Cells(Rows.count, 1).End(xlUp).row
        If row &amp;lt; 5 Then row = 5
        .Rows(&quot;5:&quot; &amp;amp; row).Clear
    End With
    
    With Workbooks(1).Sheets(4)
        row = .Cells(Rows.count, 1).End(xlUp).row
        column = .Cells(1, Columns.count).End(xlToLeft).column
        Workbooks(1).Sheets(1).Cells(5, 1).Resize(row, column).Value = .Cells(1, 1).Resize(row, column).Value
    End With
End Sub
&lt;/pre&gt;
&lt;br /&gt;
執行結果：&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqHZ_r_dFKo_u2P15Bg6y3hZeDfB0QMdDiE0mFiMB0IXyR3SsUOuI5D03xwoVZseLPmZLVgBhaVFF9YgCXOJJlrv_ZjKX3jbP21alrVn3KnrBw5BaClhlRhB5lQaTgZu8eyIhNpLCOC2U/s1600/20191208-1.gif&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;920&quot; data-original-width=&quot;1472&quot; height=&quot;250&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqHZ_r_dFKo_u2P15Bg6y3hZeDfB0QMdDiE0mFiMB0IXyR3SsUOuI5D03xwoVZseLPmZLVgBhaVFF9YgCXOJJlrv_ZjKX3jbP21alrVn3KnrBw5BaClhlRhB5lQaTgZu8eyIhNpLCOC2U/s1600/20191208-1.gif&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTY2t8OWPzv5rIPshjr9dSHLBOM5lAu0UFQN03d6IF3QTvP2BuDnluzYV_nYrX7BddQJX9ZBYLsEQ3QqI423LoSmFw8FTmsoQQ7RwT7kbfq08anSjTHzJG1qNJVpyDjEx2jP_tmB0FED8/s1600/20191208-2.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;944&quot; data-original-width=&quot;1432&quot; height=&quot;262&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTY2t8OWPzv5rIPshjr9dSHLBOM5lAu0UFQN03d6IF3QTvP2BuDnluzYV_nYrX7BddQJX9ZBYLsEQ3QqI423LoSmFw8FTmsoQQ7RwT7kbfq08anSjTHzJG1qNJVpyDjEx2jP_tmB0FED8/s400/20191208-2.gif&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a href=&quot;https://drive.google.com/file/d/18r4XAD4IKqRsjF45-h8VeQSHO-rPG_Ut/view?usp=sharing&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;檔案連結&lt;/a&gt;。</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/991097078106415189/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2019/12/excel-vba_8.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/991097078106415189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/991097078106415189'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2019/12/excel-vba_8.html' title='Excel VBA：資料篩選、進階篩選'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqHZ_r_dFKo_u2P15Bg6y3hZeDfB0QMdDiE0mFiMB0IXyR3SsUOuI5D03xwoVZseLPmZLVgBhaVFF9YgCXOJJlrv_ZjKX3jbP21alrVn3KnrBw5BaClhlRhB5lQaTgZu8eyIhNpLCOC2U/s72-c/20191208-1.gif" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-1890570651127095184</id><published>2019-12-05T08:29:00.000-08:00</published><updated>2019-12-05T19:29:06.722-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Excel"/><category scheme="http://www.blogger.com/atom/ns#" term="VBA"/><title type='text'>Excel VBA：陣列對儲存格(Array to Range)、儲存格對陣列(Range to Array)、儲存格對儲存格(Range to Range) (1)</title><content type='html'>在 Excel VBA 中，很多人對於陣列數值瑱到儲存格常會混淆，為此舉幾個範例讓大家可以清楚了解陣列填值的寫法。&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;以下為2種常見的一維陣列對儲存格填值方式。&lt;br /&gt;
第一種：陣列無指定起始&lt;br /&gt;
&lt;pre class=&quot;brush:vb&quot;&gt;Sub 陣列無指定起始()
    Dim a(3) As Integer, i As Integer
    
    For i = 1 To 3
        a(i) = i
    Next
    Sheets(1).Cells.Clear
    Sheets(1).Cells(1, 1).Resize(, UBound(a) + 1).Value = a
    Sheets(1).Cells(3, 1).Resize(UBound(a) + 1).Value = Application.Transpose(a)
End Sub
&lt;/pre&gt;
執行畫面與結果：
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5LFx_UnWFf61DSTRPHNbpkWRIAsq84WGz01AWkc_0YXth-wTEnJGo__LhQ2uB_RgFqNFEiXtombXnMaCkpsGrPheemSZ8H4V2RsOlwsLra3vRV5XX-49cdTuQpOgff4YU4GJXSzL6bco/s1600/20191205-4.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;816&quot; data-original-width=&quot;1321&quot; height=&quot;246&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5LFx_UnWFf61DSTRPHNbpkWRIAsq84WGz01AWkc_0YXth-wTEnJGo__LhQ2uB_RgFqNFEiXtombXnMaCkpsGrPheemSZ8H4V2RsOlwsLra3vRV5XX-49cdTuQpOgff4YU4GJXSzL6bco/s400/20191205-4.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
第二種：陣列有指定起始&lt;br /&gt;
&lt;pre class=&quot;brush:vb&quot;&gt;Sub 陣列有指定起始()
    Dim a(1 To 3) As Integer, i As Integer
    
    For i = 1 To 3
        a(i) = i
    Next
    Sheets(1).Cells.Clear
    Sheets(1).Cells(1, 1).Resize(, UBound(a) + 1).Value = a
    Sheets(1).Cells(3, 1).Resize(UBound(a) + 1).Value = Application.Transpose(a)
End Sub
&lt;/pre&gt;
執行畫面與結果：
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqgn0U2VPk5IEOrB8yC3INDoMUAsXwDN1Cg1IsN63iuWPF25GHYQ_LqlRjnDkOWXblzxxwxZS7yRNMmy7Qyf_4KIj7eHPKFUBK0GV9ppngAGgyRl3fwbzy4PlUZNAYYYraTGIy1Ekq6GE/s1600/20191205-5.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;816&quot; data-original-width=&quot;1321&quot; height=&quot;246&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqgn0U2VPk5IEOrB8yC3INDoMUAsXwDN1Cg1IsN63iuWPF25GHYQ_LqlRjnDkOWXblzxxwxZS7yRNMmy7Qyf_4KIj7eHPKFUBK0GV9ppngAGgyRl3fwbzy4PlUZNAYYYraTGIy1Ekq6GE/s400/20191205-5.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
以下為3種常見的二維陣列對儲存格填值方式。&lt;br /&gt;
第一種：陣列宣告，Row與Column起始皆未指定
&lt;br /&gt;
&lt;pre class=&quot;brush:vb&quot;&gt;Sub 陣列Row與Column起始皆未指定()
    Dim a(2, 3) As Integer, i As Integer, j As Integer
    
    For i = 1 To 2
        For j = 1 To 3
            a(i, j) = i * j
        Next
    Next
    Sheets(1).Cells.Clear
    Sheets(1).Cells(1, 1).Resize(UBound(a) + 1, UBound(a, 2) + 1).Value = a
End Sub&lt;/pre&gt;
執行畫面與結果：
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyy-sExXy9OekrHvffqzGSWWQLLPzNaQDa_I0jTaw_EzEBN6DWZ3vwEsxjELIHA0eDEXaGBupXXpfazBTWRDund4IUulTj0wJNohynpJB9lU2RBz16boowsQNsUgBbsnd9aMAsl9J0Pao/s1600/20191205-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;893&quot; data-original-width=&quot;1368&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyy-sExXy9OekrHvffqzGSWWQLLPzNaQDa_I0jTaw_EzEBN6DWZ3vwEsxjELIHA0eDEXaGBupXXpfazBTWRDund4IUulTj0wJNohynpJB9lU2RBz16boowsQNsUgBbsnd9aMAsl9J0Pao/s400/20191205-1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
第二種：陣列宣告，Row起始指定1與Column起始未指定
&lt;br /&gt;
&lt;pre class=&quot;brush:vb&quot;&gt;Sub 陣列Row起始指定1與Column起始未指定()
    Dim a(1 To 2, 3) As Integer, i As Integer, j As Integer
    
    For i = 1 To 2
        For j = 1 To 3
            a(i, j) = i * j
        Next
    Next
    Sheets(1).Cells.Clear
    Sheets(1).Cells(1, 1).Resize(UBound(a) + 1, UBound(a, 2) + 1).Value = a
End Sub
&lt;/pre&gt;
執行畫面與結果：
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGSf8Zoq05QknY1ykETrF3xkv5XDs8HuZqqmSTz1BhNpOVpvstwvxEn3d7tPkM3xnGmNYYBHnD3m1tKHCx8d55zPlFVOL0K0XUObIclnnblDBtZz-Jnrck1h84lj-O_dE1E1A0MjVLrps/s1600/20191205-2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;893&quot; data-original-width=&quot;1368&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGSf8Zoq05QknY1ykETrF3xkv5XDs8HuZqqmSTz1BhNpOVpvstwvxEn3d7tPkM3xnGmNYYBHnD3m1tKHCx8d55zPlFVOL0K0XUObIclnnblDBtZz-Jnrck1h84lj-O_dE1E1A0MjVLrps/s400/20191205-2.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
第三種：陣列宣告，Row起始指定1與Column起始指定1
&lt;br /&gt;
&lt;pre class=&quot;brush:vb&quot;&gt;Sub 陣列Row起始指定1與Column起始指定1()
    Dim a(1 To 2, 1 To 3) As Integer, i As Integer, j As Integer
    
    For i = 1 To 2
        For j = 1 To 3
            a(i, j) = i * j
        Next
    Next
    Sheets(1).Cells.Clear
    Sheets(1).Cells(1, 1).Resize(UBound(a) + 1, UBound(a, 2) + 1).Value = a
End Sub
&lt;/pre&gt;
執行畫面與結果：
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuPwmdfqwT_TxjqL3d9XC8L-HcC7FwpuBVLPtCfaxehM6CtcRWCNMFQusfduGETIcTjYGneDQaX4Vt2ofphVt6l-pd0SkgkCwROcZt5jwF0KJ42qApy2z_N9-BVVef5d5sxsZ7onzo0Tc/s1600/20191205-3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;893&quot; data-original-width=&quot;1368&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuPwmdfqwT_TxjqL3d9XC8L-HcC7FwpuBVLPtCfaxehM6CtcRWCNMFQusfduGETIcTjYGneDQaX4Vt2ofphVt6l-pd0SkgkCwROcZt5jwF0KJ42qApy2z_N9-BVVef5d5sxsZ7onzo0Tc/s400/20191205-3.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
以上陣列對儲存格填值方式，請注意陣列宣告方式不同，其他部分相同，如此將導致不同的果，各位可以自行偵錯查看其中的變化。&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1ADlIpUnqDJdDAouY4y4t_hoq3cHVRBkO/view?usp=sharing&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;檔案連結&lt;/a&gt;。</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/1890570651127095184/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2019/12/excel-vba.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/1890570651127095184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/1890570651127095184'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2019/12/excel-vba.html' title='Excel VBA：陣列對儲存格(Array to Range)、儲存格對陣列(Range to Array)、儲存格對儲存格(Range to Range) (1)'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5LFx_UnWFf61DSTRPHNbpkWRIAsq84WGz01AWkc_0YXth-wTEnJGo__LhQ2uB_RgFqNFEiXtombXnMaCkpsGrPheemSZ8H4V2RsOlwsLra3vRV5XX-49cdTuQpOgff4YU4GJXSzL6bco/s72-c/20191205-4.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-3794230974831165575</id><published>2019-11-30T01:28:00.001-08:00</published><updated>2019-11-30T01:39:34.962-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Google Apps Script"/><category scheme="http://www.blogger.com/atom/ns#" term="Google Spreadsheet"/><title type='text'>Google Apps Script 入門到進階(21) --- 取得工作表的最後一筆資料的位置</title><content type='html'>在寫 Google Apps Script 中，常會需要抓取工作表會後一筆資料的時候，在 Google Apps Script&amp;nbsp;有提供&amp;nbsp;getLastRow() 函數，但這函數只針對整個工作表抓取最後一筆資料的位置，若只想取得某一個範圍的最後一筆資料，那就不是很方便使用了，所以需要另外寫程式碼處理，這部分就以下面的程式碼來完成，只要指定工作表與範圍的字串，就可以完成Excel VBA的效果一樣。
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;以下Google Apps Script 程式碼，其效果等同於Excel VBA。&lt;br /&gt;
&lt;pre class=&quot;brush:vb&quot;&gt;Sheets(1).Cells(Rows.Count, 1).End(xlUp).Row
&lt;/pre&gt;
&lt;br /&gt;
Google Apps Script 取最後一筆資料的寫法。&lt;br /&gt;
寫法 1：&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt;//////////////////////////////////////////////////////////////
//
//sheet：為Google工作表SpreadsheetApp.getActiveSpreadsheet()
//column：為工作表中指定的儲存格範圍的字串
//
//////////////////////////////////////////////////////////////
function getLastRow(sheet, column)
{
  //var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  //var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(&quot;工作表名&quot;);
  
  //指定儲存格範圍
  var rng = sheet.getRange(column).getValues();
  var lrIndex;

  //取得最後一個有資料的Row位置
  for(var i = rng.length - 1 ; i &amp;gt;= 0 ; i--)
  {
 if(!rng[i].every(function(c){ return c == &quot;&quot;;}))
 {
      lrIndex = i;
      break;
    }
  }
  return lrIndex + 1;
}
&lt;/pre&gt;
寫法 2：&lt;br /&gt;
&lt;pre class=&quot;brush:js&quot;&gt;//////////////////////////////////////////////////////////////
//
//sheet：為Google工作表SpreadsheetApp.getActiveSpreadsheet()
//column：為工作表中指定的儲存格範圍的字串
//
//////////////////////////////////////////////////////////////
function getLastRow(sheet, column){
  //取得工作表最後一筆資料
  var numRows = sheet.getLastRow();
  
  //取得範圍資料
  var data = sheet.getRange(1, column, numRows).getValues();
  
  //從最後面找出資料出現的位置就是最後一筆資料的位置
  for(var i = data.length - 1 ; i &amp;gt;= 0 ; i--){
    if (data[i][0] != null &amp;amp;&amp;amp; data[i][0] != &quot;&quot;){
      return i + 1;
    }
  }
}
&lt;/pre&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/3794230974831165575/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2019/11/google-apps-script-21.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/3794230974831165575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/3794230974831165575'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2019/11/google-apps-script-21.html' title='Google Apps Script 入門到進階(21) --- 取得工作表的最後一筆資料的位置'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5413673165485961878.post-4400749508681083220</id><published>2019-11-23T02:08:00.001-08:00</published><updated>2019-11-25T18:31:09.613-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Excel"/><category scheme="http://www.blogger.com/atom/ns#" term="VBA"/><title type='text'>Excel VBA：Excel 儲存格資料進行陣列順序反轉</title><content type='html'>在Excel VBA中常會遇到要將資料進行反轉的操作，在Exce VBA中最常見的做法就是使用for迴圈來進行，VBA中雖然有陣列可使用，但卻陣列可用的操作方式又很有限，像是資料反向操作、資料排序等皆無提供，需另外使用for迴圈或其他方式處理，以下介紹已for迴圈與「System.Collections.ArrayList」物件進行陣列反轉。&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
方法1：不使用for迴圈，改以「System.Collections.ArrayList」作法&lt;br /&gt;
&lt;pre class=&quot;brush:vb&quot;&gt;Sub 方法1不使用for迴圈()
    Dim i As Long, count As Long
    Dim coll As Object
    Dim a
    Dim t As Long
    
    count = Sheets(1).Cells(1, 2)
    
    t = Timer
    
    Sheets(1).Rows(&quot;3:65535&quot;).Clear
    
    For i = 1 To count
        Sheets(1).Cells(i + 2, 1) = i
    Next

    a = Sheets(1).Cells(3, 1).Resize(count).Value

    Set coll = CreateObject(&quot;System.Collections.ArrayList&quot;)
    With coll
        &#39;清除前一次操作的暫存，做加速用
        .Clear
        
        &#39;只能用字串進行反轉
        For Each q In a
            .Add CStr(q)
        Next
        
        &#39;反轉
        .Reverse

        Sheets(1).Cells(3, 2).Resize(count, 1) = Application.Transpose(.ToArray)
        Sheets(1).Cells(3, 3).Resize(1, count) = .ToArray
    End With
    Set coll = Nothing
    MsgBox Format(Timer - t, &quot;0.00&quot;) &amp;amp; &quot;秒&quot;
End Sub
&lt;/pre&gt;
方法2：使用for迴圈&lt;br /&gt;
&lt;pre class=&quot;brush:vb&quot;&gt;Sub 方法2使用for迴圈()
    Dim i As Long, count As Long
    Dim a, b()
    Dim t As Long
    
    count = Sheets(1).Cells(1, 2)

    t = Timer
    
    Sheets(1).Rows(&quot;3:65535&quot;).Clear
    
    For i = 1 To count
        Sheets(1).Cells(i + 2, 1) = i
    Next
    
    a = Sheets(1).Cells(3, 1).Resize(count).Value
    
    ReDim b(count - 1)
    For i = count To 1 Step -1
        b(count - i) = a(i, 1)
    Next
    
    Sheets(1).Cells(3, 2).Resize(count, 1) = Application.Transpose(b)
    Sheets(1).Cells(3, 3).Resize(1, count) = b
    Erase b
    MsgBox Format(Timer - t, &quot;0.00&quot;) &amp;amp; &quot;秒&quot;
End Sub
&lt;/pre&gt;
程式碼執行畫面&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrdkrscxrfkeu2IIEhW8YYQfeBMSmJI8OuDJRqt2ou8guTDndbhQ03hRFeqwGLZEXrqRMZ_nSAa6JpI5-7iimF-Og4m6VGvur0IafW1vz6wlbeOzVfu-94NzNkgExSUF3buBDO0rCX1j4/s1600/20191123-1.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;889&quot; data-original-width=&quot;1181&quot; height=&quot;300&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrdkrscxrfkeu2IIEhW8YYQfeBMSmJI8OuDJRqt2ou8guTDndbhQ03hRFeqwGLZEXrqRMZ_nSAa6JpI5-7iimF-Og4m6VGvur0IafW1vz6wlbeOzVfu-94NzNkgExSUF3buBDO0rCX1j4/s400/20191123-1.gif&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1DeO16N1M1Xp8TlAu5iD8zilglWf14vo-/view&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;檔案連結&lt;/a&gt;。</content><link rel='replies' type='application/atom+xml' href='http://white5168.blogspot.com/feeds/4400749508681083220/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://white5168.blogspot.com/2019/11/excel-vbaexcel.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/4400749508681083220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5413673165485961878/posts/default/4400749508681083220'/><link rel='alternate' type='text/html' href='http://white5168.blogspot.com/2019/11/excel-vbaexcel.html' title='Excel VBA：Excel 儲存格資料進行陣列順序反轉'/><author><name>Amin</name><uri>http://www.blogger.com/profile/09251026691092691913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrdkrscxrfkeu2IIEhW8YYQfeBMSmJI8OuDJRqt2ou8guTDndbhQ03hRFeqwGLZEXrqRMZ_nSAa6JpI5-7iimF-Og4m6VGvur0IafW1vz6wlbeOzVfu-94NzNkgExSUF3buBDO0rCX1j4/s72-c/20191123-1.gif" height="72" width="72"/><thr:total>0</thr:total></entry></feed>