Crawler/web/ubereats/main.py

452 lines
25 KiB
Python

import re
import time
from urllib.parse import unquote
import requests
import json
from lxml import etree
from openpyxl import load_workbook
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
class ubereats:
def __init__(self):
self.html = ""
self.wb = load_workbook('Menu to 11.05PM.xlsx')
self.get_Html()
self.modify_first_row = self.modify_first_row()
def clear_sheet(self, sheet):
ws = self.wb[sheet]
for row in ws.iter_rows(min_row=2): # 首行不清空
for cell in row:
if cell.value is not None:
cell.value = None
self.wb.save('Menu.xlsx')
def clear_except_first_row(self, sheet):
ws = self.wb[sheet]
# **解除所有合并单元格**
merged_ranges = list(ws.merged_cells.ranges)
for merged_range in merged_ranges:
ws.unmerge_cells(str(merged_range))
# **获取最大行和最大列**
max_row = ws.max_row
max_col = ws.max_column
# **清除第二行及之后的所有数据和格式**
if max_row > 1:
for row in range(2, max_row + 1): # 从第二行开始清除
for col in range(1, max_col + 1):
cell = ws.cell(row=row, column=col)
cell.value = None # 清除数据
cell.fill = PatternFill(fill_type=None) # 清除背景色
cell.font = Font() # 重置字体
cell.alignment = Alignment() # 重置对齐方式
cell.border = Border() # 清除边框
# **删除第二行及之后的所有行**
ws.delete_rows(2, max_row - 1 if max_row > 2 else 1)
# **清除行级别格式**
for row in range(2, max_row + 1):
if row in ws.row_dimensions:
ws.row_dimensions[row].fill = PatternFill(fill_type=None) # 清除行级背景色
ws.row_dimensions[row].font = Font() # 清除行级字体
ws.row_dimensions[row].alignment = Alignment() # 清除行级对齐方式
# **保存 Excel**
self.wb.save('Menu.xlsx')
def get_Html(self):
url = "https://www.ubereats.com/store/orlando-china-ocean/xFyut_WfRn6gd83QgBGLoA?diningMode=PICKUP&mod=storeDeliveryTime&modctx=%257B%2522entryPoint%2522%253A%2522store-auto-surface%2522%252C%2522encodedStoreUuid%2522%253A%2522xFyut_WfRn6gd83QgBGLoA%2522%257D&pl=JTdCJTIyYWRkcmVzcyUyMiUzQSUyMkhlbGx1JTIwQ29mZmVlJTIyJTJDJTIycmVmZXJlbmNlJTIyJTNBJTIyQ2hJSjdjWHV4cFlaMmpFUlBtd2dfeGR4TXNFJTIyJTJDJTIycmVmZXJlbmNlVHlwZSUyMiUzQSUyMmdvb2dsZV9wbGFjZXMlMjIlMkMlMjJsYXRpdHVkZSUyMiUzQTEuMjgzMzU3MyUyQyUyMmxvbmdpdHVkZSUyMiUzQTEwMy44NDg0NzMzJTdE&ps=1&sc=SEARCH_SUGGESTION"
payload = {}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate, br, zstd',
'Alt-Used': 'www.ubereats.com',
'Connection': 'keep-alive',
'Cookie': 'uev2.id.xp=13f67607-d8f3-4ef4-ac9c-fae732d3a38c; dId=99b6b840-9ad5-4458-af7e-b832fa6602cb; uev2.id.session=a6af5007-9946-4ab1-a1bc-4d2b69736607; uev2.ts.session=1741796659278; uev2.diningMode=PICKUP; uev2.loc=%7B%22address%22%3A%7B%22address1%22%3A%22Hellu%20Coffee%22%2C%22address2%22%3A%22137%20Amoy%20St%2C%20%2301-05%20Far%20East%20Square%22%2C%22aptOrSuite%22%3A%22%22%2C%22eaterFormattedAddress%22%3A%22137%20Amoy%20St%2C%20%2301-05%20Far%20East%20Square%2C%20Singapore%20049965%22%2C%22subtitle%22%3A%22137%20Amoy%20St%2C%20%2301-05%20Far%20East%20Square%22%2C%22title%22%3A%22Hellu%20Coffee%22%2C%22uuid%22%3A%22%22%7D%2C%22latitude%22%3A1.2833573%2C%22longitude%22%3A103.8484733%2C%22reference%22%3A%22ChIJ7cXuxpYZ2jERPmwg_xdxMsE%22%2C%22referenceType%22%3A%22google_places%22%2C%22type%22%3A%22google_places%22%2C%22addressComponents%22%3A%7B%22city%22%3A%22%22%2C%22countryCode%22%3A%22SG%22%2C%22firstLevelSubdivisionCode%22%3A%22%22%2C%22postalCode%22%3A%22%22%7D%2C%22categories%22%3A%5B%22CAFE%22%2C%22FOOD_AND_BEVERAGE%22%2C%22RESTAURANT%22%2C%22SHOPS_AND_SERVICES%22%2C%22place%22%5D%2C%22originType%22%3A%22user_autocomplete%22%2C%22source%22%3A%22rev_geo_reference%22%2C%22userState%22%3A%22Unknown%22%7D; _ua={"session_id":"bdbf8384-0ffe-4501-90f8-6daa0eea2379","session_time_ms":1741796659351}; marketing_vistor_id=e17c0968-ef3d-4331-8211-c79c2ac7357e; jwt-session=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InNsYXRlLWV4cGlyZXMtYXQiOjE3NDE3OTg0NTkzNTB9LCJpYXQiOjE3NDE3OTY2NjAsImV4cCI6MTc0MTg4MzA2MH0.v-uUZO3RxqF6M29LFRNxNE_LpRMLWx7ApE7b7kPlQMQ; marketing_vistor_id=e17c0968-ef3d-4331-8211-c79c2ac7357e; uev2.diningMode=PICKUP; uev2.id.session=a6af5007-9946-4ab1-a1bc-4d2b69736607; uev2.ts.session=1741796659278',
'Upgrade-Insecure-Requests': '1',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'none',
'Sec-Fetch-User': '?1',
'Priority': 'u=0, i'
}
response = requests.request("GET", url, headers=headers, data=payload)
self.html = response.text.encode('utf-8').decode('unicode_escape')
with open('html_postman2utf8.html', 'w', encoding="utf-8") as f:
f.write(self.html)
# with open('html_11.html', 'r', encoding='utf-8') as f:
# self.html = f.read()
def get_Menu(self):
xpath_info = etree.HTML(self.html)
menu_list = xpath_info.xpath("//button[starts-with(@id, 'tabs-desktop-ofd-menu-tab-')]/span/text()")
menu_time = xpath_info.xpath("//p[@data-baseweb='typo-paragraphxsmall']/text()")
menu_time = menu_time[1].encode('latin-1').decode('utf-8') if menu_list else ""
menu_time = re.sub(r'\s+', '', menu_time) # Menu Description
self.clear_sheet("Menu")
ws = self.wb["Menu"]
ws["A2"] = "Third Party Menu"
self.clear_sheet("Categories")
ws = self.wb["Categories"]
for idx, item in enumerate(menu_list, start=2):
ws.cell(row=idx, column=1, value="Third Party Menu")
ws.cell(row=idx, column=2, value=item)
ws.cell(row=idx, column=3, value="") # 翻译
ws.cell(row=idx, column=4, value=menu_time)
ws.cell(row=idx, column=5, value="")
self.wb.save('Menu.xlsx')
def modify_first_row(self):
ws = self.wb["Modifier"]
source_row = 1
row_data = {}
# 提取第一行数据和格式
for col in range(1, ws.max_column + 1):
source_cell = ws.cell(row=source_row, column=col)
row_data[col] = {
"value": source_cell.value, # 数据
"font": Font(
name=source_cell.font.name,
size=source_cell.font.size,
bold=source_cell.font.bold,
italic=source_cell.font.italic,
underline=source_cell.font.underline,
color=source_cell.font.color.rgb if source_cell.font.color else None
),
"alignment": Alignment(
horizontal=source_cell.alignment.horizontal,
vertical=source_cell.alignment.vertical,
wrap_text=source_cell.alignment.wrap_text
),
"fill": PatternFill(
fill_type=source_cell.fill.patternType,
fgColor=source_cell.fill.fgColor.rgb if source_cell.fill.fgColor else None,
bgColor=source_cell.fill.bgColor.rgb if source_cell.fill.bgColor else None
) if source_cell.fill and source_cell.fill.patternType else None,
"border": Border(
left=Side(style=source_cell.border.left.style, color=source_cell.border.left.color),
right=Side(style=source_cell.border.right.style, color=source_cell.border.right.color),
top=Side(style=source_cell.border.top.style, color=source_cell.border.top.color),
bottom=Side(style=source_cell.border.bottom.style, color=source_cell.border.bottom.color),
) if source_cell.border else None
}
row_data["row_height"] = ws.row_dimensions[source_row].height
return row_data
def get_item(self):
html_info = re.findall(r'<script type="application/json" id=".*?">(.*?)</script>', self.html, re.S)
js2json = unquote(html_info[5])
json_data = json.loads(js2json)
# with open('data.json', 'w', encoding='utf-8') as f:
# f.write(json.dumps(json_data, indent=4))
# exit()
self.clear_except_first_row("Item")
self.clear_except_first_row("Modifier")
ws = self.wb["Item"]
data = []
# with open('data.json', 'r', encoding='utf-8') as f:
# json_data = json.load(f)
queries = json_data['queries'][0]['state']['data']
storeUuid = queries['uuid']
sectionUuid = list(queries["catalogSectionsMap"].keys())[0]
index = 2
for catalog in queries["catalogSectionsMap"][sectionUuid]:
playload = catalog['payload']
standardItemsPayload = playload['standardItemsPayload']
_type = standardItemsPayload['title']['text']
for citem in standardItemsPayload['catalogItems']:
menuItemUuid = citem['uuid']
title = citem['title']
price = citem['price'] / 100
itemDescription = citem['itemDescription']
if "/ ." in itemDescription:
itemDescription = itemDescription.replace("/ .", "")
if "é" in itemDescription:
itemDescription = itemDescription.replace("é", "é")
hasCustomizations = citem['hasCustomizations']
subsectionUuid = citem['subsectionUuid']
if hasCustomizations:
modifier = self.get_itemV1(storeUuid, sectionUuid, subsectionUuid, menuItemUuid)
if modifier['ism'] != 1:
for addons in modifier['addons']:
existing_addon = next((item for item in data if item["name"] == addons["name"]), None)
if existing_addon:
existing_items = {item["name"] for item in existing_addon["list"]}
new_items = [item for item in addons["list"] if item["name"] not in existing_items]
existing_addon["list"].extend(new_items)
else:
data.append(addons)
ws.cell(row=index, column=1, value="Online Lunch Menu")
ws.cell(row=index, column=2, value=_type)
ws.cell(row=index, column=3, value=title)
ws.cell(row=index, column=4, value="")
ws.cell(row=index, column=5, value=price)
ws.cell(row=index, column=7, value=itemDescription)
ws.cell(row=index, column=8, value="Sales Tax")
if not hasCustomizations:
ws.cell(row=index, column=6, value="")
else:
if modifier['ism'] == 3 or modifier['ism'] == 1:
value = ";".join(
[f"{format(price if i['price'] == 0.0 else i['price'] + price, '.2f')}/{i['name']}" for
i in
modifier['sizes']])
ws.cell(row=index, column=5, value=value)
if modifier['ism'] == 3:
v2 = "\n".join([i for i in modifier['nameList']])
ws.cell(row=index, column=6, value=v2)
if modifier['ism'] == 2:
v2 = "\n".join([i['name'] for i in modifier['addons']])
ws.cell(row=index, column=6, value=v2)
index += 1
self.wb.save('Menu.xlsx')
with open('Adata.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
def write_xlsx(self):
ws = self.wb["Modifier"]
self.clear_except_first_row("Modifier") # 清除数据,但保留第一行
with open('Adata.json', 'r', encoding='utf-8') as f:
data = json.load(f)
index = 2 # **确保从第 2 行开始填充数据**
for i in data:
# **确保从 index > 2 才复制格式**
if index > 2:
ws.row_dimensions[index].height = self.modify_first_row["row_height"]
for col, cell_data in self.modify_first_row.items():
if col == "row_height":
continue
target_cell = ws.cell(row=index, column=col)
# **正确赋值**
target_cell.value = cell_data["value"]
# **复制格式**
if cell_data["font"]:
target_cell.font = Font(
name=cell_data["font"].name,
size=cell_data["font"].size,
bold=cell_data["font"].bold,
italic=cell_data["font"].italic,
underline=cell_data["font"].underline,
color=cell_data["font"].color
)
if cell_data["alignment"]:
target_cell.alignment = Alignment(
horizontal=cell_data["alignment"].horizontal,
vertical=cell_data["alignment"].vertical,
wrap_text=cell_data["alignment"].wrap_text
)
if cell_data["fill"] and cell_data["fill"].patternType:
target_cell.fill = PatternFill(
fill_type=cell_data["fill"].patternType,
fgColor=cell_data["fill"].fgColor.rgb,
bgColor=cell_data["fill"].bgColor.rgb
)
if cell_data["border"]:
target_cell.border = Border(
left=Side(style=cell_data["border"].left.style, color=cell_data["border"].left.color),
right=Side(style=cell_data["border"].right.style,
color=cell_data["border"].right.color),
top=Side(style=cell_data["border"].top.style, color=cell_data["border"].top.color),
bottom=Side(style=cell_data["border"].bottom.style,
color=cell_data["border"].bottom.color),
)
index += 1
# **填充 JSON 数据**
ws.cell(row=index, column=1, value=i['name'])
ws.cell(row=index, column=2, value="")
ws.cell(row=index, column=7, value="Required" if i['required'] else "Not Required")
ws.cell(row=index, column=8, value="1")
ws.cell(row=index, column=9, value=i['maxPermitted'])
ws.cell(row=index, column=10, value="NO")
aindex = index
for item in i['list']:
ws.cell(row=index, column=3, value=item['name'])
ws.cell(row=index, column=6, value=item['price'])
index += 1
index += 1
bindex = index
if bindex - aindex > 1:
ws.merge_cells(start_row=aindex, start_column=1, end_row=bindex - 2, end_column=1)
ws.cell(row=aindex, column=1).alignment = Alignment(horizontal="center", vertical="center")
ws.merge_cells(start_row=aindex, start_column=2, end_row=bindex - 2, end_column=2)
ws.cell(row=aindex, column=2).alignment = Alignment(horizontal="center", vertical="center")
ws.merge_cells(start_row=aindex, start_column=7, end_row=bindex - 2, end_column=7)
ws.cell(row=aindex, column=7).alignment = Alignment(horizontal="center", vertical="center")
ws.merge_cells(start_row=aindex, start_column=8, end_row=bindex - 2, end_column=8)
ws.cell(row=aindex, column=8).alignment = Alignment(horizontal="center", vertical="center")
ws.merge_cells(start_row=aindex, start_column=9, end_row=bindex - 2, end_column=9)
ws.cell(row=aindex, column=9).alignment = Alignment(horizontal="center", vertical="center")
ws.merge_cells(start_row=aindex, start_column=10, end_row=bindex - 2, end_column=10)
ws.cell(row=aindex, column=10).alignment = Alignment(horizontal="center", vertical="center")
self.wb.save('Menu.xlsx')
def get_itemV1(self, storeUuid, sectionUuid, subsectionUuid, menuItemUuid):
cookies = {
'dId': '201f1380-db90-4fce-b53c-9e5f1a1797db',
'uev2.diningMode': 'PICKUP',
'marketing_vistor_id': 'b2b08d27-61c5-49a5-8960-3bf57d7dc740',
'u-cookie-prefs': 'eyJ2ZXJzaW9uIjoxMDAsImRhdGUiOjE3NDExNzE2MjgyODAsImNvb2tpZUNhdGVnb3JpZXMiOlsiYWxsIl0sImltcGxpY2l0Ijp0cnVlfQ%3D%3D',
'uev2.gg': 'true',
'_gcl_au': '1.1.639637700.1741171631',
'_scid': 'PKHcwyQACjnCw9d1hw_hGGK2mECWKPAw',
'_fbp': 'fb.1.1741171631251.75638408989351243',
'_ga': 'GA1.1.1953756175.1741171632',
'_ScCbts': '%5B%5D',
'_yjsu_yjad': '1741171631.b78cd8ba-9e38-46b9-b413-15deb0d5a676',
'_sctr': '1%7C1741104000000',
'_tt_enable_cookie': '1',
'_ttp': '01JNJYND745JBKHC19JF1B3ENF_.tt.1',
'uev2.embed_theme_preference': 'dark',
'uev2.id.xp': 'bd485f5e-f8f1-4dce-bf88-c1e92a3cd4c0',
'_ua': '{"session_id":"f08842b9-416c-4e82-bed0-25250e9abe14","session_time_ms":1741398128598}',
'utm_medium': 'undefined',
'utm_source': 'undefined',
'_clck': 'oo6f3j%7C2%7Cfu1%7C0%7C1890',
'uev2.loc': '%7B%22address%22%3A%7B%22address1%22%3A%22Hellu%20Coffee%22%2C%22address2%22%3A%22137%20Amoy%20St%2C%20%2301-05%20Far%20East%20Square%22%2C%22aptOrSuite%22%3A%22%22%2C%22eaterFormattedAddress%22%3A%22137%20Amoy%20St%2C%20%2301-05%20Far%20East%20Square%2C%20Singapore%20049965%22%2C%22subtitle%22%3A%22137%20Amoy%20St%2C%20%2301-05%20Far%20East%20Square%22%2C%22title%22%3A%22Hellu%20Coffee%22%2C%22uuid%22%3A%22%22%7D%2C%22latitude%22%3A1.2833573%2C%22longitude%22%3A103.8484733%2C%22reference%22%3A%22ChIJ7cXuxpYZ2jERPmwg_xdxMsE%22%2C%22referenceType%22%3A%22google_places%22%2C%22type%22%3A%22google_places%22%2C%22addressComponents%22%3A%7B%22city%22%3A%22%22%2C%22countryCode%22%3A%22SG%22%2C%22firstLevelSubdivisionCode%22%3A%22%22%2C%22postalCode%22%3A%22%22%7D%2C%22categories%22%3A%5B%22CAFE%22%2C%22FOOD_AND_BEVERAGE%22%2C%22RESTAURANT%22%2C%22SHOPS_AND_SERVICES%22%2C%22place%22%5D%2C%22originType%22%3A%22user_autocomplete%22%2C%22source%22%3A%22manual_auto_complete%22%2C%22userState%22%3A%22Unknown%22%7D',
'uev2.id.session': '92a4abd6-d9c4-4a11-97ee-ae4a7083eedd',
'uev2.ts.session': '1741414539843',
'jwt-session': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InNsYXRlLWV4cGlyZXMtYXQiOjE3NDE0MTYzNDAyOTl9LCJpYXQiOjE3NDEzOTgxMjksImV4cCI6MTc0MTQ4NDUyOX0.hpvIQEo4HoKsyOfRlVGrxuXN1dO_R_9k_tHCbMe_q3s',
'utag_main__sn': '5',
'utag_main_ses_id': '1741414545690%3Bexp-session',
'utag_main__pn': '1%3Bexp-session',
'_scid_r': 'SCHcwyQACjnCw9d1hw_hGGK2mECWKPAwQvf-Wg',
'utag_main__se': '2%3Bexp-session',
'utag_main__ss': '0%3Bexp-session',
'utag_main__st': '1741416357381%3Bexp-session',
'_userUuid': '',
'_ga_P1RM71MPFP': 'GS1.1.1741414542.6.1.1741414563.39.0.0',
'_uetsid': '8fabeee0fbbe11ef9b636786bd2c1b62',
'_uetvid': '32f691f0f9af11efad4d6dc246fea42a',
}
headers = {
'accept': '*/*',
'accept-language': 'zh-CN,zh;q=0.9',
'cache-control': 'no-cache',
'content-type': 'application/json',
'origin': 'https://www.ubereats.com',
'pragma': 'no-cache',
'priority': 'u=1, i',
# 'referer': 'https://www.ubereats.com/store/orlando-china-ocean/xFyut_WfRn6gd83QgBGLoA?diningMode=PICKUP&mod=quickView&modctx=%257B%2522storeUuid%2522%253A%2522c45caeb7-f59f-467e-a077-cdd080118ba0%2522%252C%2522sectionUuid%2522%253A%2522aa0f2b6d-8a05-575d-824a-814fa08b06d9%2522%252C%2522subsectionUuid%2522%253A%25228a6f7010-f06b-5f85-b417-38d9e96676f7%2522%252C%2522itemUuid%2522%253A%2522bad6eebb-46ff-571e-8d30-d42c40cdb62b%2522%252C%2522showSeeDetailsCTA%2522%253Atrue%257D&ps=1&sc=SEARCH_SUGGESTION',
'sec-ch-prefers-color-scheme': 'dark',
'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Google Chrome";v="134"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36',
'x-csrf-token': 'x',
'x-uber-client-gitref': 'a7f1b446e212f9e1ae1ee1c6541dbf565c7c6293'
}
json_data = {
'itemRequestType': 'ITEM',
'storeUuid': storeUuid,
'sectionUuid': sectionUuid,
'subsectionUuid': subsectionUuid,
'menuItemUuid': menuItemUuid,
'cbType': 'EATER_ENDORSED',
'contextReferences': [
{
'type': 'GROUP_ITEMS',
'payload': {
'type': 'groupItemsContextReferencePayload',
'groupItemsContextReferencePayload': {},
},
'pageContext': 'UNKNOWN',
},
],
}
proxies = {
'http': 'http://127.0.0.1:7890',
'https': 'http://127.0.0.1:7890'
}
response = requests.post('https://www.ubereats.com/_p/api/getMenuItemV1', cookies=cookies, headers=headers,
json=json_data, proxies=None).json()
size_identifiers = ["(S)", "(L)", "(小)", "(大)", "(Half Gallon)", "(One Gallon)", "1.4pcs", "8pcs", "4pcs"]
data = {"ism": 0, "sizes": [], "addons": [], "nameList": []} # **新增 nameList**
has_size_option = False
has_addon_option = False
customizationsList = response['data']['customizationsList']
for customizations in customizationsList:
title = customizations['title']
customization_entry = {"name": title, "list": []}
for item in customizations['options']:
option_title = item['title']
price = item['price'] / 100
is_required = customizations['minPermitted'] > 0
customization_entry["required"] = is_required
customization_entry["maxPermitted"] = customizations['maxPermitted']
if any(option_title.startswith(size) for size in size_identifiers):
data['sizes'].append({"name": option_title, "price": price})
has_size_option = True
else:
customization_entry["list"].append({"name": option_title, "price": price})
has_addon_option = True
# **解析子配菜**
if "childCustomizationList" in item and len(item['childCustomizationList']) > 0:
for child_customization in item["childCustomizationList"]:
for child_option in child_customization["options"]:
child_option_title = child_option["title"]
child_price = child_option["price"] / 100
customization_entry["list"].append({"name": child_option_title, "price": child_price})
has_addon_option = True # **子配菜也是配菜*
if customization_entry["list"]:
data["addons"].append(customization_entry)
# **在 ism=3 时,生成 `nameList`**
if has_size_option and has_addon_option:
data['ism'] = 3 # **大小份 + 配菜**
data['ism'] = 3 # **大小份 + 配菜**
rename = data["addons"][0]["name"]
data['nameList'] = [f"{size['name']}: {rename}" for size in data["sizes"]]
elif has_size_option:
data['ism'] = 1 # **只有大小份**
elif has_addon_option:
data['ism'] = 2 # **只有配菜**
print(data) # **检查数据是否正确**
return data
if __name__ == '__main__':
ubereats = ubereats()
ubereats.get_Menu()
ubereats.get_item()
ubereats.get_item()
ubereats.write_xlsx()
# ubereats.get_itemV1("","","","")
# ubereats.get_itemV1("0212c830-1845-41d2-aa06-6c78bfb97315", "516658e0-667f-5063-a3e9-d9d3e13a2e53", "017a5d2c-88c7-5f1e-8c5e-d8bf76ac5d12", "28eaf6a2-f83b-5d67-b20a-1cd59b4ed42c")
# ubereats.write_xlsx()