modified: amazon/__pycache__/approve.cpython-39.pyc
modified: amazon/__pycache__/asin_status.cpython-39.pyc modified: amazon/__pycache__/del_brand.cpython-39.pyc modified: amazon/__pycache__/match_action.cpython-39.pyc modified: amazon/__pycache__/price_match.cpython-39.pyc modified: amazon/approve.py modified: amazon/asin_status.py modified: amazon/del_brand.py modified: amazon/match_action.py modified: amazon/price_match.py modified: main.py
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1082,6 +1082,68 @@ class ApproveTask:
|
|||||||
del runing_shop[shop_name]
|
del runing_shop[shop_name]
|
||||||
self.log(f"店铺 {shop_name} 已从执行列表中移除")
|
self.log(f"店铺 {shop_name} 已从执行列表中移除")
|
||||||
|
|
||||||
|
def action_init(self,driver,country_name,shop_name,risk_listing_filter):
|
||||||
|
"""切换到指定国际 -> 页面 -》 筛选好"""
|
||||||
|
max_retries = 5
|
||||||
|
switch_success = False
|
||||||
|
switch_success_pg = False
|
||||||
|
search_success = False
|
||||||
|
sku_ls = []
|
||||||
|
for retry in range(max_retries):
|
||||||
|
try:
|
||||||
|
self.log(f"尝试切换到国家 {country_name} (第 {retry + 1}/{max_retries} 次)")
|
||||||
|
if retry > 2:
|
||||||
|
# 刷新不行就重新打开店铺
|
||||||
|
self.log("重试前重新打开店铺...")
|
||||||
|
try:
|
||||||
|
driver.close_store()
|
||||||
|
time.sleep(3)
|
||||||
|
driver.open_shop(shop_name)
|
||||||
|
except Exception as e:
|
||||||
|
self.log(f"关闭重新打开店铺: {str(e)}", "WARNING")
|
||||||
|
# 如果不是第一次尝试,先刷新页面
|
||||||
|
if retry > 0:
|
||||||
|
self.log("重试前刷新页面...")
|
||||||
|
try:
|
||||||
|
driver.tab.refresh()
|
||||||
|
time.sleep(3)
|
||||||
|
except Exception as e:
|
||||||
|
self.log(f"刷新页面失败: {str(e)}", "WARNING")
|
||||||
|
|
||||||
|
switch_success = driver.SwitchingCountries(country_name)
|
||||||
|
if switch_success:
|
||||||
|
self.log(f"成功切换到国家 {country_name}")
|
||||||
|
|
||||||
|
# 切换到库存管理页面
|
||||||
|
driver.SwitchPage()
|
||||||
|
self.log(f"已切换到库存管理页面")
|
||||||
|
time.sleep(3)
|
||||||
|
switch_success_pg = True
|
||||||
|
|
||||||
|
sku_ls = driver.search(filter_type=risk_listing_filter)
|
||||||
|
search_success = True
|
||||||
|
self.log(f"国家 {country_name} 搜索出 {len(sku_ls)} 商品,开始处理...")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
self.log(f"切换到国家 {country_name} 失败", "WARNING")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
import traceback
|
||||||
|
self.log(f"切换国家 {country_name} 异常: {str(e)}", "ERROR")
|
||||||
|
self.log(traceback.format_exc(), "ERROR")
|
||||||
|
|
||||||
|
# 如果还有重试机会,等待后继续
|
||||||
|
if retry < max_retries - 1:
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
# 如果切换失败,直接返回
|
||||||
|
# if not switch_success or not switch_success_pg or not search_success:
|
||||||
|
# error_message = f"切换到国家({switch_success})/库存页面({switch_success_pg})/搜索筛选到指定选项({search_success}) {country_name} 失败,已重试 {max_retries} 次,跳过该国家"
|
||||||
|
# self.log(error_message, "ERROR")
|
||||||
|
# if task_id in runing_task:
|
||||||
|
# runing_task[task_id]["processed_countries"] += 1
|
||||||
|
return switch_success,switch_success_pg,search_success,sku_ls
|
||||||
|
|
||||||
def process_country(self, driver: AmzoneApprove, country_code: str, task_id: int, shop_name: str, risk_listing_filter: str):
|
def process_country(self, driver: AmzoneApprove, country_code: str, task_id: int, shop_name: str, risk_listing_filter: str):
|
||||||
"""处理单个国家的审批任务
|
"""处理单个国家的审批任务
|
||||||
|
|
||||||
@@ -1108,81 +1170,92 @@ class ApproveTask:
|
|||||||
max_retries = 3
|
max_retries = 3
|
||||||
switch_success = False
|
switch_success = False
|
||||||
|
|
||||||
for retry in range(max_retries):
|
# for retry in range(max_retries):
|
||||||
try:
|
# try:
|
||||||
self.log(f"尝试切换到国家 {country_name} (第 {retry + 1}/{max_retries} 次)")
|
# self.log(f"尝试切换到国家 {country_name} (第 {retry + 1}/{max_retries} 次)")
|
||||||
if retry > 1:
|
# if retry > 1:
|
||||||
# 刷新不行就重新打开店铺
|
# # 刷新不行就重新打开店铺
|
||||||
self.log("重试前重新打开店铺...")
|
# self.log("重试前重新打开店铺...")
|
||||||
try:
|
# try:
|
||||||
driver.close_store()
|
# driver.close_store()
|
||||||
time.sleep(3)
|
# time.sleep(3)
|
||||||
driver.open_shop(shop_name)
|
# driver.open_shop(shop_name)
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
self.log(f"关闭重新打开店铺: {str(e)}", "WARNING")
|
# self.log(f"关闭重新打开店铺: {str(e)}", "WARNING")
|
||||||
|
#
|
||||||
# 如果不是第一次尝试,先刷新页面
|
# # 如果不是第一次尝试,先刷新页面
|
||||||
if retry > 0:
|
# if retry > 0:
|
||||||
self.log("重试前刷新页面...")
|
# self.log("重试前刷新页面...")
|
||||||
try:
|
# try:
|
||||||
driver.tab.refresh()
|
# driver.tab.refresh()
|
||||||
time.sleep(3)
|
# time.sleep(3)
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
self.log(f"刷新页面失败: {str(e)}", "WARNING")
|
# self.log(f"刷新页面失败: {str(e)}", "WARNING")
|
||||||
|
#
|
||||||
switch_success = driver.SwitchingCountries(country_name)
|
# switch_success = driver.SwitchingCountries(country_name)
|
||||||
if switch_success:
|
# if switch_success:
|
||||||
self.log(f"成功切换到国家 {country_name}")
|
# self.log(f"成功切换到国家 {country_name}")
|
||||||
break
|
# break
|
||||||
else:
|
# else:
|
||||||
self.log(f"切换到国家 {country_name} 失败", "WARNING")
|
# self.log(f"切换到国家 {country_name} 失败", "WARNING")
|
||||||
|
#
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
import traceback
|
# import traceback
|
||||||
self.log(f"切换国家 {country_name} 异常: {str(e)}", "ERROR")
|
# self.log(f"切换国家 {country_name} 异常: {str(e)}", "ERROR")
|
||||||
self.log(traceback.format_exc(), "ERROR")
|
# self.log(traceback.format_exc(), "ERROR")
|
||||||
|
#
|
||||||
# 如果还有重试机会,等待后继续
|
# # 如果还有重试机会,等待后继续
|
||||||
if retry < max_retries - 1:
|
# if retry < max_retries - 1:
|
||||||
time.sleep(2)
|
# time.sleep(2)
|
||||||
|
#
|
||||||
|
# # 如果切换失败,直接返回
|
||||||
|
# if not switch_success:
|
||||||
|
# error_message = f"切换到国家 {country_name} 失败,已重试 {max_retries} 次,跳过该国家"
|
||||||
|
# self.log(error_message, "ERROR")
|
||||||
|
# if task_id in runing_task:
|
||||||
|
# runing_task[task_id]["processed_countries"] += 1
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
# # 切换到库存管理页面
|
||||||
|
# try:
|
||||||
|
# driver.SwitchPage()
|
||||||
|
# self.log(f"已切换到库存管理页面")
|
||||||
|
# except Exception as e:
|
||||||
|
# import traceback
|
||||||
|
# self.log(f"切换页面失败: {str(e)}", "ERROR")
|
||||||
|
# self.log(traceback.format_exc(), "ERROR")
|
||||||
|
# if task_id in runing_task:
|
||||||
|
# runing_task[task_id]["processed_countries"] += 1
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
# # 搜索需要审批的商品,最多重试3次
|
||||||
|
# sku_ls = []
|
||||||
|
# for retry in range(max_retries):
|
||||||
|
# try:
|
||||||
|
# self.log(f"尝试搜索需要审批的商品 (第 {retry + 1}/{max_retries} 次)")
|
||||||
|
# sku_ls = driver.search(filter_type=risk_listing_filter)
|
||||||
|
# break
|
||||||
|
# except Exception as e:
|
||||||
|
# self.log(f"搜索商品异常: {str(e)}", "ERROR")
|
||||||
|
# if retry < max_retries - 1:
|
||||||
|
# try:
|
||||||
|
# driver.tab.refresh()
|
||||||
|
# time.sleep(3)
|
||||||
|
# except Exception as refresh_error:
|
||||||
|
# self.log(f"刷新页面失败: {str(refresh_error)}", "WARNING")
|
||||||
|
#
|
||||||
|
max_retries = 5
|
||||||
|
switch_success, switch_success_pg, search_success,sku_ls = self.action_init(driver, country_name, shop_name,
|
||||||
|
risk_listing_filter)
|
||||||
# 如果切换失败,直接返回
|
# 如果切换失败,直接返回
|
||||||
if not switch_success:
|
if not switch_success or not switch_success_pg or not search_success:
|
||||||
error_message = f"切换到国家 {country_name} 失败,已重试 {max_retries} 次,跳过该国家"
|
error_message = f"切换到国家({switch_success})/库存页面({switch_success_pg})/搜索筛选到指定选项({search_success}) {country_name} 失败,已重试 {max_retries} 次,跳过该国家"
|
||||||
self.log(error_message, "ERROR")
|
self.log(error_message, "ERROR")
|
||||||
if task_id in runing_task:
|
if task_id in runing_task:
|
||||||
runing_task[task_id]["processed_countries"] += 1
|
runing_task[task_id]["processed_countries"] += 1
|
||||||
return
|
return
|
||||||
|
|
||||||
# 切换到库存管理页面
|
# # 如果没有需要审批的商品,直接返回
|
||||||
try:
|
|
||||||
driver.SwitchPage()
|
|
||||||
self.log(f"已切换到库存管理页面")
|
|
||||||
except Exception as e:
|
|
||||||
import traceback
|
|
||||||
self.log(f"切换页面失败: {str(e)}", "ERROR")
|
|
||||||
self.log(traceback.format_exc(), "ERROR")
|
|
||||||
if task_id in runing_task:
|
|
||||||
runing_task[task_id]["processed_countries"] += 1
|
|
||||||
return
|
|
||||||
|
|
||||||
# 搜索需要审批的商品,最多重试3次
|
|
||||||
sku_ls = []
|
|
||||||
for retry in range(max_retries):
|
|
||||||
try:
|
|
||||||
self.log(f"尝试搜索需要审批的商品 (第 {retry + 1}/{max_retries} 次)")
|
|
||||||
sku_ls = driver.search(filter_type=risk_listing_filter)
|
|
||||||
break
|
|
||||||
except Exception as e:
|
|
||||||
self.log(f"搜索商品异常: {str(e)}", "ERROR")
|
|
||||||
if retry < max_retries - 1:
|
|
||||||
try:
|
|
||||||
driver.tab.refresh()
|
|
||||||
time.sleep(3)
|
|
||||||
except Exception as refresh_error:
|
|
||||||
self.log(f"刷新页面失败: {str(refresh_error)}", "WARNING")
|
|
||||||
|
|
||||||
# 如果没有需要审批的商品,直接返回
|
|
||||||
if len(sku_ls) == 0:
|
if len(sku_ls) == 0:
|
||||||
self.log(f"国家 {country_name} 没有需要审批的商品")
|
self.log(f"国家 {country_name} 没有需要审批的商品")
|
||||||
if task_id in runing_task:
|
if task_id in runing_task:
|
||||||
|
|||||||
@@ -537,8 +537,6 @@ class StatusTask:
|
|||||||
self.log(f"切换页面失败重试退出", "ERROR")
|
self.log(f"切换页面失败重试退出", "ERROR")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 处理所有需要审批的商品(通过yield获取结果)
|
# 处理所有需要审批的商品(通过yield获取结果)
|
||||||
|
|
||||||
# 指定 asin
|
# 指定 asin
|
||||||
|
|||||||
@@ -8,11 +8,12 @@ import json
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from typing import Literal
|
from typing import Literal
|
||||||
from DrissionPage import Chromium
|
from DrissionPage import Chromium,ChromiumOptions
|
||||||
from DrissionPage.common import By
|
from DrissionPage.common import By
|
||||||
from DrissionPage._pages.chromium_tab import ChromiumTab
|
from DrissionPage._pages.chromium_tab import ChromiumTab
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def kill_process(version: Literal["v5", "v6"]):
|
def kill_process(version: Literal["v5", "v6"]):
|
||||||
"""杀紫鸟客户端进程(独立函数版本)"""
|
"""杀紫鸟客户端进程(独立函数版本)"""
|
||||||
driver = ZiniaoDriver({})
|
driver = ZiniaoDriver({})
|
||||||
@@ -205,7 +206,11 @@ class ZiniaoDriver:
|
|||||||
Returns:
|
Returns:
|
||||||
Chromium: DrissionPage浏览器实例
|
Chromium: DrissionPage浏览器实例
|
||||||
"""
|
"""
|
||||||
browser = Chromium(port)
|
co = ChromiumOptions()
|
||||||
|
# 设置不加载图片、静音
|
||||||
|
co.set_local_port(port)
|
||||||
|
co.no_imgs(True).mute(True)
|
||||||
|
browser = Chromium(co)
|
||||||
return browser
|
return browser
|
||||||
|
|
||||||
def start_client(self):
|
def start_client(self):
|
||||||
|
|||||||
@@ -468,6 +468,70 @@ class MatchTak:
|
|||||||
del runing_shop[shop_name]
|
del runing_shop[shop_name]
|
||||||
self.log(f"店铺 {shop_name} 已从执行列表中移除")
|
self.log(f"店铺 {shop_name} 已从执行列表中移除")
|
||||||
|
|
||||||
|
def action_init(self,driver,country_name,shop_name,risk_listing_filter):
|
||||||
|
"""切换到指定国际 -> 页面 -》 筛选好"""
|
||||||
|
max_retries = 5
|
||||||
|
switch_success = False
|
||||||
|
switch_success_pg = False
|
||||||
|
search_success = False
|
||||||
|
sku_ls = []
|
||||||
|
for retry in range(max_retries):
|
||||||
|
try:
|
||||||
|
self.log(f"尝试切换到国家 {country_name} (第 {retry + 1}/{max_retries} 次)")
|
||||||
|
if retry > 2:
|
||||||
|
# 刷新不行就重新打开店铺
|
||||||
|
self.log("重试前重新打开店铺...")
|
||||||
|
try:
|
||||||
|
driver.close_store()
|
||||||
|
time.sleep(3)
|
||||||
|
driver.open_shop(shop_name)
|
||||||
|
except Exception as e:
|
||||||
|
self.log(f"关闭重新打开店铺: {str(e)}", "WARNING")
|
||||||
|
# 如果不是第一次尝试,先刷新页面
|
||||||
|
if retry > 0:
|
||||||
|
self.log("重试前刷新页面...")
|
||||||
|
try:
|
||||||
|
driver.tab.refresh()
|
||||||
|
time.sleep(3)
|
||||||
|
except Exception as e:
|
||||||
|
self.log(f"刷新页面失败: {str(e)}", "WARNING")
|
||||||
|
|
||||||
|
switch_success = driver.SwitchingCountries(country_name)
|
||||||
|
if switch_success:
|
||||||
|
self.log(f"成功切换到国家 {country_name}")
|
||||||
|
|
||||||
|
# 切换到库存管理页面
|
||||||
|
driver.SwitchPage()
|
||||||
|
self.log(f"已切换到库存管理页面")
|
||||||
|
time.sleep(3)
|
||||||
|
switch_success_pg = True
|
||||||
|
|
||||||
|
sku_ls = driver.search(filter_type=risk_listing_filter)
|
||||||
|
search_success = True
|
||||||
|
self.log(f"国家 {country_name} 搜索出 {len(sku_ls)} 商品,开始处理...")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
self.log(f"切换到国家 {country_name} 失败", "WARNING")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
import traceback
|
||||||
|
self.log(f"切换国家 {country_name} 异常: {str(e)}", "ERROR")
|
||||||
|
self.log(traceback.format_exc(), "ERROR")
|
||||||
|
|
||||||
|
# 如果还有重试机会,等待后继续
|
||||||
|
if retry < max_retries - 1:
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
# 如果切换失败,直接返回
|
||||||
|
# if not switch_success or not switch_success_pg or not search_success:
|
||||||
|
# error_message = f"切换到国家({switch_success})/库存页面({switch_success_pg})/搜索筛选到指定选项({search_success}) {country_name} 失败,已重试 {max_retries} 次,跳过该国家"
|
||||||
|
# self.log(error_message, "ERROR")
|
||||||
|
# if task_id in runing_task:
|
||||||
|
# runing_task[task_id]["processed_countries"] += 1
|
||||||
|
return switch_success,switch_success_pg,search_success,sku_ls
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def process_country(self, driver: AmzoneMatchAction, country_code: str, task_id: int, shop_name: str, risk_listing_filter: str,limit:str=None):
|
def process_country(self, driver: AmzoneMatchAction, country_code: str, task_id: int, shop_name: str, risk_listing_filter: str,limit:str=None):
|
||||||
"""处理单个国家的审批任务
|
"""处理单个国家的审批任务
|
||||||
|
|
||||||
@@ -491,86 +555,104 @@ class MatchTak:
|
|||||||
runing_task[task_id]["current_country"] = country_name
|
runing_task[task_id]["current_country"] = country_name
|
||||||
|
|
||||||
# 切换国家,最多重试3次
|
# 切换国家,最多重试3次
|
||||||
max_retries = 3
|
# max_retries = 3
|
||||||
switch_success = False
|
# switch_success = False
|
||||||
|
#
|
||||||
for retry in range(max_retries):
|
# for retry in range(max_retries):
|
||||||
try:
|
# try:
|
||||||
self.log(f"尝试切换到国家 {country_name} (第 {retry + 1}/{max_retries} 次)")
|
# self.log(f"尝试切换到国家 {country_name} (第 {retry + 1}/{max_retries} 次)")
|
||||||
if retry > 1:
|
# if retry > 1:
|
||||||
# 刷新不行就重新打开店铺
|
# # 刷新不行就重新打开店铺
|
||||||
self.log("重试前重新打开店铺...")
|
# self.log("重试前重新打开店铺...")
|
||||||
try:
|
# try:
|
||||||
driver.close_store()
|
# driver.close_store()
|
||||||
time.sleep(3)
|
# time.sleep(3)
|
||||||
driver.open_shop(shop_name)
|
# driver.open_shop(shop_name)
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
self.log(f"关闭重新打开店铺: {str(e)}", "WARNING")
|
# self.log(f"关闭重新打开店铺: {str(e)}", "WARNING")
|
||||||
|
#
|
||||||
# 如果不是第一次尝试,先刷新页面
|
# # 如果不是第一次尝试,先刷新页面
|
||||||
if retry > 0:
|
# if retry > 0:
|
||||||
self.log("重试前刷新页面...")
|
# self.log("重试前刷新页面...")
|
||||||
try:
|
# try:
|
||||||
driver.tab.refresh()
|
# driver.tab.refresh()
|
||||||
time.sleep(3)
|
# time.sleep(3)
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
self.log(f"刷新页面失败: {str(e)}", "WARNING")
|
# self.log(f"刷新页面失败: {str(e)}", "WARNING")
|
||||||
|
#
|
||||||
switch_success = driver.SwitchingCountries(country_name)
|
# switch_success = driver.SwitchingCountries(country_name)
|
||||||
if switch_success:
|
# if switch_success:
|
||||||
self.log(f"成功切换到国家 {country_name}")
|
# self.log(f"成功切换到国家 {country_name}")
|
||||||
break
|
# break
|
||||||
else:
|
# else:
|
||||||
self.log(f"切换到国家 {country_name} 失败", "WARNING")
|
# self.log(f"切换到国家 {country_name} 失败", "WARNING")
|
||||||
|
#
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
import traceback
|
# import traceback
|
||||||
self.log(f"切换国家 {country_name} 异常: {str(e)}", "ERROR")
|
# self.log(f"切换国家 {country_name} 异常: {str(e)}", "ERROR")
|
||||||
self.log(traceback.format_exc(), "ERROR")
|
# self.log(traceback.format_exc(), "ERROR")
|
||||||
|
#
|
||||||
# 如果还有重试机会,等待后继续
|
# # 如果还有重试机会,等待后继续
|
||||||
if retry < max_retries - 1:
|
# if retry < max_retries - 1:
|
||||||
time.sleep(2)
|
# time.sleep(2)
|
||||||
|
#
|
||||||
|
# # 如果切换失败,直接返回
|
||||||
|
# if not switch_success:
|
||||||
|
# error_message = f"切换到国家 {country_name} 失败,已重试 {max_retries} 次,跳过该国家"
|
||||||
|
# self.log(error_message, "ERROR")
|
||||||
|
# if task_id in runing_task:
|
||||||
|
# runing_task[task_id]["processed_countries"] += 1
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
# # 切换到库存管理页面
|
||||||
|
# try:
|
||||||
|
# driver.SwitchPage()
|
||||||
|
# self.log(f"已切换到库存管理页面")
|
||||||
|
# except Exception as e:
|
||||||
|
# import traceback
|
||||||
|
# self.log(f"切换页面失败: {str(e)}", "ERROR")
|
||||||
|
# self.log(traceback.format_exc(), "ERROR")
|
||||||
|
# if task_id in runing_task:
|
||||||
|
# runing_task[task_id]["processed_countries"] += 1
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
# # 搜索需要审批的商品,最多重试3次
|
||||||
|
# sku_ls = []
|
||||||
|
# for retry in range(max_retries):
|
||||||
|
# try:
|
||||||
|
# self.log(f"尝试搜索匹配操作商品 (第 {retry + 1}/{max_retries} 次)")
|
||||||
|
# sku_ls = driver.search(filter_type=risk_listing_filter)
|
||||||
|
# break
|
||||||
|
# except Exception as e:
|
||||||
|
# self.log(f"搜索商品异常: {str(e)}", "ERROR")
|
||||||
|
# if retry < max_retries - 1:
|
||||||
|
# try:
|
||||||
|
# driver.tab.refresh()
|
||||||
|
# time.sleep(3)
|
||||||
|
# except Exception as refresh_error:
|
||||||
|
# self.log(f"刷新页面失败: {str(refresh_error)}", "WARNING")
|
||||||
|
#
|
||||||
|
# # 如果没有需要审批的商品,直接返回
|
||||||
|
# if len(sku_ls) == 0:
|
||||||
|
# self.log(f"国家 {country_name} 没有搜索出的商品")
|
||||||
|
# if task_id in runing_task:
|
||||||
|
# runing_task[task_id]["processed_countries"] += 1
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
max_retries = 5
|
||||||
|
switch_success, switch_success_pg, search_success, sku_ls = self.action_init(driver, country_name, shop_name,
|
||||||
|
risk_listing_filter)
|
||||||
# 如果切换失败,直接返回
|
# 如果切换失败,直接返回
|
||||||
if not switch_success:
|
if not switch_success or not switch_success_pg or not search_success:
|
||||||
error_message = f"切换到国家 {country_name} 失败,已重试 {max_retries} 次,跳过该国家"
|
error_message = f"切换到国家({switch_success})/库存页面({switch_success_pg})/搜索筛选到指定选项({search_success}) {country_name} 失败,已重试 {max_retries} 次,跳过该国家"
|
||||||
self.log(error_message, "ERROR")
|
self.log(error_message, "ERROR")
|
||||||
if task_id in runing_task:
|
if task_id in runing_task:
|
||||||
runing_task[task_id]["processed_countries"] += 1
|
runing_task[task_id]["processed_countries"] += 1
|
||||||
return
|
return
|
||||||
|
|
||||||
# 切换到库存管理页面
|
# # 如果没有需要审批的商品,直接返回
|
||||||
try:
|
|
||||||
driver.SwitchPage()
|
|
||||||
self.log(f"已切换到库存管理页面")
|
|
||||||
except Exception as e:
|
|
||||||
import traceback
|
|
||||||
self.log(f"切换页面失败: {str(e)}", "ERROR")
|
|
||||||
self.log(traceback.format_exc(), "ERROR")
|
|
||||||
if task_id in runing_task:
|
|
||||||
runing_task[task_id]["processed_countries"] += 1
|
|
||||||
return
|
|
||||||
|
|
||||||
# 搜索需要审批的商品,最多重试3次
|
|
||||||
sku_ls = []
|
|
||||||
for retry in range(max_retries):
|
|
||||||
try:
|
|
||||||
self.log(f"尝试搜索匹配操作商品 (第 {retry + 1}/{max_retries} 次)")
|
|
||||||
sku_ls = driver.search(filter_type=risk_listing_filter)
|
|
||||||
break
|
|
||||||
except Exception as e:
|
|
||||||
self.log(f"搜索商品异常: {str(e)}", "ERROR")
|
|
||||||
if retry < max_retries - 1:
|
|
||||||
try:
|
|
||||||
driver.tab.refresh()
|
|
||||||
time.sleep(3)
|
|
||||||
except Exception as refresh_error:
|
|
||||||
self.log(f"刷新页面失败: {str(refresh_error)}", "WARNING")
|
|
||||||
|
|
||||||
# 如果没有需要审批的商品,直接返回
|
|
||||||
if len(sku_ls) == 0:
|
if len(sku_ls) == 0:
|
||||||
self.log(f"国家 {country_name} 没有搜索出的商品")
|
self.log(f"国家 {country_name} 没有需要审批的商品")
|
||||||
if task_id in runing_task:
|
if task_id in runing_task:
|
||||||
runing_task[task_id]["processed_countries"] += 1
|
runing_task[task_id]["processed_countries"] += 1
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -16,28 +16,32 @@ from amazon.tool import show_notification,get_shop_info,remove_special_character
|
|||||||
|
|
||||||
from config import runing_task, runing_shop,base_dir,DELETE_BRAND_API_BASE
|
from config import runing_task, runing_shop,base_dir,DELETE_BRAND_API_BASE
|
||||||
|
|
||||||
|
|
||||||
class RepricingLogic:
|
class RepricingLogic:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def situation_1_general_decrease(my_price, rank1_price, is_first_time=False):
|
def situation_1_general_decrease(my_price, rank1_price, is_first_time=False):
|
||||||
"""
|
"""
|
||||||
情况1:常规递减跟价 (最左侧独立长图块)
|
情况1:常规递减跟价 (最左侧独立长图块)
|
||||||
当不是自己购物车时,按总价当作第一名递减。
|
|
||||||
"""
|
"""
|
||||||
if is_first_time:
|
if is_first_time:
|
||||||
return rank1_price - 0.3
|
return rank1_price - 0.3
|
||||||
|
|
||||||
diff = my_price - rank1_price
|
# 这里的 diff 算出的是一个正数,代表“我比第一名低多少”
|
||||||
|
diff = rank1_price - my_price
|
||||||
|
|
||||||
# 精简了原图中长串的阶梯逻辑
|
# 如果当前价格高于或等于第一名,默认按照第一名减0.3处理
|
||||||
|
if diff <= 0:
|
||||||
|
return rank1_price - 0.3
|
||||||
|
|
||||||
|
# 逻辑更清晰的写法:第一名价格 - (差价 + 对应阶梯值)
|
||||||
|
# 例如差价0.7,则相当于 第一名价格 - (0.7 + 0.5) = 第一名价格 - 1.2
|
||||||
if diff <= 0.3:
|
if diff <= 0.3:
|
||||||
return rank1_price - 0.5
|
return rank1_price - (diff + 0.5)
|
||||||
elif diff <= 0.8:
|
elif diff <= 0.8:
|
||||||
return rank1_price - 0.7
|
return rank1_price - (diff + 0.7)
|
||||||
elif diff <= 10.5:
|
elif diff <= 10.5:
|
||||||
# 0.8 到 10.5 之间,原图逻辑全部是“减1”
|
# 0.8 到 10.5 之间全部是在减1
|
||||||
return rank1_price - 1.0
|
return rank1_price - (diff + 1.0)
|
||||||
else:
|
else:
|
||||||
return None # 相差10.5以上,跳过
|
return None # 相差10.5以上,跳过
|
||||||
|
|
||||||
@@ -45,55 +49,56 @@ class RepricingLogic:
|
|||||||
def situation_2_own_buybox(my_price, rank2_price):
|
def situation_2_own_buybox(my_price, rank2_price):
|
||||||
"""
|
"""
|
||||||
情况2:已经是自己购物车
|
情况2:已经是自己购物车
|
||||||
逻辑:判断与第二名的差价,如果拉开足够差距,则稍微降一点点(减0.5)保持优势,防止卖太便宜。
|
|
||||||
"""
|
"""
|
||||||
diff = rank2_price - my_price
|
diff = rank2_price - my_price
|
||||||
|
|
||||||
# 1. 绝对差价2欧以上
|
|
||||||
if diff >= 2.0:
|
if diff >= 2.0:
|
||||||
return rank2_price - 0.3
|
return rank2_price - 0.3
|
||||||
|
|
||||||
# 2. 产品售价区间判定 (是否要提高价格)
|
|
||||||
if (20 <= my_price < 30 and diff >= 4) or \
|
if (20 <= my_price < 30 and diff >= 4) or \
|
||||||
(30 <= my_price < 60 and diff >= 8) or \
|
(30 <= my_price < 60 and diff >= 8) or \
|
||||||
(60 <= my_price <= 150 and diff >= 15):
|
(60 <= my_price <= 150 and diff >= 15):
|
||||||
return rank2_price - 0.3 # 满足区间大差价,提价至第二名之下
|
return rank2_price - 0.3
|
||||||
|
|
||||||
return my_price # 不满足条件则保持原价
|
return my_price
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def situation_3_not_own_buybox(my_price, rank1_price):
|
def situation_3_not_own_buybox(my_price, rank1_price):
|
||||||
"""
|
"""
|
||||||
情况3:不是自己购物车 (常规情况)
|
情况3:不是自己购物车 (除Amazon US外)
|
||||||
"""
|
"""
|
||||||
diff = my_price - rank1_price
|
diff = rank1_price - my_price
|
||||||
|
|
||||||
|
if diff <= 0:
|
||||||
|
return rank1_price - 0.3
|
||||||
|
|
||||||
|
# 逻辑更清晰的写法:第一名价格 - (差价 + 对应阶梯值)
|
||||||
if diff <= 0.3:
|
if diff <= 0.3:
|
||||||
return rank1_price - 0.5
|
return rank1_price - (diff + 0.5)
|
||||||
elif 0.5 <= diff <= 0.8:
|
elif diff <= 0.8:
|
||||||
return rank1_price - 0.7
|
return rank1_price - (diff + 0.7)
|
||||||
elif 0.8 < diff <= 2.5:
|
elif diff <= 2.5:
|
||||||
return rank1_price - 1.0
|
return rank1_price - (diff + 1.0)
|
||||||
elif diff > 2.5: # 2.5-3.5以上跳过
|
else:
|
||||||
return None
|
return None # 2.5-3.5以上跳过
|
||||||
|
|
||||||
return rank1_price - 0.3 # 默认按第一名减0.3
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def situation_4_encounter_amz_us_1st(my_price, amz_us_price):
|
def situation_4_encounter_amz_us_1st(my_price, amz_us_price):
|
||||||
"""
|
"""
|
||||||
情况4:第一名是 Amazon US 卖家
|
情况4:遇到第一名是 Amazon US 卖家
|
||||||
"""
|
"""
|
||||||
diff = my_price - amz_us_price
|
diff = amz_us_price - my_price
|
||||||
|
|
||||||
if diff <= 3:
|
if diff <= 0:
|
||||||
return amz_us_price - 2
|
|
||||||
elif 4 <= diff <= 6:
|
|
||||||
return amz_us_price - 3
|
return amz_us_price - 3
|
||||||
elif 8 <= diff <= 12:
|
|
||||||
return None # 跳过不跟价
|
|
||||||
|
|
||||||
return amz_us_price - 3 # 默认直接按照 Amazon US 减去3
|
# 逻辑更清晰的写法:第一名价格 - (差价 + 对应阶梯值)
|
||||||
|
if diff <= 3:
|
||||||
|
return amz_us_price - (diff + 2)
|
||||||
|
elif diff <= 6:
|
||||||
|
return amz_us_price - (diff + 3)
|
||||||
|
else:
|
||||||
|
return None # 超过6直接跳过
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def situation_5_im_1st_amz_us_2nd(my_price, amz_us_price):
|
def situation_5_im_1st_amz_us_2nd(my_price, amz_us_price):
|
||||||
@@ -103,7 +108,7 @@ class RepricingLogic:
|
|||||||
diff = amz_us_price - my_price
|
diff = amz_us_price - my_price
|
||||||
|
|
||||||
if diff <= 7:
|
if diff <= 7:
|
||||||
return None # 相差5以内跳过 (保持原价)
|
return None # 相差7以内跳过 (保持原价)
|
||||||
else:
|
else:
|
||||||
return amz_us_price - 5
|
return amz_us_price - 5
|
||||||
|
|
||||||
@@ -133,16 +138,6 @@ def calculate_target_price(
|
|||||||
price_col = recommended_price + recommended_shipping
|
price_col = recommended_price + recommended_shipping
|
||||||
print(f"【紫鸟后台价格】{is_my_buybox} 推荐价格: {recommended_price},推荐运费: {recommended_shipping},总和: {price_col}")
|
print(f"【紫鸟后台价格】{is_my_buybox} 推荐价格: {recommended_price},推荐运费: {recommended_shipping},总和: {price_col}")
|
||||||
return RepricingLogic.situation_1_general_decrease(my_price,price_col,is_my_buybox)
|
return RepricingLogic.situation_1_general_decrease(my_price,price_col,is_my_buybox)
|
||||||
# backend_base_price = recommended_price
|
|
||||||
# backend_shipping = recommended_shipping
|
|
||||||
# total_price = backend_base_price + backend_shipping
|
|
||||||
#
|
|
||||||
# if is_my_buybox:
|
|
||||||
# # 🌟【逻辑更新】:如果是自己的购物车,直接跳过,不做任何价格调整
|
|
||||||
# return None
|
|
||||||
# else:
|
|
||||||
# # 不是自己的购物车:直接将紫鸟的总和作为"第一名"价格,强制抛入阶梯跟价逻辑
|
|
||||||
# return calculate_standard_competitor_pricing(my_price, total_price)
|
|
||||||
|
|
||||||
# # 第一名是自己, 第二名 Amazon US 卖家 的情况
|
# # 第一名是自己, 第二名 Amazon US 卖家 的情况
|
||||||
shop_name_1 = front_end_data.get("top_sellers")[0].get("shop_name")
|
shop_name_1 = front_end_data.get("top_sellers")[0].get("shop_name")
|
||||||
@@ -152,13 +147,11 @@ def calculate_target_price(
|
|||||||
return RepricingLogic.situation_5_im_1st_amz_us_2nd(my_price,price_2)
|
return RepricingLogic.situation_5_im_1st_amz_us_2nd(my_price,price_2)
|
||||||
|
|
||||||
# --- Step 3: 常规核心分流逻辑 (如果没有紫鸟后台数据) ---
|
# --- Step 3: 常规核心分流逻辑 (如果没有紫鸟后台数据) ---
|
||||||
|
|
||||||
# 分支 A:第一名是 Amazon US 卖家 (特殊强敌优先)
|
# 分支 A:第一名是 Amazon US 卖家 (特殊强敌优先)
|
||||||
price_1 = float(front_end_data.get("top_sellers")[0].get("price")) # 实际第一名价格
|
price_1 = float(front_end_data.get("top_sellers")[0].get("price")) # 实际第一名价格
|
||||||
if "Amazon" in shop_name_1:
|
if "Amazon" in shop_name_1:
|
||||||
return RepricingLogic.situation_4_encounter_amz_us_1st(my_price,price_1)
|
return RepricingLogic.situation_4_encounter_amz_us_1st(my_price,price_1)
|
||||||
|
|
||||||
|
|
||||||
# 分支 B:不是 Amazon US,且目前是自己的购物车
|
# 分支 B:不是 Amazon US,且目前是自己的购物车
|
||||||
elif is_my_buybox:
|
elif is_my_buybox:
|
||||||
price_2 = float(front_end_data.get("top_sellers")[1].get("price")) # 实际第二名价格
|
price_2 = float(front_end_data.get("top_sellers")[1].get("price")) # 实际第二名价格
|
||||||
@@ -650,6 +643,13 @@ class AmzonePriceMatch(AmamzonBase):
|
|||||||
print(f"【{self.mark_name}】获取到 {len(sku_ls)}")
|
print(f"【{self.mark_name}】获取到 {len(sku_ls)}")
|
||||||
|
|
||||||
if len(sku_ls) == 0:
|
if len(sku_ls) == 0:
|
||||||
|
if mode == "asin":
|
||||||
|
print(f"asin 模式查询不到,{asin}")
|
||||||
|
yield (asin, {
|
||||||
|
"statu": "查询不到"
|
||||||
|
})
|
||||||
|
break
|
||||||
|
|
||||||
retry_num += 1
|
retry_num += 1
|
||||||
print(f"没有获取到 ASIN 商品,重试{retry_num}/{max_retry_num}")
|
print(f"没有获取到 ASIN 商品,重试{retry_num}/{max_retry_num}")
|
||||||
self.tab.refresh()
|
self.tab.refresh()
|
||||||
@@ -680,19 +680,16 @@ class AmzonePriceMatch(AmamzonBase):
|
|||||||
bottom_price = f"{sum(split_currency_values(bottom_price_text))}"
|
bottom_price = f"{sum(split_currency_values(bottom_price_text))}"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("最低价提取失败",e)
|
print("最低价提取失败",e)
|
||||||
|
|
||||||
current_price_ele = sku_ele.eles('xpath:.//b[text()="价格"]/../..//kat-input',timeout=5)
|
current_price_ele = sku_ele.eles('xpath:.//b[text()="价格"]/../..//kat-input',timeout=5)
|
||||||
if len(current_price_ele) > 0:
|
if len(current_price_ele) > 0:
|
||||||
current_price = current_price_ele[0].attr("value")
|
current_price = current_price_ele[0].attr("value")
|
||||||
print("获取到当前价格为 ->",current_price)
|
print("获取到当前价格为 ->",current_price)
|
||||||
# 如果紫鸟里当前价格低于最低价则删除,否则跳过
|
# 如果紫鸟里当前价格低于最低价则删除,否则跳过
|
||||||
if mode == "status" and miniprice_info.get(asin):
|
# if mode == "status" and miniprice_info.get(asin):
|
||||||
|
if miniprice_info.get(asin):
|
||||||
backend_price = float(miniprice_info.get(asin))
|
backend_price = float(miniprice_info.get(asin))
|
||||||
if float(current_price) <= backend_price:
|
if float(current_price) <= backend_price:
|
||||||
# yield (asin, {
|
|
||||||
# "statu": "删除(当前价格低于最低价)",
|
|
||||||
# "deleteSkipAsin": True,
|
|
||||||
# "removeAsin": asin,
|
|
||||||
# })
|
|
||||||
yield (asin, {
|
yield (asin, {
|
||||||
"statu": "跳过(当前价格低于或等于最低价)",
|
"statu": "跳过(当前价格低于或等于最低价)",
|
||||||
"currentPrice": current_price,
|
"currentPrice": current_price,
|
||||||
@@ -764,6 +761,9 @@ class AmzonePriceMatch(AmamzonBase):
|
|||||||
print(asin,"-->>",f"【逻辑计算后的价格】",adjust_prices)
|
print(asin,"-->>",f"【逻辑计算后的价格】",adjust_prices)
|
||||||
if adjust_prices is not None and adjust_prices != float(current_price):
|
if adjust_prices is not None and adjust_prices != float(current_price):
|
||||||
#修改价格
|
#修改价格
|
||||||
|
print("准备填入的原始值:",adjust_prices)
|
||||||
|
adjust_prices = round(adjust_prices, 2)
|
||||||
|
print("保留两位小数后的::",adjust_prices)
|
||||||
self.tab.actions.click(current_price_ele[0])
|
self.tab.actions.click(current_price_ele[0])
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
current_price_ele[0].input(f"{adjust_prices}", clear=True)
|
current_price_ele[0].input(f"{adjust_prices}", clear=True)
|
||||||
@@ -784,12 +784,12 @@ class AmzonePriceMatch(AmamzonBase):
|
|||||||
"statu" : "改价成功",
|
"statu" : "改价成功",
|
||||||
"currentPrice" : current_price,
|
"currentPrice" : current_price,
|
||||||
"recommendedPrice" : f"{recommendedPrice}",
|
"recommendedPrice" : f"{recommendedPrice}",
|
||||||
"minimumPrice" : bottom_price, #最低价格
|
"minimumPrice" : f"{miniprice_info.get(asin)}" if miniprice_info.get(asin) else "",#bottom_price, #最低价格
|
||||||
"firstPlace": price_1,
|
"firstPlace": price_1,
|
||||||
"secondPlace": price_2,
|
"secondPlace": price_2,
|
||||||
"cartShopName" : cartShopName,
|
"cartShopName" : cartShopName,
|
||||||
"shippingFee" : f"{shipping_fee}",
|
"shippingFee" : f"{shipping_fee}",
|
||||||
"priceChangeStatus" : f"{adjust_prices}",
|
"priceChangePrice" : f"{adjust_prices}",
|
||||||
"priceChangeStatus" : "改价成功",
|
"priceChangeStatus" : "改价成功",
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
@@ -803,12 +803,14 @@ class AmzonePriceMatch(AmamzonBase):
|
|||||||
"statu": "跳过,无需改价",
|
"statu": "跳过,无需改价",
|
||||||
"currentPrice": current_price,
|
"currentPrice": current_price,
|
||||||
"recommendedPrice": f"{recommendedPrice}",
|
"recommendedPrice": f"{recommendedPrice}",
|
||||||
"minimumPrice": bottom_price, # 最低价格
|
# "minimumPrice": bottom_price, # 最低价格
|
||||||
|
"minimumPrice": f"{miniprice_info.get(asin)}" if miniprice_info.get(asin) else "",
|
||||||
"firstPlace": price_1,
|
"firstPlace": price_1,
|
||||||
"secondPlace": price_2,
|
"secondPlace": price_2,
|
||||||
"cartShopName": cartShopName,
|
"cartShopName": cartShopName,
|
||||||
"shippingFee": f"{shipping_fee}",
|
"shippingFee": f"{shipping_fee}",
|
||||||
"priceChangeStatus": "跳过,无需改价",
|
"priceChangeStatus": "跳过,无需改价",
|
||||||
|
"priceChangePrice": f"{adjust_prices}".replace("None",""),
|
||||||
})
|
})
|
||||||
|
|
||||||
already_asin.add(asin)
|
already_asin.add(asin)
|
||||||
@@ -1029,6 +1031,68 @@ class PriceTask:
|
|||||||
return driver
|
return driver
|
||||||
return driver
|
return driver
|
||||||
|
|
||||||
|
def action_init(self,driver,country_name,shop_name,risk_listing_filter):
|
||||||
|
"""切换到指定国际 -> 页面 -》 筛选好"""
|
||||||
|
max_retries = 5
|
||||||
|
switch_success = False
|
||||||
|
switch_success_pg = False
|
||||||
|
search_success = False
|
||||||
|
sku_ls = []
|
||||||
|
for retry in range(max_retries):
|
||||||
|
try:
|
||||||
|
self.log(f"尝试切换到国家 {country_name} (第 {retry + 1}/{max_retries} 次)")
|
||||||
|
if retry > 2:
|
||||||
|
# 刷新不行就重新打开店铺
|
||||||
|
self.log("重试前重新打开店铺...")
|
||||||
|
try:
|
||||||
|
driver.close_store()
|
||||||
|
time.sleep(3)
|
||||||
|
driver.open_shop(shop_name)
|
||||||
|
except Exception as e:
|
||||||
|
self.log(f"关闭重新打开店铺: {str(e)}", "WARNING")
|
||||||
|
# 如果不是第一次尝试,先刷新页面
|
||||||
|
if retry > 0:
|
||||||
|
self.log("重试前刷新页面...")
|
||||||
|
try:
|
||||||
|
driver.tab.refresh()
|
||||||
|
time.sleep(3)
|
||||||
|
except Exception as e:
|
||||||
|
self.log(f"刷新页面失败: {str(e)}", "WARNING")
|
||||||
|
|
||||||
|
switch_success = driver.SwitchingCountries(country_name)
|
||||||
|
if switch_success:
|
||||||
|
self.log(f"成功切换到国家 {country_name}")
|
||||||
|
|
||||||
|
# 切换到库存管理页面
|
||||||
|
driver.SwitchPage()
|
||||||
|
self.log(f"已切换到库存管理页面")
|
||||||
|
time.sleep(3)
|
||||||
|
switch_success_pg = True
|
||||||
|
|
||||||
|
sku_ls = driver.search(filter_type=risk_listing_filter)
|
||||||
|
search_success = True
|
||||||
|
self.log(f"国家 {country_name} 搜索出 {len(sku_ls)} 商品,开始处理...")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
self.log(f"切换到国家 {country_name} 失败", "WARNING")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
import traceback
|
||||||
|
self.log(f"切换国家 {country_name} 异常: {str(e)}", "ERROR")
|
||||||
|
self.log(traceback.format_exc(), "ERROR")
|
||||||
|
|
||||||
|
# 如果还有重试机会,等待后继续
|
||||||
|
if retry < max_retries - 1:
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
# 如果切换失败,直接返回
|
||||||
|
# if not switch_success or not switch_success_pg or not search_success:
|
||||||
|
# error_message = f"切换到国家({switch_success})/库存页面({switch_success_pg})/搜索筛选到指定选项({search_success}) {country_name} 失败,已重试 {max_retries} 次,跳过该国家"
|
||||||
|
# self.log(error_message, "ERROR")
|
||||||
|
# if task_id in runing_task:
|
||||||
|
# runing_task[task_id]["processed_countries"] += 1
|
||||||
|
return switch_success,switch_success_pg,search_success
|
||||||
|
|
||||||
|
|
||||||
def process_shop(self, shop_item: dict, country_codes: list, task_id: int, risk_listing_filter: str,
|
def process_shop(self, shop_item: dict, country_codes: list, task_id: int, risk_listing_filter: str,
|
||||||
user_id=None, stage_index=None, final_stage: bool = True, limit: str = None):
|
user_id=None, stage_index=None, final_stage: bool = True, limit: str = None):
|
||||||
@@ -1149,94 +1213,42 @@ class PriceTask:
|
|||||||
runing_task[task_id]["current_country"] = country_name
|
runing_task[task_id]["current_country"] = country_name
|
||||||
|
|
||||||
# 切换国家,最多重试3次
|
# 切换国家,最多重试3次
|
||||||
max_retries = 3
|
max_retries = 5
|
||||||
switch_success = False
|
|
||||||
|
|
||||||
for retry in range(max_retries):
|
|
||||||
try:
|
|
||||||
self.log(f"尝试切换到国家 {country_name} (第 {retry + 1}/{max_retries} 次)")
|
|
||||||
if retry > 1:
|
|
||||||
# 刷新不行就重新打开店铺
|
|
||||||
self.log("重试前重新打开店铺...")
|
|
||||||
try:
|
|
||||||
driver.close_store()
|
|
||||||
time.sleep(3)
|
|
||||||
driver.open_shop(shop_name)
|
|
||||||
except Exception as e:
|
|
||||||
self.log(f"关闭重新打开店铺: {str(e)}", "WARNING")
|
|
||||||
# 如果不是第一次尝试,先刷新页面
|
|
||||||
if retry > 0:
|
|
||||||
self.log("重试前刷新页面...")
|
|
||||||
try:
|
|
||||||
driver.tab.refresh()
|
|
||||||
time.sleep(3)
|
|
||||||
except Exception as e:
|
|
||||||
self.log(f"刷新页面失败: {str(e)}", "WARNING")
|
|
||||||
|
|
||||||
switch_success = driver.SwitchingCountries(country_name)
|
|
||||||
if switch_success:
|
|
||||||
self.log(f"成功切换到国家 {country_name}")
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
self.log(f"切换到国家 {country_name} 失败", "WARNING")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
import traceback
|
|
||||||
self.log(f"切换国家 {country_name} 异常: {str(e)}", "ERROR")
|
|
||||||
self.log(traceback.format_exc(), "ERROR")
|
|
||||||
|
|
||||||
# 如果还有重试机会,等待后继续
|
|
||||||
if retry < max_retries - 1:
|
|
||||||
time.sleep(2)
|
|
||||||
|
|
||||||
|
switch_success,switch_success_pg,search_success = self.action_init( driver, country_name, shop_name, risk_listing_filter)
|
||||||
# 如果切换失败,直接返回
|
# 如果切换失败,直接返回
|
||||||
if not switch_success:
|
if not switch_success or not switch_success_pg or not search_success:
|
||||||
error_message = f"切换到国家 {country_name} 失败,已重试 {max_retries} 次,跳过该国家"
|
error_message = f"切换到国家({switch_success})/库存页面({switch_success_pg})/搜索筛选到指定选项({search_success}) {country_name} 失败,已重试 {max_retries} 次,跳过该国家"
|
||||||
self.log(error_message, "ERROR")
|
self.log(error_message, "ERROR")
|
||||||
if task_id in runing_task:
|
if task_id in runing_task:
|
||||||
runing_task[task_id]["processed_countries"] += 1
|
runing_task[task_id]["processed_countries"] += 1
|
||||||
return
|
return
|
||||||
|
|
||||||
# 切换到库存管理页面
|
|
||||||
for retry in range(max_retries):
|
|
||||||
try:
|
|
||||||
driver.SwitchPage()
|
|
||||||
self.log(f"已切换到库存管理页面")
|
|
||||||
except Exception as e:
|
|
||||||
import traceback
|
|
||||||
self.log(f"切换页面失败: {str(e)}", "ERROR")
|
|
||||||
self.log(traceback.format_exc(), "ERROR")
|
|
||||||
|
|
||||||
if retry >= max_retries-1:
|
|
||||||
if task_id in runing_task:
|
|
||||||
runing_task[task_id]["processed_countries"] += 1
|
|
||||||
self.log(f"切换页面失败重试退出", "ERROR")
|
|
||||||
return
|
|
||||||
|
|
||||||
# 搜索需要审批的商品,最多重试3次
|
# 搜索需要审批的商品,最多重试3次
|
||||||
sku_ls = []
|
# sku_ls = []
|
||||||
for retry in range(max_retries):
|
# for retry in range(max_retries):
|
||||||
try:
|
# try:
|
||||||
self.log(f"尝试搜索匹配操作商品 (第 {retry + 1}/{max_retries} 次)")
|
# self.log(f"尝试搜索匹配操作商品 (第 {retry + 1}/{max_retries} 次)")
|
||||||
sku_ls = driver.search(filter_type=risk_listing_filter)
|
# sku_ls = driver.search(filter_type=risk_listing_filter)
|
||||||
break
|
# break
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
self.log(f"搜索商品异常: {str(e)}", "ERROR")
|
# self.log(f"搜索商品异常: {str(e)}", "ERROR")
|
||||||
if retry < max_retries - 1:
|
# if retry < max_retries - 1:
|
||||||
try:
|
# try:
|
||||||
driver.tab.refresh()
|
# driver.tab.refresh()
|
||||||
time.sleep(3)
|
# driver.tab.wait.doc_loaded()
|
||||||
except Exception as refresh_error:
|
# time.sleep(3)
|
||||||
self.log(f"刷新页面失败: {str(refresh_error)}", "WARNING")
|
# except Exception as refresh_error:
|
||||||
|
# self.log(f"刷新页面失败: {str(refresh_error)}", "WARNING")
|
||||||
|
#
|
||||||
|
# # 如果没有需要审批的商品,直接返回
|
||||||
|
# if len(sku_ls) == 0:
|
||||||
|
# self.log(f"国家 {country_name} 没有搜索出的商品")
|
||||||
|
# if task_id in runing_task:
|
||||||
|
# runing_task[task_id]["processed_countries"] += 1
|
||||||
|
# return
|
||||||
|
|
||||||
# 如果没有需要审批的商品,直接返回
|
self.log(f"国家 {country_name} ,开始处理...")
|
||||||
if len(sku_ls) == 0:
|
|
||||||
self.log(f"国家 {country_name} 没有搜索出的商品")
|
|
||||||
if task_id in runing_task:
|
|
||||||
runing_task[task_id]["processed_countries"] += 1
|
|
||||||
return
|
|
||||||
|
|
||||||
self.log(f"国家 {country_name} 搜索出 {len(sku_ls)} 商品,开始处理...")
|
|
||||||
|
|
||||||
# 处理所有需要审批的商品(通过yield获取结果)
|
# 处理所有需要审批的商品(通过yield获取结果)
|
||||||
|
|
||||||
@@ -1350,13 +1362,14 @@ class PriceTask:
|
|||||||
"firstPlace": status.get("firstPlace") if status.get("firstPlace") else "",
|
"firstPlace": status.get("firstPlace") if status.get("firstPlace") else "",
|
||||||
"secondPlace": status.get("secondPlace") if status.get("secondPlace") else "",
|
"secondPlace": status.get("secondPlace") if status.get("secondPlace") else "",
|
||||||
"cartShopName": status.get("cartShopName") if status.get("cartShopName") else "",
|
"cartShopName": status.get("cartShopName") if status.get("cartShopName") else "",
|
||||||
"priceChangeStatus": "UPDATED",
|
# "priceChangeStatus": "UPDATED",
|
||||||
"deleteSkipAsin": status.get("deleteSkipAsin",False),
|
"deleteSkipAsin": status.get("deleteSkipAsin",False),
|
||||||
"removeAsin": status.get("removeAsin") if status.get("removeAsin") else "",
|
"removeAsin": status.get("removeAsin") if status.get("removeAsin") else "",
|
||||||
"modifyCount": "1",
|
"modifyCount": "1",
|
||||||
"shippingFee" : status.get("shippingFee") if status.get("shippingFee") else "",
|
"shippingFee" : status.get("shippingFee") if status.get("shippingFee") else "",
|
||||||
"status": status.get("statu"),
|
"status": status.get("statu"),
|
||||||
"priceChangeStatus" : status.get("priceChangeStatus") if status.get("priceChangeStatus") else "",
|
"priceChangeStatus" : status.get("priceChangeStatus") if status.get("priceChangeStatus") else "",
|
||||||
|
"priceChangePrice" : status.get("priceChangePrice") if status.get("priceChangePrice") else "",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -1405,20 +1418,20 @@ class PriceTask:
|
|||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# 使用示例
|
# 使用示例
|
||||||
# user_info = {
|
# user_info = {
|
||||||
# "company": "rongchuang123",
|
# "company": "尾号5578的公司115",
|
||||||
# "username": "自动化_Robot",
|
# "username": "自动化_Robot",
|
||||||
# "password": "#20zsg25"
|
# "password": "#20zsg25"
|
||||||
# }
|
# }
|
||||||
# shop_name = "郭亚芳"
|
# shop_name = "刘建煌"
|
||||||
# country = "德国"
|
# country = "法国"
|
||||||
# kill_process('v6')
|
# kill_process('v6')
|
||||||
# driver = AmzonePriceMatch(user_info)
|
# driver = AmzonePriceMatch(user_info)
|
||||||
# browser = driver.open_shop(shop_name)
|
# browser = driver.open_shop(shop_name)
|
||||||
# sw_suc = driver.SwitchingCountries(country)
|
# sw_suc = driver.SwitchingCountries(country)
|
||||||
# driver.SwitchPage()
|
# driver.SwitchPage()
|
||||||
# risk_listing_filter = "Active"
|
# risk_listing_filter = "Active"
|
||||||
# _shopMallName = "yafang123"
|
# _shopMallName = "Jianhuang 888"
|
||||||
# ap_asin ="B0BTHBJDKG"
|
# ap_asin ="B0F25Y52PH"
|
||||||
# skip_asin = []
|
# skip_asin = []
|
||||||
# for _ in range(3):
|
# for _ in range(3):
|
||||||
# try:
|
# try:
|
||||||
@@ -1436,14 +1449,19 @@ if __name__ == '__main__':
|
|||||||
# print(f"ASIN {asin} 的处理结果: {status}")
|
# print(f"ASIN {asin} 的处理结果: {status}")
|
||||||
# print("已完成操作")
|
# print("已完成操作")
|
||||||
|
|
||||||
front_end_data = {'top_sellers': [{'rank': 1, 'price': '50.24', 'stock': '26', 'shop_name': 'yafang123'}, {'rank': 2, 'price': '44.35', 'stock': '100', 'shop_name': 'QinPimy'}], 'cart_seller': 'Amazon US', 'timestamp': '2026-04-27 16:17:42'}
|
front_end_data = {'top_sellers': [{'rank': 1, 'price': '52.51', 'stock': '100', 'shop_name': 'Amazon US'}, {'rank': 2, 'price': '62.58', 'stock': '30', 'shop_name': 'Amazon US'}], 'cart_seller': 'Jianhuang 888', 'timestamp': '2026-04-30 09:52:49'}
|
||||||
|
|
||||||
current_Price = 44.35
|
current_Price = 52.51
|
||||||
current_shop_name = "yafang123"
|
current_shop_name = "Jianhuang 888"
|
||||||
recommended_price = 44.35
|
recommended_price = 52.51
|
||||||
recommended_shipping =0.0
|
recommended_shipping =0.0
|
||||||
res = calculate_target_price(
|
res = calculate_target_price(
|
||||||
front_end_data, current_Price, current_shop_name,
|
front_end_data, current_Price, current_shop_name,
|
||||||
recommended_price, recommended_shipping
|
recommended_price, recommended_shipping
|
||||||
)
|
)
|
||||||
print(res)
|
print(res)
|
||||||
|
|
||||||
|
|
||||||
|
# task_data = {'type': 'price-track-run', 'ts': 1777388166302, 'data': {'task_id': 4892, 'result_id': 6685, 'shop_name': '魏振峰', 'shop_id': '27543917795757', 'platform': '亚马逊', 'company_name': 'rongchuang123', 'shop_mall_name': 'WEIZHENFENG168', 'matched': True, 'match_status': 'MATCHED', 'match_message': None, 'success': False, 'error': None, 'output_filename': None, 'download_url': None, 'task_status': 'RUNNING', 'loop_run_id': 168, 'round_index': 1, 'country_codes': ['DE', 'UK', 'FR', 'IT', 'ES'], 'mode': 'asin', 'skip_asins': {}, 'skip_asins_by_country': {}, 'skip_asin_details_by_country': {}, 'minimum_price_by_country_and_asin': {'DE': {'B0CFY5M3XJ': '38', 'B0DSJGJBWV': '9'}, 'UK': {'B0G2LPSGP5': '30', 'B0G1LY2K8L': '10'}}, 'skip_asin_delete_policy': {'enabled': False, 'mode': 'NONE', 'deleteWhenPriceBelowMinimum': False, 'compareField': 'price', 'thresholdField': 'minimumPrice', 'target': 'skip_asin', 'source': 'frontend-price-track'}, 'delete_skip_asin_when_price_below_minimum': False, 'deleteSkipAsinWhenPriceBelowMinimum': False, 'asin_rows_by_country': {'DE': [{'shopMallName': '', 'asin': 'B0CFY5M3XJ', 'price': '', 'recommendedPrice': '', 'minimumPrice': '38', 'firstPlace': '', 'secondPlace': '', 'cartShopName': '', 'priceChangeStatus': '', 'modifyCount': '', 'status': ''}, {'shopMallName': '', 'asin': 'B0DSJGJBWV', 'price': '', 'recommendedPrice': '', 'minimumPrice': '9', 'firstPlace': '', 'secondPlace': '', 'cartShopName': '', 'priceChangeStatus': '', 'modifyCount': '', 'status': ''}], 'UK': [{'shopMallName': '', 'asin': 'B0G2LPSGP5', 'price': '', 'recommendedPrice': '', 'minimumPrice': '30', 'firstPlace': '', 'secondPlace': '', 'cartShopName': '', 'priceChangeStatus': '', 'modifyCount': '', 'status': ''}, {'shopMallName': '', 'asin': 'B0G1LY2K8L', 'price': '', 'recommendedPrice': '', 'minimumPrice': '10', 'firstPlace': '', 'secondPlace': '', 'cartShopName': '', 'priceChangeStatus': '', 'modifyCount': '', 'status': ''}]}, 'taskId': 4892, 'resultId': 6685, 'shopName': '魏振峰', 'shopId': '27543917795757', 'platformName': '亚马逊', 'companyName': 'rongchuang123', 'shopMallName': 'WEIZHENFENG168', 'matchStatus': 'MATCHED', 'matchMessage': None, 'outputFilename': None, 'downloadUrl': None, 'taskStatus': 'RUNNING', 'loopRunId': 168, 'roundIndex': 1}}
|
||||||
|
# price_cls = PriceTask(user_info)
|
||||||
|
# price_cls.process_task(task_data)
|
||||||
@@ -438,7 +438,7 @@ def main():
|
|||||||
window.expose(api.close, api.minimize, api.maximize, api.toggle_maximize, generate_images, api.save_image, api.save_image_to_folder, api.select_folder, api.select_brand_xlsx_files, api.select_brand_folder,
|
window.expose(api.close, api.minimize, api.maximize, api.toggle_maximize, generate_images, api.save_image, api.save_image_to_folder, api.select_folder, api.select_brand_xlsx_files, api.select_brand_folder,
|
||||||
api.save_file_from_url, api.save_template_xlsx,api.save_template_zip,api.upload_file_to_java,api.open_external_url,api.enqueue_json,api.get_detail_del,api.save_file_from_url_new)
|
api.save_file_from_url, api.save_template_xlsx,api.save_template_zip,api.upload_file_to_java,api.open_external_url,api.enqueue_json,api.get_detail_del,api.save_file_from_url_new)
|
||||||
webview.start(
|
webview.start(
|
||||||
debug=False,
|
debug=True,
|
||||||
storage_path=cache_path,
|
storage_path=cache_path,
|
||||||
private_mode=False
|
private_mode=False
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user