前一天教了如何使用氣象局API來爬取天氣資訊,那今天也來個進階一點的吧!!爬取汽油資訊。
我們爬取的網站是GoodLife 油價預測,此處使用requests與beautifulsoup去爬取資訊。
程式碼範例如下
import requests
import json
import threading
import warnings
import subprocess
from bs4 import BeautifulSoup
from flask import Flask, request
from linebot.models import TextSendMessage
from linebot import LineBotApi, WebhookHandler, LineBotSdkDeprecatedIn30
def check_oil_price(user_id):
#這邊記得修改
api = LineBotApi('<你的channel access token>')
#目標網址
url = "https://gas.goodlife.tw/"
price_array = []
#輸出用
output_keyword = [
"92汽油",
"95汽油",
"98汽油",
]
#搜尋網站元素關鍵字
search_keyword = [
"92:",
"95油價:",
"98:",
]
#目前油價
output_curr_price = ""
#下週調整
output_oli_price_adjust = ""
html = requests.get(url)
#此網站編碼使用ISO-8859-1需更改編碼為utf-8
soup = BeautifulSoup(html.content, "html.parser", from_encoding='utf-8')
#油價
for i in search_keyword:
price = soup.find(lambda tag:tag.name=='li' and i in tag.text)
price = price.text.split("\n")
price_array.append(price[2])
#下周油價
data = soup.find("li", class_="main").text.split()
#網站可能的變化
if len(data) == 3:
output_oli_price_adjust = "從下周一起汽油每公升" + data[2]
elif data[9] == "不":
output_oli_price_adjust = "從今日起汽油每公升不調整"
else:
output_oli_price_adjust = "自"
for i in range(1, 10):
output_oli_price_adjust += data[i]
#取得目前油價
for i in range(3):
output_curr_price += "目前" + output_keyword[i] + "價格:" + str(price_array[i]) + "\n"
#傳送訊息給使用者
api.push_message(user_id, TextSendMessage(text=output_curr_price))
api.push_message(user_id, TextSendMessage(text=output_oli_price_adjust))
app = Flask(__name__)
@app.route("/", methods=['POST'])
def get_reply():
handler = WebhookHandler('<你的channel secret>')
body = request.get_data(as_text=True)
json_data = json.loads(body)
try:
signature = request.headers['X-Line-Signature']
handler.handle(body, signature)
user_id = json_data['events'][0]["source"]['userId']
text = json_data['events'][0]['message']['text']
if text == "油價":
check_oil_price(user_id)
except Exception as e:
print(e)
return 'OK'
def jobs1():
app.run()
#此處記得修改
def jobs2():
subprocess.run([
"ngrok",
"http",
"5000",
"--domain=<你的domain網址>",
"--log=stdout"
])
if __name__ == "__main__":
#避免出現警告訊息
warnings.filterwarnings("ignore", category=LineBotSdkDeprecatedIn30)
#使用多線程
jobs = []
jobs.append(threading.Thread(target=jobs1))
jobs.append(threading.Thread(target=jobs2))
for i in range(len(jobs)):
jobs[i].start()
結果如下圖
這邊多一種輸出寫法,將數字更改為貼圖,美化輸出
只需將60後的部分更改為下面演示的程式碼即可(不用覆蓋到app = Flask(__name__)
的部分)
emoji_output(user_id, api, output_curr_price)
emoji_output(user_id, api, output_oli_price_adjust)
def emoji_output(user_id, api, message):
output_emoji_dict = []
#篩選是否含有0~9的字元
for i in range(len(message)):
if message[i] == '1':
message = replace_emoji(i, "053", message, output_emoji_dict)
elif message[i] == '2':
message = replace_emoji(i, "054", message, output_emoji_dict)
elif message[i] == '3':
message = replace_emoji(i, "055", message, output_emoji_dict)
elif message[i] == '4':
message = replace_emoji(i, "056", message, output_emoji_dict)
elif message[i] == '5':
message = replace_emoji(i, "057", message, output_emoji_dict)
elif message[i] == '6':
message = replace_emoji(i, "058", message, output_emoji_dict)
elif message[i] == '7':
message = replace_emoji(i, "059", message, output_emoji_dict)
elif message[i] == '8':
message = replace_emoji(i, "060", message, output_emoji_dict)
elif message[i] == '9':
message = replace_emoji(i, "061", message, output_emoji_dict)
elif message[i] == '0':
message = replace_emoji(i, "062", message, output_emoji_dict)
#想要修改的也可以自己新增喔,範本如下所示(記得把註解去掉)
'''
elif message[i] == '<想要修改的字元>':
message = replace_emoji(i, <貼圖的索引>)
'''
#傳送訊息
#記得TextSendMessage的emojis最高上限為單則留言20個貼圖喔
api.push_message(user_id, TextSendMessage(text=message, emojis=output_emoji_dict))
def replace_emoji(for_index, emoji_id, target_array, output_emoji_dict):
#作為範本使用
data = {
"index": -1,
"productId": "5ac21a8c040ab15980c9b43f",
"emojiId": "0"
}
data["index"] = for_index
data["emojiId"] = emoji_id
output_emoji_dict.append(data)
#將字元修改為'$'符號
return_str = target_array[:for_index] + '$' + target_array[for_index+1:]
return return_str
效果如下圖
在Day 14有做詳細的解說,若有不懂可以跳轉連結去參考。
油價調漲(降)可能隨著網站的變化而導致資訊跑掉,屆時需要再做修改