目標
- 新增互動功能,例如:推薦景點、美食等
- 結合前一章學到各種message回覆形式
推薦景點
這裡我選擇玩全台灣作為景點資訊的提供網站,使用爬蟲方式將全台灣各縣市各景點的資訊爬下來。如scraping.py
:
import requests
import pandas as pd
import json
from bs4 import BeautifulSoup
def generate_city_json(city = 'keelung'):
# 抓目標網站html內容
url = f"https://okgo.tw/buty/{city}.html"
r = requests.get(url)
web_content = r.text
print(web_content) # 可以印出來看看, 會跟從網頁右鍵查看原始碼看到的一樣
# 利用BS4套件解析html結構,讓我們容易查找
soup = BeautifulSoup(web_content, 'lxml')
area_set = soup.find_all('ul', class_ ="dot")
# 每個縣市景點,由每一區多個地點組成,每個景點包含名字、連結、簡述
d = {'name': [], 'link': [], 'description': []}
for area in area_set:
d['name'].extend([ele.text.replace('\r\n', '').strip() for ele in area.find_all('span', class_ = 'tooltip')])
d['link'].extend(['https://okgo.tw/' + ele.attrs['href'].split('/')[1] for ele in area.find_all('a') ])
d['description'].extend([ele.text.replace('\r\n', '').strip() for ele in area.find_all('p')])
# 先轉成dataframe在轉成json
df = pd.DataFrame(d)
with open(f'{city}.json', 'w', encoding='utf-8') as f:
f.write(df.to_json())
# 測試反轉換回dataframe是否成功
with open(f'{city}.json', 'r', encoding='utf-8') as f:
con = f.read()
df_new = pd.DataFrame(json.loads(con))
print(df_new)
if __name__ == "__main__":
# generate_city_json('keelung')
for city in ['taipei', 'taoyuan', 'hsinchu', 'miaoli', 'taichung', 'changhua', 'nantou', 'yunlin', 'chiayi', 'tainan', 'kaohsiung', 'pingtung', 'yilan', 'hualien', 'taitung', 'penghu', 'kinmen', 'matsu']:
generate_city_json(city)
最後爬下來的資料我們整理成dataframe形式:
並且以json檔方式儲存起來,後續只要讀取檔案即可取得各景點資訊和連結了。
Template & QuickReply message
接下來,當使用者輸入「推薦XX景點」XX這裡以基隆為例,可以隨機產生基隆4個景點作為訊息回覆。
我們透過讀取前面爬蟲存下的json檔,包含景點的名稱、連結、簡述,用Buttons template message
包裝起來。由於Buttons template
限制4個連結物件所以我們採隨機取4個該縣市景點。
def handle_message(event):
message = event.message.text
if '推薦基隆景點' in message:
buttons_template_message = generate_views('基隆景點', 'keelung.json')
line_bot_api.reply_message(event.reply_token, buttons_template_message)
def generate_views(place, path = 'keelung.json'):
with open(os.path.join('.', 'viewpoint', path), 'r', encoding='utf-8') as f:
con = f.read()
df_new = pd.DataFrame(json.loads(con))
selected_index = random.sample(range(len(df_new)), 4)
buttons_template_message = TemplateSendMessage(
alt_text='Buttons template',
template=ButtonsTemplate(
title=place,
text=df_new.iloc[selected_index[0], 2][:60],
actions=[
URIAction(
label=df_new.iloc[selected_index[0], 0],
uri=df_new.iloc[selected_index[0], 1]
),
URIAction(
label=df_new.iloc[selected_index[1], 0],
uri=df_new.iloc[selected_index[1], 1]
),
URIAction(
label=df_new.iloc[selected_index[2], 0],
uri=df_new.iloc[selected_index[2], 1]
),
URIAction(
label=df_new.iloc[selected_index[3], 0],
uri=df_new.iloc[selected_index[3], 1]
)
]
)
)
return buttons_template_message
這裡實際使用情境痛點:
- 使用者不知道有哪些縣市可以選擇
- 使用者不知道要輸入什麼關鍵字才可以開啟推薦景點功能
因此,我們可以設計,當使用者輸入「嗨」、「Hi」等打招呼時,機器人會回覆輔助文字讓使用者知道有什麼功能可以使用:
接著,當使用者輸入「推薦景點」,這裡用一段輔助文字搭配QuickReply message
,讓使用者從給定的一些選項當中選擇回覆訊息,實際使用狀況如下圖:
def handle_message(event):
message = event.message.text
if '推薦景點' in message:
text_message = TextSendMessage(text='嗨囉你好,\n請選擇一個縣市或直接輸入「推薦XX景點」XX為縣市,\n將隨機跑出該縣市景點。',
quick_reply=QuickReply(items=[
# 這裡line限制最多可以放13個項目
QuickReplyButton(action=MessageAction(label="基隆", text="推薦基隆景點")),
QuickReplyButton(action=MessageAction(label="台北", text="推薦台北景點")),
QuickReplyButton(action=MessageAction(label="桃園", text="推薦桃園景點")),
QuickReplyButton(action=MessageAction(label="新竹", text="推薦新竹景點")),
QuickReplyButton(action=MessageAction(label="苗栗", text="推薦苗栗景點")),
QuickReplyButton(action=MessageAction(label="台中", text="推薦台中景點")),
QuickReplyButton(action=MessageAction(label="彰化", text="推薦彰化景點")),
QuickReplyButton(action=MessageAction(label="南投", text="推薦南投景點")),
QuickReplyButton(action=MessageAction(label="雲林", text="推薦雲林景點")),
QuickReplyButton(action=MessageAction(label="嘉義", text="推薦嘉義景點")),
QuickReplyButton(action=MessageAction(label="台南", text="推薦台南景點")),
QuickReplyButton(action=MessageAction(label="高雄", text="推薦高雄景點")),
QuickReplyButton(action=MessageAction(label="屏東", text="推薦屏東景點"))
]))
line_bot_api.reply_message(event.reply_token, text_message)
在上圖中,你可以往右滑動看到更多選項,並且選擇其中一個,例如:點選「屏東」,就會顯示出隨機4個景點。
最後,如果你想玩玩看這項功能,歡迎加入好友,掃QR code。