Spaces:
Sleeping
Sleeping
Commit
·
56e1415
1
Parent(s):
3f0bb34
穩定版本
Browse files- .gitignore +2 -1
- app.py +178 -225
.gitignore
CHANGED
@@ -1 +1,2 @@
|
|
1 |
-
/myenv
|
|
|
|
1 |
+
/myenv
|
2 |
+
/docs/assets
|
app.py
CHANGED
@@ -1,268 +1,226 @@
|
|
1 |
import gradio as gr
|
2 |
import requests
|
3 |
-
import re
|
4 |
import json
|
5 |
import os
|
6 |
import pandas as pd
|
7 |
-
from xml.etree import ElementTree
|
8 |
from geopy.distance import geodesic
|
9 |
|
10 |
-
# ===============
|
11 |
-
|
12 |
-
|
|
|
|
|
13 |
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
|
18 |
# 3 公里範圍
|
19 |
MAX_DISTANCE = 3000
|
20 |
|
21 |
# -----------------------------------------------------------
|
22 |
-
#
|
23 |
# -----------------------------------------------------------
|
24 |
-
def
|
25 |
"""
|
26 |
-
|
27 |
-
|
28 |
-
force_update=True 時,強制重新抓取。
|
29 |
"""
|
30 |
-
|
31 |
-
print("7-11 商品 JSON 已存在,跳過下載 (如要強制更新請設 force_update=True)")
|
32 |
-
return
|
33 |
-
|
34 |
-
base_url = "https://www.7-11.com.tw/freshfoods/Read_Food_xml_hot.aspx"
|
35 |
headers = {
|
36 |
-
"
|
37 |
}
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
data_list = []
|
47 |
-
|
48 |
-
# 按照分類依序爬取
|
49 |
-
for index, cat in enumerate(categories):
|
50 |
-
# 注意:實際參數可能需要你自行測試
|
51 |
-
params = {"": index}
|
52 |
-
try:
|
53 |
-
resp = requests.get(base_url, headers=headers, params=params, timeout=10)
|
54 |
-
if resp.status_code == 200:
|
55 |
-
try:
|
56 |
-
root = ElementTree.fromstring(resp.content)
|
57 |
-
# 解析 XML
|
58 |
-
for item in root.findall(".//Item"):
|
59 |
-
data_list.append({
|
60 |
-
"category": cat,
|
61 |
-
"name": item.findtext("name", ""),
|
62 |
-
"kcal": item.findtext("kcal", ""),
|
63 |
-
"price": item.findtext("price", ""),
|
64 |
-
"image": f'https://www.7-11.com.tw/freshfoods/{cat}/' + item.findtext("image", ""),
|
65 |
-
"special_sale": item.findtext("special_sale", ""),
|
66 |
-
"new": item.findtext("new", ""),
|
67 |
-
"content": item.findtext("content", ""),
|
68 |
-
# 如果你另外有店家經緯度資訊,請自行加上:
|
69 |
-
# "latitude": ...,
|
70 |
-
# "longitude": ...
|
71 |
-
})
|
72 |
-
except ElementTree.ParseError:
|
73 |
-
print(f"分類 {cat} 返回非 XML 格式資料,略過。")
|
74 |
-
else:
|
75 |
-
print(f"分類 {cat} 請求失敗,HTTP 狀態碼: {resp.status_code}")
|
76 |
-
except Exception as e:
|
77 |
-
print(f"分類 {cat} 請求錯誤: {e}")
|
78 |
-
|
79 |
-
# 儲存到 JSON
|
80 |
-
with open(SEVEN_ELEVEN_PRODUCTS_FILE, "w", encoding="utf-8") as jf:
|
81 |
-
json.dump(data_list, jf, ensure_ascii=False, indent=4)
|
82 |
-
|
83 |
-
print(f"✅ 7-11 商品資料抓取完成,共 {len(data_list)} 筆,已存為 {SEVEN_ELEVEN_PRODUCTS_FILE}")
|
84 |
|
85 |
# -----------------------------------------------------------
|
86 |
-
#
|
87 |
# -----------------------------------------------------------
|
88 |
-
def
|
89 |
"""
|
90 |
-
|
91 |
-
|
92 |
-
force_update=True 時,強制重新抓取。
|
93 |
"""
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
|
|
|
|
|
|
|
|
111 |
|
112 |
# -----------------------------------------------------------
|
113 |
-
#
|
114 |
# -----------------------------------------------------------
|
115 |
-
def
|
116 |
"""
|
117 |
-
|
118 |
-
|
119 |
-
force_update=True 時,強制重新抓取。
|
120 |
"""
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
"title": product.get("name"),
|
140 |
-
"picture_url": product.get("imgurl"),
|
141 |
-
"protein": product.get("protein", 0),
|
142 |
-
"carb": product.get("carb", 0),
|
143 |
-
"calories": product.get("calo", 0),
|
144 |
-
"fat": product.get("fat", 0),
|
145 |
-
"description": product.get("description", ""),
|
146 |
-
})
|
147 |
-
with open(FAMILY_MART_PRODUCTS_FILE, "w", encoding="utf-8") as jf:
|
148 |
-
json.dump(results, jf, ensure_ascii=False, indent=4)
|
149 |
-
print(f"✅ 全家商品資料抓取完成,共 {len(results)} 筆,已存為 {FAMILY_MART_PRODUCTS_FILE}")
|
150 |
-
else:
|
151 |
-
print("❌ 找不到 var categories = ... 之內容,無法解析全家商品。")
|
152 |
-
else:
|
153 |
-
print(f"❌ 全家商品頁面請求失敗,HTTP 狀態碼: {resp.status_code}")
|
154 |
-
except Exception as e:
|
155 |
-
print(f"❌ 全家商品頁面請求錯誤: {e}")
|
156 |
|
157 |
# -----------------------------------------------------------
|
158 |
-
#
|
159 |
# -----------------------------------------------------------
|
160 |
-
def
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
|
166 |
# -----------------------------------------------------------
|
167 |
-
#
|
168 |
# -----------------------------------------------------------
|
169 |
def find_nearest_store(address, lat, lon):
|
|
|
|
|
|
|
|
|
|
|
170 |
print(f"🔍 收到查詢請求: address={address}, lat={lat}, lon={lon}")
|
171 |
-
|
172 |
if lat == 0 or lon == 0:
|
173 |
return [["❌ 請輸入地址或提供 GPS 座標", "", "", "", ""]]
|
174 |
|
175 |
-
|
176 |
-
|
177 |
-
# ========== 讀取 7-11 JSON 並印出前 10 筆 (檢查欄位用) ==========
|
178 |
-
seven_data = load_json(SEVEN_ELEVEN_PRODUCTS_FILE)
|
179 |
-
print(f"7-11 JSON 總筆數: {len(seven_data)}")
|
180 |
-
print("===== 7-11 JSON 前 10 筆 =====")
|
181 |
-
print(seven_data[:10])
|
182 |
-
|
183 |
-
# 將 7-11 資料轉成 DataFrame (假設內含 latitude, longitude)
|
184 |
-
seven_df = pd.DataFrame(seven_data)
|
185 |
-
if {"latitude", "longitude"}.issubset(seven_df.columns):
|
186 |
-
seven_df["latitude"] = seven_df["latitude"].astype(float)
|
187 |
-
seven_df["longitude"] = seven_df["longitude"].astype(float)
|
188 |
-
# 計算距離
|
189 |
-
seven_df["distance_m"] = seven_df.apply(
|
190 |
-
lambda row: geodesic(user_coords, (row["latitude"], row["longitude"])).meters,
|
191 |
-
axis=1
|
192 |
-
)
|
193 |
-
else:
|
194 |
-
print("⚠️ 7-11 JSON 裡沒有 'latitude' 或 'longitude' 欄位,無法計算距離。")
|
195 |
-
seven_df = pd.DataFrame() # 清空,代表無法顯示 7-11 門市
|
196 |
-
|
197 |
-
# ========== 讀取 全家門市 JSON 並印出前 10 筆 (檢查欄位用) ==========
|
198 |
-
family_stores = load_json(FAMILY_MART_STORES_FILE)
|
199 |
-
print(f"全家 JSON 總筆數: {len(family_stores)}")
|
200 |
-
print("===== 全家 JSON 前 10 筆 =====")
|
201 |
-
print(family_stores[:10])
|
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 |
-
for _, row in nearby_family.iterrows():
|
248 |
-
store_name = row.get("Name", "全家 未提供店名")
|
249 |
-
dist_str = f"{row['distance_m']:.1f} m"
|
250 |
-
output.append([
|
251 |
-
f"全家 {store_name}",
|
252 |
-
dist_str,
|
253 |
-
"全家即期食品(示意)",
|
254 |
-
"1"
|
255 |
-
])
|
256 |
|
257 |
-
return
|
258 |
|
259 |
# -----------------------------------------------------------
|
260 |
-
#
|
261 |
# -----------------------------------------------------------
|
262 |
with gr.Blocks() as demo:
|
263 |
-
gr.Markdown("##
|
264 |
-
gr.Markdown("
|
265 |
-
|
|
|
|
|
|
|
|
|
266 |
address = gr.Textbox(label="輸入地址(可留空)")
|
267 |
lat = gr.Number(label="GPS 緯度", value=0, elem_id="lat")
|
268 |
lon = gr.Number(label="GPS 經度", value=0, elem_id="lon")
|
@@ -306,14 +264,9 @@ with gr.Blocks() as demo:
|
|
306 |
|
307 |
def main():
|
308 |
"""
|
309 |
-
|
310 |
-
|
311 |
"""
|
312 |
-
# 下載 / 更新 所有資料
|
313 |
-
fetch_seven_eleven_products(force_update=False)
|
314 |
-
fetch_family_stores(force_update=False)
|
315 |
-
fetch_family_products(force_update=False)
|
316 |
-
|
317 |
demo.launch(server_name="0.0.0.0", server_port=7860, debug=True)
|
318 |
|
319 |
if __name__ == "__main__":
|
|
|
1 |
import gradio as gr
|
2 |
import requests
|
|
|
3 |
import json
|
4 |
import os
|
5 |
import pandas as pd
|
|
|
6 |
from geopy.distance import geodesic
|
7 |
|
8 |
+
# =============== 7-11 所需常數 ===============
|
9 |
+
# 請確認此處的 MID_V 是否有效,若過期請更新
|
10 |
+
MID_V = "W0_DiF4DlgU5OeQoRswrRcaaNHMWOL7K3ra3385ocZcv-bBOWySZvoUtH6j-7pjiccl0C5h30uRUNbJXsABCKMqiekSb7tdiBNdVq8Ro5jgk6sgvhZla5iV0H3-8dZfASc7AhEm85679LIK3hxN7Sam6D0LAnYK9Lb0DZhn7xeTeksB4IsBx4Msr_VI" # 請填入有效的 mid_v
|
11 |
+
USER_AGENT_7_11 = "Mozilla/5.0 (iPhone; CPU iPhone OS 17_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148"
|
12 |
+
API_7_11_BASE = "https://lovefood.openpoint.com.tw/LoveFood/api"
|
13 |
|
14 |
+
# =============== FamilyMart 所需常數 ===============
|
15 |
+
FAMILY_PROJECT_CODE = "202106302" # 若有需要請自行調整
|
16 |
+
API_FAMILY = "https://stamp.family.com.tw/api/maps/MapProductInfo"
|
17 |
|
18 |
# 3 公里範圍
|
19 |
MAX_DISTANCE = 3000
|
20 |
|
21 |
# -----------------------------------------------------------
|
22 |
+
# 7-11: 取得 AccessToken
|
23 |
# -----------------------------------------------------------
|
24 |
+
def get_7_11_token():
|
25 |
"""
|
26 |
+
POST /Auth/FrontendAuth/AccessToken?mid_v=$mid_v
|
27 |
+
回傳 JWT token
|
|
|
28 |
"""
|
29 |
+
url = f"{API_7_11_BASE}/Auth/FrontendAuth/AccessToken?mid_v={MID_V}"
|
|
|
|
|
|
|
|
|
30 |
headers = {
|
31 |
+
"user-agent": USER_AGENT_7_11
|
32 |
}
|
33 |
+
resp = requests.post(url, headers=headers, data="")
|
34 |
+
resp.raise_for_status()
|
35 |
+
js = resp.json()
|
36 |
+
if not js.get("isSuccess"):
|
37 |
+
raise RuntimeError(f"取得 7-11 token 失敗: {js}")
|
38 |
+
token = js["element"]
|
39 |
+
return token
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
|
41 |
# -----------------------------------------------------------
|
42 |
+
# 7-11: 取得附近門市清單 (含剩餘即期品總數量)
|
43 |
# -----------------------------------------------------------
|
44 |
+
def get_7_11_nearby_stores(token, lat, lon):
|
45 |
"""
|
46 |
+
POST /Search/FrontendStoreItemStock/GetNearbyStoreList?token=$token
|
47 |
+
取得附近門市的「即期品」總數量
|
|
|
48 |
"""
|
49 |
+
url = f"{API_7_11_BASE}/Search/FrontendStoreItemStock/GetNearbyStoreList?token={token}"
|
50 |
+
headers = {
|
51 |
+
"user-agent": USER_AGENT_7_11,
|
52 |
+
"content-type": "application/json",
|
53 |
+
}
|
54 |
+
body = {
|
55 |
+
"CurrentLocation": {
|
56 |
+
"Latitude": lat,
|
57 |
+
"Longitude": lon
|
58 |
+
},
|
59 |
+
"SearchLocation": {
|
60 |
+
"Latitude": lat,
|
61 |
+
"Longitude": lon
|
62 |
+
}
|
63 |
+
}
|
64 |
+
resp = requests.post(url, headers=headers, json=body)
|
65 |
+
resp.raise_for_status()
|
66 |
+
js = resp.json()
|
67 |
+
if not js.get("isSuccess"):
|
68 |
+
raise RuntimeError(f"取得 7-11 附近門市失敗: {js}")
|
69 |
+
return js["element"].get("StoreStockItemList", [])
|
70 |
|
71 |
# -----------------------------------------------------------
|
72 |
+
# 7-11: 取得單一門市的即期品清單
|
73 |
# -----------------------------------------------------------
|
74 |
+
def get_7_11_store_detail(token, lat, lon, store_no):
|
75 |
"""
|
76 |
+
POST /Search/FrontendStoreItemStock/GetStoreDetail?token=$token
|
77 |
+
回傳該門市的即期品細項 (商品名稱 / 剩餘數量 等)
|
|
|
78 |
"""
|
79 |
+
url = f"{API_7_11_BASE}/Search/FrontendStoreItemStock/GetStoreDetail?token={token}"
|
80 |
+
headers = {
|
81 |
+
"user-agent": USER_AGENT_7_11,
|
82 |
+
"content-type": "application/json",
|
83 |
+
}
|
84 |
+
body = {
|
85 |
+
"CurrentLocation": {
|
86 |
+
"Latitude": lat,
|
87 |
+
"Longitude": lon
|
88 |
+
},
|
89 |
+
"StoreNo": store_no
|
90 |
+
}
|
91 |
+
resp = requests.post(url, headers=headers, json=body)
|
92 |
+
resp.raise_for_status()
|
93 |
+
js = resp.json()
|
94 |
+
if not js.get("isSuccess"):
|
95 |
+
raise RuntimeError(f"取得 7-11 門市({store_no})資料失敗: {js}")
|
96 |
+
return js["element"].get("StoreStockItem", {})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
|
98 |
# -----------------------------------------------------------
|
99 |
+
# FamilyMart: 取得附近門市即期品清單 (單次呼叫可拿到所有商品細項)
|
100 |
# -----------------------------------------------------------
|
101 |
+
def get_family_nearby_stores(lat, lon):
|
102 |
+
"""
|
103 |
+
POST https://stamp.family.com.tw/api/maps/MapProductInfo
|
104 |
+
查詢附近門市及即期品庫存,回傳資料中 code 應為 1 代表成功
|
105 |
+
"""
|
106 |
+
headers = {
|
107 |
+
"Content-Type": "application/json;charset=utf-8",
|
108 |
+
}
|
109 |
+
body = {
|
110 |
+
"ProjectCode": FAMILY_PROJECT_CODE,
|
111 |
+
"latitude": lat,
|
112 |
+
"longitude": lon
|
113 |
+
}
|
114 |
+
resp = requests.post(API_FAMILY, headers=headers, json=body)
|
115 |
+
resp.raise_for_status()
|
116 |
+
js = resp.json()
|
117 |
+
# 修改判斷:根據回傳範例,成功時 code 為 1
|
118 |
+
if js.get("code") != 1:
|
119 |
+
raise RuntimeError(f"取得全家門市資料失敗: {js}")
|
120 |
+
return js["data"]
|
121 |
|
122 |
# -----------------------------------------------------------
|
123 |
+
# Gradio 查詢邏輯
|
124 |
# -----------------------------------------------------------
|
125 |
def find_nearest_store(address, lat, lon):
|
126 |
+
"""
|
127 |
+
1. 使用者輸入經緯度
|
128 |
+
2. 查詢 7-11 與 FamilyMart 的即期品清單
|
129 |
+
3. 合併結果後顯示
|
130 |
+
"""
|
131 |
print(f"🔍 收到查詢請求: address={address}, lat={lat}, lon={lon}")
|
|
|
132 |
if lat == 0 or lon == 0:
|
133 |
return [["❌ 請輸入地址或提供 GPS 座標", "", "", "", ""]]
|
134 |
|
135 |
+
result_rows = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
|
137 |
+
# ------------------ 7-11 ------------------
|
138 |
+
try:
|
139 |
+
token_711 = get_7_11_token()
|
140 |
+
nearby_stores_711 = get_7_11_nearby_stores(token_711, lat, lon)
|
141 |
+
for store in nearby_stores_711:
|
142 |
+
dist_m = store.get("Distance", 999999)
|
143 |
+
if dist_m <= MAX_DISTANCE:
|
144 |
+
store_no = store.get("StoreNo")
|
145 |
+
store_name = store.get("StoreName", "7-11 未提供店名")
|
146 |
+
remaining_qty = store.get("RemainingQty", 0)
|
147 |
+
if remaining_qty > 0:
|
148 |
+
detail = get_7_11_store_detail(token_711, lat, lon, store_no)
|
149 |
+
for cat in detail.get("CategoryStockItems", []):
|
150 |
+
cat_name = cat.get("Name", "")
|
151 |
+
for item in cat.get("ItemList", []):
|
152 |
+
item_name = item.get("ItemName", "")
|
153 |
+
item_qty = item.get("RemainingQty", 0)
|
154 |
+
row = [
|
155 |
+
f"7-11 {store_name}",
|
156 |
+
f"{dist_m:.1f} m",
|
157 |
+
f"{cat_name} - {item_name}",
|
158 |
+
str(item_qty)
|
159 |
+
]
|
160 |
+
result_rows.append(row)
|
161 |
+
else:
|
162 |
+
row = [
|
163 |
+
f"7-11 {store_name}",
|
164 |
+
f"{dist_m:.1f} m",
|
165 |
+
"即期品 0 項",
|
166 |
+
"0"
|
167 |
+
]
|
168 |
+
result_rows.append(row)
|
169 |
+
except Exception as e:
|
170 |
+
print(f"❌ 取得 7-11 即期品時發生錯誤: {e}")
|
171 |
|
172 |
+
# ------------------ FamilyMart ------------------
|
173 |
+
try:
|
174 |
+
nearby_stores_family = get_family_nearby_stores(lat, lon)
|
175 |
+
for store in nearby_stores_family:
|
176 |
+
dist_m = store.get("distance", 999999)
|
177 |
+
if dist_m <= MAX_DISTANCE:
|
178 |
+
store_name = store.get("name", "全家 未提供店名")
|
179 |
+
info_list = store.get("info", [])
|
180 |
+
has_item = False
|
181 |
+
for big_cat in info_list:
|
182 |
+
big_cat_name = big_cat.get("name", "")
|
183 |
+
for subcat in big_cat.get("categories", []):
|
184 |
+
subcat_name = subcat.get("name", "")
|
185 |
+
for product in subcat.get("products", []):
|
186 |
+
product_name = product.get("name", "")
|
187 |
+
qty = product.get("qty", 0)
|
188 |
+
if qty > 0:
|
189 |
+
has_item = True
|
190 |
+
row = [
|
191 |
+
f"全家 {store_name}",
|
192 |
+
f"{dist_m:.1f} m",
|
193 |
+
f"{big_cat_name} - {subcat_name} - {product_name}",
|
194 |
+
str(qty)
|
195 |
+
]
|
196 |
+
result_rows.append(row)
|
197 |
+
if not has_item:
|
198 |
+
row = [
|
199 |
+
f"全家 {store_name}",
|
200 |
+
f"{dist_m:.1f} m",
|
201 |
+
"即期品 0 項",
|
202 |
+
"0"
|
203 |
+
]
|
204 |
+
result_rows.append(row)
|
205 |
+
except Exception as e:
|
206 |
+
print(f"❌ 取得全家 即期品時發生錯誤: {e}")
|
207 |
|
208 |
+
if not result_rows:
|
209 |
+
return [["❌ 附近 3 公里內沒有即期食品", "", "", "", ""]]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
210 |
|
211 |
+
return result_rows
|
212 |
|
213 |
# -----------------------------------------------------------
|
214 |
+
# Gradio 介面
|
215 |
# -----------------------------------------------------------
|
216 |
with gr.Blocks() as demo:
|
217 |
+
gr.Markdown("## 便利商店「即期食品」搜尋示範")
|
218 |
+
gr.Markdown("""
|
219 |
+
1. 按下「使用目前位置」或自行輸入緯度/經度
|
220 |
+
2. 點選「搜尋」查詢 3 公里內 7-11 / 全家的即期品
|
221 |
+
3. 若要執行,需要有效的 mid_v (7-11 愛食記憶官網)
|
222 |
+
4. 在 Logs 查看詳細錯誤或除錯資訊
|
223 |
+
""")
|
224 |
address = gr.Textbox(label="輸入地址(可留空)")
|
225 |
lat = gr.Number(label="GPS 緯度", value=0, elem_id="lat")
|
226 |
lon = gr.Number(label="GPS 經度", value=0, elem_id="lon")
|
|
|
264 |
|
265 |
def main():
|
266 |
"""
|
267 |
+
主程式入口,在本地端執行:
|
268 |
+
python your_script.py
|
269 |
"""
|
|
|
|
|
|
|
|
|
|
|
270 |
demo.launch(server_name="0.0.0.0", server_port=7860, debug=True)
|
271 |
|
272 |
if __name__ == "__main__":
|