可以帮我们看看程式码中有没有哪里错,因为不是本科系,所以救救商科女大生,谢谢大家!
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
import requests
from bs4 import BeautifulSoup
import pandas as pd
from datetime import datetime
# 设定 Line Bot API
LINE_TOKEN = os.getenv(\'LINE_TOKEN\')
LINE_SECRET = os.getenv(\'LINE_SECRET\')
if not LINE_TOKEN or not LINE_SECRET:
raise ValueError("请设置 LINE_TOKEN 和 LINE_SECRET 环境变数")
api = LineBotApi(LINE_TOKEN)
handler = WebhookHandler(LINE_SECRET)
app = Flask(__name__)
def get_uniqlo_price_history(product_code):
"""爬取 Uniqlo 商品价格历史"""
try:
# Uniqlo 台湾官网的 URL 格式
url = f"https://www.uniqlo.com/tw/zh_TW/products/{product_code}"
headers = {
\'User-Agent\': \'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\',
\'Accept\': \'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\',
\'Accept-Language\': \'zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7\',
\'Connection\': \'keep-alive\'
}
response = requests.get(url, headers=headers, timeout=10)
if response.status_code != 200:
return None
soup = BeautifulSoup(response.text, \'html.parser\')
try:
product_name = soup.select_one(\'[data-test="product-name"]\').text.strip()
current_price = soup.select_one(\'[data-test="price-value"]\').text.strip()
except AttributeError:
return None
return {
\'name\': product_name,
\'current_price\': current_price,
\'url\': url
}
except Exception as e:
print(f"爬虫错误:{str(e)}")
return None
# 加入根路由,确认服务器正常运行
@app.route("/", methods=[\'GET\'])
def hello():
return \'Hello, World!\'
# 处理 webhook
@app.route("/webhook", methods=[\'POST\'])
def webhook():
# 取得 X-Line-Signature 表头电子签章内容
signature = request.headers.get(\'X-Line-Signature\', \'\')
# 以文字形式取得请求内容
body = request.get_data(as_text=True)
print(f"收到 webhook 请求:{body}") # 添加日誌
# 比对电子签章并处理请求内容
try:
handler.handle(body, signature)
except InvalidSignatureError:
print("电子签章错误,请检查密钥是否正确?")
abort(400)
except Exception as e:
print(f"发生错误:{str(e)}")
abort(500)
return \'OK\'
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
try:
user_message = event.message.text
print(f"收到用户讯息:{user_message}")
if len(user_message) == 6 and user_message.isdigit():
# 爬取价格历史
price_info = get_uniqlo_price_history(user_message)
if price_info:
reply_text = (
f"商品名称:{price_info[\'name\']}\\n"
f"目前售价:{price_info[\'current_price\']}\\n"
f"商品连结:{price_info[\'url\']}\\n\\n"
f"💡 提示:建议等待特价活动时购买"
)
else:
reply_text = "抱歉,找不到此商品资讯,请确认商品编号是否正确。"
else:
reply_text = "请输入正确的 Uniqlo 商品货号(6位数字)\\n例如:469773"
print(f"準备回覆:{reply_text}")
api.reply_message(
event.reply_token,
TextSendMessage(text=reply_text))
print("回覆讯息成功")
except Exception as e:
print(f"处理讯息时发生错误:{str(e)}")
api.reply_message(
event.reply_token,
TextSendMessage(text="抱歉,系统发生错误,请稍后再试。"))
if __name__ == "__main__":
print("正在启动机器人...")
print(f"LINE_TOKEN 是否存在: {bool(os.getenv(\'LINE_TOKEN\'))}")
print(f"LINE_SECRET 是否存在: {bool(os.getenv(\'LINE_SECRET\'))}")
# 测试 LINE Bot API 连接
try:
bot_info = api.get_bot_info()
print(f"机器人名称: {bot_info.display_name}")
print("LINE Bot API 连接成功")
except Exception as e:
print(f"LINE Bot API 连接失败: {str(e)}")
port = int(os.environ.get(\'PORT\', 8080))
app.run(host=\'0.0.0.0\', port=port)
2 个回答
1
Antonio
iT邦新手 4 级 ‧ 2024-12-25 22:32:09
我这边直接把你的程式码跑起来串我自己的 Linebot,这部分有也没有问题。
至于爬虫那部分我没有看得很仔细,但是这个页面感觉是没办法直接抓到他的静态 html 完整内容,感觉爬虫那块可以调整一下。
-
2 -
-
Antonio
iT邦新手 4 级 ‧
2024-12-25 22:34:07
修改
11111
iT邦新手 5 级 ‧
2024-12-25 23:40:53
好的!有成功连接了,谢谢!
修改
0
meebox
iT邦新手 3 级 ‧ 2024-12-26 09:27:48
应该是你的 official account 那边自动功能没有关闭,这样讯息就不会转送到你 webhook 设定的后端,可参考这里第 5 步骤:
https://hackmd.io/@flagmaker/r1fcsp20R