跳到主要內容

[Python爬蟲教學]學會使用Selenium及BeautifulSoup套件爬取查詢式網頁

python_integrate_selenium_and_beautifulsoup
Photo by Austin Distel on Unsplash
在多樣化的網頁中,為了避免一次載入大量的資料影響執行效能,除了可以使用分頁,或像電子商務及社群平台,透過滾動捲軸的方式動態載入資料外,另一種常見的做法,就是增加查詢的功能。

常見的查詢式網頁,舉例來說,像是訂票系統,在網頁載入時,並不會把所有的時刻票劵資訊顯示出來,而是需要使用者指定想要購買的時刻,點擊查詢後,才會載入資料。如果想要利用Python網頁爬蟲爬取這種查詢類型的網頁,該如何實作呢?

本文以臺灣證券交易所的「個股日收盤價及月平均價查詢式網頁為例,分享如何整合Python的selenium及beautifulsoup套件,自動化指定查詢條件,並且爬取查詢結果。其中的實作重點包含:
  • 「個股日收盤價及月平均價」網頁分析
  • 安裝selenium及beautifulsoup套件
  • selenium自動化指定查詢條件
  • beautifulsoup爬取查詢結果

一、「個股日收盤價及月平均價」網頁分析

臺灣證券交易所的「個股日收盤價及月平均價」,主要用來提供使用者查詢個股在指定的年月中,每日的收盤價及月平均價,如下圖:
python_integrate_selenium_and_beautifulsoup
如果有多檔股票需要分析,相信使用人工的方式來進行查詢及下載,會花費不少的時間,而透過Python網頁爬蟲,將會大幅提升取得資料的效率。

從上圖中可以看到,網頁分為查詢條件及結果,而指定查詢條件的部分,就需要使用Python的selenium自動化套件,來模仿使用者輸入年、月、股票代碼及點擊查詢按鈕,有了查詢結果後,即可利用Python的beautifulsoup套件,解析HTML原始碼,取得所需的資料。

二、安裝selenium及beautifulsoup套件

本文以Visual Studio Code為例,在Terminal視窗中利用以下的指令來安裝Python的selenium、beautifulsoup及webdriver-manager套件
$ pip install selenium

$ pip install beautifulsoup4

$ pip install webdriver-manager
其中,webdriver-manager套件是用來協助selenium套件,在執行Python網頁爬蟲時,自動下載瀏覽器的驅動程式(Webdriver)。

三、selenium自動化指定查詢條件

新增scraper.py檔案,引用剛剛所下載的beautifulsoup、selenium、webdriver及time模組(Module),如下範例
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from webdriver_manager.chrome import ChromeDriverManager
import time
為了要能夠自動化操作個股日收盤價及月平均價」查詢條件的年月下拉選單,所以範例中就需引用selenium套件的Select模組(Module),如上範例第3行。

接著,建立一個股票類別(Stock),其中包含建構式(Constructor)及爬取「個股日收盤價及月平均價」的daily方法(Method),如下範例
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from webdriver_manager.chrome import ChromeDriverManager
import time

class Stock:
    def __init__(self, *stock_numbers):
        self.stock_numbers = stock_numbers

    def daily(self, year, month):
	pass
其中,建構式(Constructor)為了提供使用者能夠傳入多檔股票代碼,所以使用*args參數,將傳入的多個股票代碼,打包成元組(Tuple),這樣在後續就能夠透過迴圈的方式,讀取多個股票代碼。

而daily()方法(Method),則包含兩個參數,分別是年份及月份,讓使用者可以彈性的傳入所要查詢的年月。

daily()方法(Method)中,首先,利用webdriver模組(Module)建立瀏覽器物件,其中,使用webdriver-manager模組(Module)自動下載瀏覽器驅動程式,接著,透過selenium套件的get()方法(Method),請求臺灣證券交易所的「個股日收盤價及月平均價」網頁,如下範例
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from webdriver_manager.chrome import ChromeDriverManager
import time

class Stock:
    def __init__(self, *stock_numbers):
        self.stock_numbers = stock_numbers

    def daily(self, year, month):
	browser = webdriver.Chrome(ChromeDriverManager().install())
        browser.get(
            "https://www.twse.com.tw/zh/page/trading/exchange/STOCK_DAY_AVG.html")
接下來,就需要定位查詢條件的資料日期,在年份的地方,點擊滑鼠右鍵,選擇「檢查」,可以看到HTML原始碼如下:
python_integrate_selenium_and_beautifulsoup
這時候,就可以使用selenium套件的find_element_by_name()方法(Method)來進行元素的定位,由於是下拉選單,所以將定位的元素傳入selenium的Select模組(Module)來建立下拉選單物件,進而利用select_by_value()方法(Method),選取使用者所傳入的年份,如下範例
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from webdriver_manager.chrome import ChromeDriverManager
import time

class Stock:
    def __init__(self, *stock_numbers):
        self.stock_numbers = stock_numbers

    def daily(self, year, month):
	browser = webdriver.Chrome(ChromeDriverManager().install())
        browser.get(
            "https://www.twse.com.tw/zh/page/trading/exchange/STOCK_DAY_AVG.html")

        select_year = Select(browser.find_element_by_name("yy"))
        select_year.select_by_value(year)  # 選擇傳入的年份
月份的部分,可以看到HTML原始碼為:
python_integrate_selenium_and_beautifulsoup
同樣使用selenium套件的find_element_by_name()方法(Method)來定位元素,傳入Select模組(Module)建立下拉選單物件,利用select_by_value()方法(Method),選取使用者所傳入的月份,如下範例
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from webdriver_manager.chrome import ChromeDriverManager
import time

class Stock:
    def __init__(self, *stock_numbers):
        self.stock_numbers = stock_numbers

    def daily(self, year, month):
	browser = webdriver.Chrome(ChromeDriverManager().install())
        browser.get(
            "https://www.twse.com.tw/zh/page/trading/exchange/STOCK_DAY_AVG.html")

        select_year = Select(browser.find_element_by_name("yy"))
        select_year.select_by_value(year)  # 選擇傳入的年份

        select_month = Select(browser.find_element_by_name("mm"))
        select_month.select_by_value(month)  # 選擇傳入的月份
而股票代碼,可以看到它的HTML原始碼為:
python_integrate_selenium_and_beautifulsoup

由於不是下拉選單,所以使用selenium套件的find_element_by_name()方法(Method)來定位元素即可,並且利用send_keys()方法(Method)來模擬輸入資料,完成後,呼叫submit()方法(Method)送出,也就是查詢,如下範例
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from webdriver_manager.chrome import ChromeDriverManager
import time

class Stock:
    def __init__(self, *stock_numbers):
        self.stock_numbers = stock_numbers

    def daily(self, year, month):
	browser = webdriver.Chrome(ChromeDriverManager().install())
        browser.get(
            "https://www.twse.com.tw/zh/page/trading/exchange/STOCK_DAY_AVG.html")

        select_year = Select(browser.find_element_by_name("yy"))
        select_year.select_by_value(year)  # 選擇傳入的年份

        select_month = Select(browser.find_element_by_name("mm"))
        select_month.select_by_value(month)  # 選擇傳入的月份

        stockno = browser.find_element_by_name("stockNo")  # 定位股票代碼輸入框
	stockno.send_keys("2330")
	stockno.submit()
Python網頁爬蟲送出查詢條件後,就會產生查詢結果,也就是指定股票的日收盤價及月平均價」,為了避免在查詢等待的期間,Python網頁爬蟲在內容尚未完成就進行爬取,所以可以使用sleep()方法(Method),暫停一下,如下範例
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from webdriver_manager.chrome import ChromeDriverManager
import time

class Stock:
    def __init__(self, *stock_numbers):
        self.stock_numbers = stock_numbers

    def daily(self, year, month):
	browser = webdriver.Chrome(ChromeDriverManager().install())
        browser.get(
            "https://www.twse.com.tw/zh/page/trading/exchange/STOCK_DAY_AVG.html")

        select_year = Select(browser.find_element_by_name("yy"))
        select_year.select_by_value(year)  # 選擇傳入的年份

        select_month = Select(browser.find_element_by_name("mm"))
        select_month.select_by_value(month)  # 選擇傳入的月份

        stockno = browser.find_element_by_name("stockNo")  # 定位股票代碼輸入框
	stockno.send_keys("2330")
	stockno.submit()

        time.sleep(2)

四、beautifulsoup爬取查詢結果

接下來,要爬取查詢結果,就需要把網頁的原始碼,傳入beautifulsoup套件來進行解析,如下範例
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from webdriver_manager.chrome import ChromeDriverManager
import time

class Stock:
    def __init__(self, *stock_numbers):
        self.stock_numbers = stock_numbers

    def daily(self, year, month):
	browser = webdriver.Chrome(ChromeDriverManager().install())
        browser.get(
            "https://www.twse.com.tw/zh/page/trading/exchange/STOCK_DAY_AVG.html")

        select_year = Select(browser.find_element_by_name("yy"))
        select_year.select_by_value(year)  # 選擇傳入的年份

        select_month = Select(browser.find_element_by_name("mm"))
        select_month.select_by_value(month)  # 選擇傳入的月份

        stockno = browser.find_element_by_name("stockNo")  # 定位股票代碼輸入框
	stockno.send_keys("2330")
	stockno.submit()

        time.sleep(2)

        soup = BeautifulSoup(browser.page_source, "lxml")
回到日收盤價及月平均價」網頁,可以看到查詢結果的表格HTML原始碼為:
python_integrate_selenium_and_beautifulsoup
從上圖可以看到,表格(table)擁有id的屬性,所以可以利用beautifulsoup套件的find()方法(Method)來進行定位,如下範例:
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from webdriver_manager.chrome import ChromeDriverManager
import time

class Stock:
    def __init__(self, *stock_numbers):
        self.stock_numbers = stock_numbers

    def daily(self, year, month):
	browser = webdriver.Chrome(ChromeDriverManager().install())
        browser.get(
            "https://www.twse.com.tw/zh/page/trading/exchange/STOCK_DAY_AVG.html")

        select_year = Select(browser.find_element_by_name("yy"))
        select_year.select_by_value(year)  # 選擇傳入的年份

        select_month = Select(browser.find_element_by_name("mm"))
        select_month.select_by_value(month)  # 選擇傳入的月份

        stockno = browser.find_element_by_name("stockNo")  # 定位股票代碼輸入框
	stockno.send_keys("2330")
	stockno.submit()

        time.sleep(2)

        soup = BeautifulSoup(browser.page_source, "lxml")

        table = soup.find("table", {"id": "report-table"})
有了表格(table)物件後,就可以再利用beautifulsoup套件的find_all()方法(Method),取得表格(table)下所有的資料欄位,如下範例
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from webdriver_manager.chrome import ChromeDriverManager
import time

class Stock:
    def __init__(self, *stock_numbers):
        self.stock_numbers = stock_numbers

    def daily(self, year, month):
	browser = webdriver.Chrome(ChromeDriverManager().install())
        browser.get(
            "https://www.twse.com.tw/zh/page/trading/exchange/STOCK_DAY_AVG.html")

        select_year = Select(browser.find_element_by_name("yy"))
        select_year.select_by_value(year)  # 選擇傳入的年份

        select_month = Select(browser.find_element_by_name("mm"))
        select_month.select_by_value(month)  # 選擇傳入的月份

        stockno = browser.find_element_by_name("stockNo")  # 定位股票代碼輸入框
	stockno.send_keys("2330")
	stockno.submit()

        time.sleep(2)

        soup = BeautifulSoup(browser.page_source, "lxml")

        table = soup.find("table", {"id": "report-table"})

        elements = table.find_all(
                "td", {"class": "dt-head-center dt-body-center"})
而要取得資料欄位中的文字,就需要透過迴圈進行讀取,並且利用beautifulsoup套件的getText()方法(Method)來取得,這邊使用Python Comprehension語法,如下範例
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from webdriver_manager.chrome import ChromeDriverManager
import time

class Stock:
    def __init__(self, *stock_numbers):
        self.stock_numbers = stock_numbers

    def daily(self, year, month):
	browser = webdriver.Chrome(ChromeDriverManager().install())
        browser.get(
            "https://www.twse.com.tw/zh/page/trading/exchange/STOCK_DAY_AVG.html")

        select_year = Select(browser.find_element_by_name("yy"))
        select_year.select_by_value(year)  # 選擇傳入的年份

        select_month = Select(browser.find_element_by_name("mm"))
        select_month.select_by_value(month)  # 選擇傳入的月份

        stockno = browser.find_element_by_name("stockNo")  # 定位股票代碼輸入框
	stockno.send_keys("2330")
	stockno.submit()

        time.sleep(2)

        soup = BeautifulSoup(browser.page_source, "lxml")

        table = soup.find("table", {"id": "report-table"})

        elements = table.find_all(
                "td", {"class": "dt-head-center dt-body-center"})
				
	data = [element.getText() for element in elements]
到目前為止,都是查詢一檔股票的實作,而要能夠自動化查詢多檔股票,則需要透過迴圈來重覆執行,如下範例
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from webdriver_manager.chrome import ChromeDriverManager
import time

class Stock:
    def __init__(self, *stock_numbers):
        self.stock_numbers = stock_numbers

    def daily(self, year, month):
	browser = webdriver.Chrome(ChromeDriverManager().install())
        browser.get(
            "https://www.twse.com.tw/zh/page/trading/exchange/STOCK_DAY_AVG.html")

        select_year = Select(browser.find_element_by_name("yy"))
        select_year.select_by_value(year)  # 選擇傳入的年份

        select_month = Select(browser.find_element_by_name("mm"))
        select_month.select_by_value(month)  # 選擇傳入的月份

        stockno = browser.find_element_by_name("stockNo")  # 定位股票代碼輸入框
		
	result = []
        for stock_number in self.stock_numbers:
            stockno.clear()  # 清空股票代碼輸入框
	    stockno.send_keys(stock_number)
	    stockno.submit()

	    time.sleep(2)

	    soup = BeautifulSoup(browser.page_source, "lxml")

	    table = soup.find("table", {"id": "report-table"})

	    elements = table.find_all(
			"td", {"class": "dt-head-center dt-body-center"})
					
	    data = (stock_number,) + tuple(element.getText() for element in elements)
				   
	    result.append(data)

        print(result)
範例中第24行,建立result串列(List),是用來儲存多檔股票的日收盤價及月平均價」。接著,第25行迴圈讀取初始化的多檔股票代碼,其中,在每一次執行時,需先清空上一次查詢的股票代碼的輸入框,才進行股票代碼的輸入及查詢。最後,第39行為了能夠區別每檔股票的資料,所以增加了股票代碼,並且,與爬取的日收盤價及月平均價」轉型為元組(Tuple)打包起來,儲存至result串列(List)中。

接下來,就可以建立Stock物件,並且傳入想查詢的股票代碼來進行初始化,然後,呼教daily()方法(Method),指定年份及月份,來爬取多檔股票的日收盤價及月平均價」,如下範例
stock = Stock('2451', '2454', '2369')  # 建立Stock物件
stock.daily("2019", "7")  # 動態爬取指定的年月份中,股票代碼的每日收盤價
執行結果
[
 ('2451', '108/07/01', '71.70', '108/07/02', '71.30', '108/07/03', '67.70', '108/07/04', '67.50', '108/07/05', '67.80', '108/07/08', '67.70', '108/07/09', '68.70', '108/07/10', '68.60', '108/07/11', '68.10', '108/07/12', '67.70', '108/07/15', '68.00', '108/07/16', '67.60', '108/07/17', '67.30', '108/07/18', '67.00', '108/07/19', '67.40', '108/07/22', '67.00', '108/07/23', '67.50', '108/07/24', '66.90', '108/07/25', '67.50', '108/07/26', '67.40', '108/07/29', '68.20', '108/07/30', '67.80', '108/07/31', '68.00', '月平均收盤價', '68.02'), 
 ('2454', '108/07/01', '314.00', '108/07/02', '319.00', '108/07/03', '317.50', '108/07/04', '319.00', '108/07/05', '321.00', '108/07/08', '314.00', '108/07/09', '313.50', '108/07/10', '318.00', '108/07/11', '322.50', '108/07/12', '318.00', '108/07/15', '314.50', '108/07/16', '314.00', '108/07/17', '310.00', '108/07/18', '302.00', '108/07/19', '304.50', '108/07/22', '308.50', '108/07/23', '314.50', '108/07/24', '308.00', '108/07/25', '313.00', '108/07/26', '313.50', '108/07/29', '319.00', '108/07/30', '325.50', '108/07/31', '314.50', '月平均收盤價', '314.70'), 
 ('2369', '108/07/01', '8.36', '108/07/02', '8.39', '108/07/03', '8.45', '108/07/04', '8.46', '108/07/05', '8.48', '108/07/08', '8.49', '108/07/09', '8.40', '108/07/10', '8.36', '108/07/11', '8.41', '108/07/12', '8.62', '108/07/15', '8.91', '108/07/16', '8.81', '108/07/17', '8.83', '108/07/18', '8.76', '108/07/19', '8.80', '108/07/22', '8.90', '108/07/23', '8.88', '108/07/24', '8.81', '108/07/25', '8.87', '108/07/26', '9.11', '108/07/29', '9.19', '108/07/30', '8.98', '108/07/31', '8.91', '月平均收盤價', '8.70')
]

五、小結

本文的Python網頁爬蟲透過整合selenium及beautifulsoup套件,實現查詢式的網頁資料爬取,對於想要進行大量資料的分析,能夠提升資料取得的效率,讀者不妨利用本文所分享的實作方式,來開發自動化查詢的網頁爬蟲吧。

如果您喜歡我的文章,請幫我按五下Like(使用GoogleFacebook帳號免費註冊),支持我創作教學文章,回饋由LikeCoin基金會出資,完全不會花到錢,感謝大家。

有想要看的教學內容嗎?歡迎利用以下的Google表單讓我知道,將有機會成為教學文章,分享給大家😊

Python網頁爬蟲推薦課程

你可能有興趣的文章

留言

這個網誌中的熱門文章

Python學習資源整理

Photo by Pablo Heimplatz on Unsplash 本文將分享在學習Python的過程中,所參考的學習資源,由於喜歡做中學,所以分享的教學資源大部分都會有應用實作,除了能夠瞭解基本的Python語法外,透過實際的專案開發,可以增加熟悉度,並且從中培養解決問題的能力。而今天分享的Python學習資源,分別有: 網站書籍YouTube頻道線上課程一、網站以下是除了Python官方之外,推薦的教學網站,除了附有範例程式碼說明之外,觀念講解清楚且易於理解,包含: 1.Real Python: Python Tutorials
2.Python Programming Language - GeeksforGeeks
3.ccClub(Coding&Co-working Club)

二、書籍 1.Python初學特訓班(第四版):從快速入門到主流應用全面實戰(附250分鐘影音教學/範例程式)這本書從Python的基本語法教學開始,最後進行幾個應用程式的開發,包含了YouTube、LINE Bot聊天機器人、網頁爬蟲及資訊圖表繪製等Python專案的開發,這也是我非常喜歡的原因,學習任何的程式語言,在學習完基礎語法後,就是要透過實際的專案開發來練習及增加熟悉度,其中的實戰專案也是我目前正在學習的,並且還有附影音教學,非常適合初學者入門或是想要增加自己實戰經驗的開發人員。

2.Python自動化的樂趣:搞定重複瑣碎&單調無聊的工作(第二版)這本書同樣是先介紹Python的基本重要語法,簡潔易懂,不過這裡的專案實作比較是針對Python自動化的處理,包含Web擷取資訊、工作排程、影像圖片處理及Email發送等,是我在開發自動化專案時的參考書籍,實作範例都很實用,適合初學者及對Python自動化處理有興趣的開發人員。

3.Python設計模式實務上在開發專案時,大家都知道需求會隨著業務一直改變,這時候就會有機會修改程式碼,而有好的架構會讓程式碼好維護,相信這是開發人員所追求的,這本書就是介紹Python常用的設計模式(Design Pattern)及設計原則(Design Principle),藉此設計出好維護及簡潔的程式碼,適合進階且已有實務經驗的開發人員,未來在部落格中,會參考本書來分享學習心得。
三、YouTube頻道 1.Programming with …

[Python爬蟲教學]7個Python使用BeautifulSoup開發網頁爬蟲的實用技巧

Photo by Stanley Dai on Unsplash 在實務上開發專案時,很多時候會利用其他網站的資料來進行分析或運用,而取得的方式除了透過網站所提供的API(Application Programming Interface)外,也可以利用Python來開發爬蟲程式,將網頁的HTML內容下載下來,接著利用BeautifulSoup套件(Package),擷取所需的資訊。

本文將開發一個簡單的爬蟲程式,爬取「ETtoday旅遊雲」網頁,擷取桃園旅遊景點的標題資訊,如下圖: 取自ETtoday的旅遊雲 而在開發的過程中,常會需要搜尋HTML的節點,本文將分享幾個常用的方法,包含: BeautifulSoup安裝以HTML標籤及屬性搜尋節點以CSS屬性搜尋節點搜尋父節點搜尋前、後節點取得屬性值取得連結文字一、BeautifulSoup安裝BeautifulSoup是一個用來解析HTML結構的Python套件(Package),將取回的網頁HTML結構,透過其提供的方法(Method),能夠輕鬆的搜尋及擷取網頁上所需的資料,因此廣泛的應用在網頁爬蟲的開發上。

Beautifulsoup套件(Package)可以透過pip指令來進行安裝,如下範例: pip install beautifulsoup4而要解析網頁的HTML程式碼前,還需要安裝Python的requests套件(Package),將要爬取的網頁HTML程式碼取回來,安裝方式如下: pip install requests安裝完成後,首先引用requests套件(Package),並且透過get()方法(Method)存取ETtoday旅遊雲的桃園景點網址,如下範例: import requests response = requests.get( "https://travel.ettoday.net/category/%E6%A1%83%E5%9C%92/")將網頁的HTML程式碼取回來後,接著引用BeautifulSoup類別(Class),傳入取回的HTML結構字串,並且指定HTML的解析型態來建立其物件,如下範例: import requests from bs4 import BeautifulSoup response = requests.get( "…

[Python爬蟲教學]Python網頁爬蟲結合LINE Notify打造自動化訊息通知服務

Photo by William Hook on Unsplash 日常生活中,每個人都有關注的事情,像是演唱會門票的開賣、喜歡的商品降價或新電影上檔等,而為了要及時自動取得這些資訊,Python網頁爬蟲就被廣泛的使用,除了將爬取的資訊透過 [Python實戰應用]Python寄送Gmail電子郵件實作教學文章介紹的電子郵件進行通知外,另一個備受歡迎的接收通知管道就是LINE。
而LINE官方提供了LINE Notify的服務,只要完成和LINE網站的連動設定,就可以透過LINE Notify推播或傳送訊息至目標使用者的LINE中。
本文即以Udemy線上課程網站為例,利用Python網頁爬蟲關注想購買的線上課程,只要低於指定的價格,就透過LINE Notify服務傳送訊息給使用者。本文的重點包含: 登錄LINE Notify服務 發行LINE Notify權杖(Token) 整合Python網頁爬蟲及LINE Notify服務 一、登錄LINE Notify服務首先,前往LINE Notify官網,來進行Python網頁爬蟲與LINE Notify的連動設定,如下圖: 點選右上角的登入,輸入LINE帳號及密碼,如下圖: 成功登入後,就可以看到「管理登錄服務」頁面,如下圖: 接著,點擊「登錄服務」,輸入LINE Notify服務的基本資料,由於本文的Python爬蟲是跑在本機上,所以「服務網址」及「Callback URL」皆為http://127.0.0.1,如下範例: 填寫完成後,點擊「同意並前往下一步」,就可以看到剛剛所輸入的基本資料,確認沒問題點選「登錄」按鈕即可,如下範例: 這時後LINE Notify會發送認證郵件到登錄服務時,所填寫的電子郵件帳號中,如下圖: 完成電子郵件認證後,點擊「前往服務一覽」,可以看到LINE Notify配發了一個Client ID(帳號)給我們,如下圖: 而密碼則需點擊服務,才可以看到,如下圖:
以上就完成了LINE Notify服務的基本資料登錄了。 二、發行LINE Notify權杖(Token)有了的服務帳號及密碼後,接下來,就可以向LINE Notify取得權杖(token),各位可以把它想像是一張活動的門票,只要參加者有這張門票,就可以進入會場,並且主辦單位會為參加者提供多樣的服務。
同樣的道理,只要程式碼中帶有LINE Notify所給的權杖(t…

解析Python模組(Module)和套件(Package)的概念

Photo by Helloquence on Unsplash 當我們在開發大型應用程式時,如果沒有適當的組織程式碼,除了會降低開發的效率外,也不易於維護,所以模組(Module)化就顯得相當的重要,讓程式碼能夠透過引用的方式來重複使用,提升重用性(Reusable)。
但是隨著專案模組(Module)的增加,將難以管理及問題的追蹤,這時候就能將模組(Module)打包成套件(Package),利用其階層式的結構來彈性規劃模組(Module)。
本篇文章就帶大家瞭解Python模組(Module)及套件(Package)的重要觀念,包含: 什麼是模組(Module)模組引用方式(Import)什麼是套件(Package)dir()函式(dir function)將模組當作腳本來執行(Executing a Module as a Script)一、什麼是模組(Module)模組(Module)就是一個檔案,包含了相關性較高的程式碼。隨著應用程式的開發規模越來越大,我們不可能把所有的程式碼都寫在同一份Python檔案中,一定會將關聯性較高的程式碼抽出來放在不同的檔案中來形成模組(Module),主程式再透過引用的方式來使用。所以模組(Module)可以提高程式碼的重用性(Reusable)且易於維護。
假設我們現在要開發一個部落格,主程式為 app.py ,在還沒有模組化時,程式碼可能長得像這樣: #取得作者 def get_author(): return "Mike" #取得電子郵件 def get_email(): return "learncodewithmike@gmail.com" #新增文章 def add_post(title): pass #刪除文章 def delete_post(title): pass add_post() author = get_author() email = get_email()各位應該可以想像,隨著部落格功能的增加,將所有程式碼都寫在 app.py 主程式中會變得怎麼樣。所以這時候就可以將相關性較高的功能進行模組化的動作。
以此範例來說,取得作者及電子郵件可以獨立出來建立一個關於模組(about.py),而新增及刪除文章則可以獨立出來為文章模…

[Python實戰應用]瞭解Python存取API的重要觀念-以KKBOX Open API為例

Photo by Nirmal Rajendharkumar on Unsplash 在現今很多網站,都會透過API(Application Programming Interface)的方式來提供服務,讓用呼端能夠藉由這個介面存取其資料,進行多樣化的應用開發。本文就以KKBOX Open API為例,實作一個簡單的專案,示範Python如何存取音樂排行榜API,並且可以讓使用者選擇想聽的排行榜類別,試聽其中的歌曲。

經過本文的教學,將會瞭解API的基本觀念,以及學會如何解析Python存取API後的回傳結果,並且篩選所需的欄位,重點包含了: 什麼是API專案前置準備KKBOX Open API用戶端憑證(Client Credentials)KKBOX Open API - Charts 一、什麼是API 各位可以將API(Application Programming Interface)想像是一個大門,要進入存取必須提供合法的帳號及密碼,才能拿到存取憑證(Access Token),之後要存取門後的API資源,只要帶著這個憑證,就可以進行存取。

而實際上API就是一組網址,透過HTTP協定來和用戶端進行溝通。舉例來說,各位可以開啟Chrome瀏覽器,按下F12進入開發者視窗,點擊Network頁籤,接著輸入google.com.tw網址,可以看到類似下圖的結果: 點選任一個網址,可以看到以下的資訊: 其中的Headers(標頭)就是瀏覽器發送至Google的資訊,如果換成是存取KKBOX Open API,Request URL就是API網址,Request Method有幾個常用的類型,分別有: GET(查詢資料)POST(新增資料)PUT(修改資料)DELETE(刪除資料) 以上四個是在存取API時,常用的HTTP動詞。而Response頁籤中的內容即是Google回傳給瀏覽器的結果。 二、專案前置準備有了基本的API觀念後,

[Python+LINE Bot教學]6步驟快速上手LINE Bot機器人

Photo by Yura Fresh on Unsplash 每當朋友或家人要聚餐時,是不是總要花很長的時間尋找評價不錯的餐廳?不但要確認營業時間、消費價格及地點,還要觀看許多的美食文章才有辦法決定,這時候如果有人能夠明確提供幾間符合條件且有人氣的餐廳作為選擇,想必會省事許多。
所以筆者開發了一個美食的LINE Bot小作品,透過對談的方式瞭解使用者所要尋找的餐廳條件後,利用Python網頁爬蟲取得目前正在營業的五間最高人氣餐廳資料,回覆給使用者作為參考。
為了要讓想學習的您能夠由淺入深,瞭解其中的實作過程,所以將會分成三篇文章來進行教學。
2020/06/30補充說明 而在進行實作前,先來看一下LINE Bot主要的執行架構,如下圖: 使用者透過LINE發送訊息時,LINE Platform將會進行接收,並且傳遞至我們所開發的LINE Bot執行邏輯運算後,透過LINE所提供的Messaging API回應訊息給LINE Platform,最後再將訊息傳遞給使用者。
其中Messaging API(Application Programming Interface),就是LINE官方定義的回應訊息標準介面,包含Text(文字)、Sticker(貼圖)、Video(影片)、Audio(聲音)及Template(樣板)訊息等,完整的說明可以參考LINE的官方文件
所以在我們的LINE Bot回應訊息時,就要依據Messaging API定義的規範,傳入相應的參數後,Messaging API就會回應使用者相對的訊息類型。簡單來說,就是LINE Platform與LINE Bot的溝通橋樑。
而本文就先以最基本的使用者發送什麼訊息,LINE Bot就回應什麼訊息為例,讓讀者體會其中的運作方式,整體架構如下圖: 在LINE Bot的部分,使用Django框架來進行建置,並且透過Messaging API回應Text(文字)訊息。在下一篇文章中,將會加入Python網頁爬蟲,取得美食網站的資訊回應給使用者。
本文的實作步驟包含: 建立Provider建立Messaging API channel設定LINE Bot憑證開發LINE Bot應用程式安裝Ngrok設定LINE Webhook URL一、建立Provider要開發LINE Bot前,首先需建立一個Provider,也就是服務提供者…

[Python物件導向]淺談Python類別(Class)

Photo by Bram Naus on Unsplash 在學習程式語言時,或多或少都有聽過物件導向程式設計(Object-oriented programming,簡稱OOP),它是一個具有物件(Object)概念的開發方式,能夠提高軟體的重用性、擴充性及維護性,在開發大型的應用程式時更是被廣為使用,所以在現今多數的程式語言都有此種開發方式,Python當然也不例外。而要使用物件導向程式設計就必須對類別(Class)及物件(Object)等有一些基本的了解,包含了: 類別(Class)物件(Object)屬性(Attribute)建構式(Constructor)方法(Method)我們先來看一下今天要來建立的類別: # 汽車類別 class Cars: # 建構式 def __init__(self, color, seat): self.color = color # 顏色屬性 self.seat = seat # 座位屬性 # 方法(Method) def drive(self): print(f"My car is {self.color} and {self.seat} seats.") 接下來就針對類別(Class)各個部分來進行介紹。 一、類別(Class) 簡單來說,就是物件(Object)的藍圖(blueprint)。就像要生產一部汽車時,都會有設計圖,藉此可以知道此類汽車會有哪些特性及功能,類別(Class)就類似設計圖,會定義未來產生物件(Object)時所擁有的屬性(Attribute)及方法(Method)。而定義類別的語法如下: class classname:   statement 首先會有class關鍵字,接著自定類別名稱,最後加上冒號。類別名稱的命名原則習慣上使用Pascal命名法,也就是每個單字字首大寫,不得使用空白或底線分隔單字,如下範例: #範例一 class Cars: #範例二 class MyCars:二、物件(Object) 就是透過類別(Class)實際建立的實體,就像實際生產出來的汽車(例如:Mazda)。類別(Class)與物件(Object)的關係就像汽車設計圖與汽車實體。而建立物件(Object)的語法如…

有效管理Python套件(Package)的工具及概念

Photo by Kevin Bhagat on Unsplash 在實務上發展應用程式時,除了可以自行開發模組(Module)與套件(Package)外,很多時候會安裝使用第三方套件(Package),來提升專案的開發效率。
所以本文將介紹如何在PyPI中搜尋所需的Python套件(Package),並且以Windows作業系統及Visual Studio Code開發工具為例,瞭解Python強大的套件管理工具,讓您有效管理專案中的Python套件(Package)。
由於是在Visual Studio Code的Terminal視窗中下指令的方式來操作,所以使用命令提示字元視窗,也可以達到相同的效果。本文重點包含: PyPI(Python Package Index)pip套件管理工具pipenv套件管理工具Pipfile及Pipfile.lock檔案一、PyPI(Python Package Index)PyPI是一個套件庫,位於https://pypi.org,其中包含了各式各樣的Python套件(Package),在開發應用程式的過程中,可以到這邊來搜尋是否有所需的功能套件(Package),安裝後透過引用的方式來進行使用,藉此提升開發效率。

現在就來介紹幾個在使用PyPI時,需要瞭解的基本功能。首先,PyPI的首頁如下圖: 各位可以在搜尋的地方查詢所需的套件,例如搜尋常應用在網路爬蟲的beautifulsoup4套件(Package),從查詢結果可以看到許多相關的套件(Package),如下圖: 以beautifulsoup4 4.8.2為例,點進此套件(Package)後,可以看到安裝的指令及最新版的發佈日期,如下圖: 一個套件(Package)要如何使用,一定會有文件可以參考,往下即可看到Documentation的連結,如下圖: 而套件(Package)的版本演進歷史則可以透過左邊的Release history來查看,如下圖: 以上是在使用PyPI上查找套件(Package)時,較常使用的部分,接下來,就來教大家如何透過指令來安裝套件(Package)吧。 二、pip套件管理工具pip是一個全域環境的套件管理工具,用來安裝及管理PyPI上的Python套件(Package),也就是說利用pip指令所安裝的Python套件(Package),所有專案皆可使用。其中包…

[Python爬蟲教學]整合Python Selenium及BeautifulSoup實現動態網頁爬蟲

Photo by LAUREN GRAY on Unsplash 相信大家都知道,取得資料後能夠進行許多的應用,像是未來的趨勢預測、機器學習或資料分析等,而有效率的取得資料則是這些應用的首要議題,網頁爬蟲則是其中的一個方法。
網頁爬蟲就是能夠取得網頁原始碼中的元素資料技術,但是,有一些網頁較為特別,像是社群平台,需先登入後才能進行資料的爬取,或是電商網站,無需登入,但是要透過滾動捲軸,才會動態載入更多的資料,而要爬取這樣類型的網頁爬蟲,就稱為動態網頁爬蟲。
該如何實作呢?本文將使用Python Selenium及BeautifulSoup套件來示範動態網頁爬蟲的開發過程,重點包含: BeautifualSoup vs Selenium安裝Selenium及Webdriver安裝BeautifulSoupSelenium get()方法Selenium元素定位Selenium send_keys()方法Selenium execute_script方法BeautifulSoup find_all()方法BeautifulSoup getText()方法 一、BeautifualSoup vs SeleniumBeautifulSoup套件相信對於開發網頁爬蟲的人員來說,應該都有聽過,能夠解析及取得HTML原始碼各個標籤的元素資料,擁有非常容易上手的方法(Method),但是,對於想要爬取動態網頁資料來說,則無法達成,因為BeautifulSoup套件並沒有模擬使用者操作網頁的方法(Method),像是輸入帳號密碼進行登入或滾動捲軸等,來讓網頁動態載入資料,進行爬取的動作。
所以,這時候,就可以使用被設計於自動化測試的Selenium套件,來模擬使用者的動作,進行登入後爬取資料或滾動卷軸,並且能夠執行JavaScript程式碼,這些就是Selenium與BeautifulSoup套件最大不同的地方。對於開發Python動態爬蟲來說,就可以結合Selenium套件以上的特點,讓網頁動態載入資料後,再利用BeautifulSoup套件簡潔的方法(Method),將所需的資料爬取下來。
本文就是利用這樣的概念,利用Selenium套件登入Facebook後,前往粉絲專頁,執行滾動卷軸的JavaScript程式碼,讓網頁動態載入資料後,再使用BeautifulSoup套件爬取貼文標題。 二、…

[Django教學1]3步驟快速安裝Django網站框架

Photo by Danielle MacInnes on Unsplash 在現今網路發達的時代,許多人都會透過網站來經營個人的品牌或生意,在上面能夠展示各種的產品、課程或部落格等,甚至是社群平台,皆是利用網站的方式來連接全世界的使用者,是傳達訊息非常重要的媒介。

而想要利用Python簡潔的語法及特性來開發網站,則可以使用最受歡迎的網站框架Django,能夠快速的建置出具有安全性且模組化的網站應用程式,知名的網站像Instagram、YouTube及Spotify等,皆使用Django網站框架來進行開發。
為什麼這些國際性的網站會選擇使用Django來進行開發呢?接下來,將會撰寫一系列的Django教學文章,從安裝到開發出一個簡單的網站,最後發佈到雲端,帶大家來體會一下強大的Django網站框架吧。本文的重點包含: Django的架構Django的優點Django安裝步驟一、Django的架構 Django是一個由Python建構而成的網站框架(Web Framework),其中能夠包含許多的應用程式(APP),其架構就是將網站的各個功能,模組化為多個應用程式(APP),而每一個應用程式(APP),其實就是Python的套件(Package),如下圖: 就像是如果要開發一個旅遊社群網站,可以把整個網站的功能切分為多個不同的應用程式(APP),例如登入(Login)、貼文(Post)、旅遊規劃(Plan)及搜尋景點(Search)等,每一個應用程式(APP)皆專注在特定的功能邏輯,這就是Django框架的基本架構。 二、Django的優點擴展性由於Django的架構是將網站中關聯性高的功能模組化為多個套件(Package),所以未來要擴展新功能時非常的容易,並且不會影響到既有的專案架構。 移值性Django模組化的架構,讓專案中的應用程式(APP),可以移植至其它的Django專案中使用,擁有非常高的程式碼重用性(Reusable)。 快速開發Django框架定義了專案的基本架構及程式碼撰寫規範,開發人員在參與多個專案時,無需重新適應,可以快速的進入狀況,也因為遵循了Django的規範,提高了Django專案的維護性。 強大的後台在建立Django專案後,預設即提供了一個功能完整的後台,包含使用者的管理、群組管理及資料庫等,並且能夠依需求客製化,無須從頭開發,這也是Django能夠…