Files
crawler-plugin/app/amazon/price_match.py
铭坤 b0514c3e9a modified: amazon/price_match.py
modified:   config.py
2026-05-07 11:14:15 +08:00

1300 lines
97 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import json
import time
import re
import traceback
from datetime import datetime
import requests
from amazon.amazon_base import AmamzonBase, kill_process,TaskBase
from amazon.tool import show_notification,get_shop_info,remove_special_characters,split_currency_values
from config import runing_task, runing_shop,DELETE_BRAND_API_BASE
class RepricingLogic:
@staticmethod
def situation_1_general_decrease(my_price, rank1_price, is_first_time=False):
"""
情况1常规递减跟价 (最左侧独立长图块)
"""
if is_first_time:
return rank1_price - 0.3
# 这里的 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:
return rank1_price - (diff + 0.5)
elif diff <= 0.8:
return rank1_price - (diff + 0.7)
elif diff <= 10.5:
# 0.8 到 10.5 之间全部是在减1
return rank1_price - (diff + 1.0)
else:
return rank1_price - 10.5 # 相差10.5以上,跳过
@staticmethod
def situation_2_own_buybox(my_price, rank2_price):
"""
情况2已经是自己购物车
"""
diff = rank2_price - my_price
if diff >= 2.0:
return rank2_price - 0.3
if (20 <= my_price < 30 and diff >= 4) or \
(30 <= my_price < 60 and diff >= 8) or \
(60 <= my_price <= 150 and diff >= 15):
return rank2_price - 0.3
return my_price
@staticmethod
def situation_3_not_own_buybox(my_price, rank1_price):
"""
情况3不是自己购物车 (除Amazon US外)
"""
diff = rank1_price - my_price
if diff <= 0:
return rank1_price - 0.3
# 逻辑更清晰的写法:第一名价格 - (差价 + 对应阶梯值)
if diff <= 0.3:
return rank1_price - (diff + 0.5)
elif diff <= 0.8:
return rank1_price - (diff + 0.7)
elif diff <= 2.5:
return rank1_price - (diff + 1.0)
else:
return None # 2.5-3.5以上跳过
@staticmethod
def situation_4_encounter_amz_us_1st(my_price, amz_us_price):
"""
情况4遇到第一名是 Amazon US 卖家
"""
diff = amz_us_price - my_price
if diff <= 0:
return amz_us_price - 3
# 逻辑更清晰的写法:第一名价格 - (差价 + 对应阶梯值)
if diff <= 3:
return amz_us_price - (diff + 2)
elif diff <= 6:
return amz_us_price - (diff + 3)
else:
return None # 超过6直接跳过
@staticmethod
def situation_5_im_1st_amz_us_2nd(my_price, amz_us_price):
"""
情况5自己是第一名第二名是 Amazon US 卖家
"""
diff = amz_us_price - my_price
if diff <= 7:
return None # 相差7以内跳过 (保持原价)
else:
return amz_us_price - 5
def calculate_target_price(
front_end_data,current_Price,current_shop_name,
recommended_price,recommended_shipping
):
"""
recommended_price 推荐价格
recommended_shipping 推荐运费
"""
# --- Step 1: 获取基础数据 ---
cart_seller = front_end_data.get("cart_seller")
my_price = current_Price # 我当前的售价
is_my_buybox = True if cart_seller == current_shop_name else False # 当前是否自己占据购物车
# --- Step 2: 紫鸟后台特殊判定 (最高优先级) ---
if recommended_shipping > 0:
price_1 = float(front_end_data.get("top_sellers")[0].get("price")) # 实际第一名价格
if is_my_buybox:
price_col = price_1
else:
price_col = recommended_price + recommended_shipping
print(f"【紫鸟后台价格】{is_my_buybox} 推荐价格: {recommended_price},推荐运费: {recommended_shipping},总和: {price_col}")
return RepricingLogic.situation_1_general_decrease(my_price,price_col,is_my_buybox)
# # 第一名是自己, 第二名 Amazon US 卖家 的情况
shop_name_1 = front_end_data.get("top_sellers")[0].get("shop_name")
shop_name_2 = front_end_data.get("top_sellers")[1].get("shop_name") if len(front_end_data.get("top_sellers")) >=2 else ""
if shop_name_1 == current_shop_name and "Amazon" in shop_name_2:
price_2 = float(front_end_data.get("top_sellers")[1].get("price")) # 实际第二名价格
return RepricingLogic.situation_5_im_1st_amz_us_2nd(my_price,price_2)
# --- Step 3: 常规核心分流逻辑 (如果没有紫鸟后台数据) ---
# 分支 A第一名是 Amazon US 卖家 (特殊强敌优先)
price_1 = float(front_end_data.get("top_sellers")[0].get("price")) # 实际第一名价格
if "Amazon" in shop_name_1:
# 增补第6种情况如果是自己购物车 且 第一名是Amazon 且Amazon的价格高于自己的价格 按照这个 :如果低于自己的价格 就跳过,
if is_my_buybox:
if price_1 > my_price:
diff = price_1 - my_price
if diff <= 7 :
return None
else:
return price_1 - 5
else:
return None
else:
return RepricingLogic.situation_4_encounter_amz_us_1st(my_price,price_1)
# 分支 B不是 Amazon US且目前是自己的购物车
elif is_my_buybox:
if len(front_end_data.get("top_sellers")) < 2:
return None
price_2 = float(front_end_data.get("top_sellers")[1].get("price")) # 实际第二名价格
return RepricingLogic.situation_2_own_buybox(my_price,price_2)
# 分支 C不是 Amazon US也不是自己的购物车
else:
# 正常情况下的普通跟价,调用阶梯逻辑
return RepricingLogic.situation_3_not_own_buybox(my_price, price_1)
class ChromeAmzone:
mark_name = "亚马逊详情采集"
country_info = {
"英国": {
"url": "https://www.amazon.co.uk/dp/B0CJ8SNXXV",
"zip_code": "SW1A 1AA",
"mark": "SW1A 1"
},
"德国": {
"url": "https://www.amazon.de/dp/B0CC8CW9G2?th=1",
"zip_code": "10115"
},
"法国": {
"url": "https://www.amazon.fr/dp/B0FRG1MJ8H?th=1",
"zip_code": "75001"
},
"西班牙": {
"url": "https://www.amazon.es/dp/B08ZXVNYNN",
"zip_code": "28001"
},
"意大利": {
"url": "https://www.amazon.it/dp/B0D1P17T2Q",
"zip_code": "20121"
}
}
def __init__(self,tab):
self.tab = tab
def close_init_popup(self):
"""
关闭所有的初始化弹窗
"""
self.tab.wait.doc_loaded(timeout=60,raise_err=True)
footbar = self.tab.eles('xpath://footer[@class="el-dialog__footer"]',timeout=5)
if len(footbar) > 0:
do_not_remind = footbar[0].eles('xpath:.//input[@class="el-checkbox__original"]')
if len(do_not_remind) > 0:
do_not_remind[0].check()
resume_immediately = footbar[0].eles('xpath:.//button')
if len(resume_immediately) > 0:
resume_immediately[0].click()
self.tab.wait.doc_loaded(timeout=60,raise_err=True)
accept_btn = self.tab.eles('xpath://input[@id="sp-cc-accept"]',timeout=10)
if len(accept_btn) > 0:
accept_btn[0].click()
def _set_zip_code(self, zip_code, mark=None):
"""
设置邮编
Args:
zip_code: 目标邮编
"""
try:
# 检查当前邮编
zip_display = self.tab.ele('xpath://div[@id="glow-ingress-block"]', timeout=10)
if zip_display:
current_text = zip_display.text
# print(f"当前地址信息: {current_text}")
# 先检查标识
if mark is not None and mark in current_text:
print(f"邮编检测到标识: {mark},无需修改")
return True
# 检查是否已经包含目标邮编
if zip_code in current_text:
print(f"邮编已经设置为: {zip_code},无需修改")
return True
# 需要设置邮编
print(f"正在设置邮编为: {zip_code}")
# 点击地址选择按钮
location_link = self.tab.ele('xpath://a[@id="nav-global-location-popover-link"]', timeout=10)
if not location_link:
print("找不到地址设置按钮")
return False
location_link.click()
time.sleep(1)
# 等待邮编输入框出现
zip_input = self.tab.ele('xpath://input[@id="GLUXZipUpdateInput"]', timeout=10)
if not zip_input:
print("找不到邮编输入框")
return False
# 输入邮编
zip_input.input(zip_code, clear=True)
time.sleep(0.5)
# 点击提交按钮
submit_btn = self.tab.ele('xpath://input[@aria-labelledby="GLUXZipUpdate-announce"]', timeout=10)
if not submit_btn:
print("找不到提交按钮")
return False
submit_btn.click()
continue_btn = self.tab.eles('xpath://div[@class="a-popover-footer"]//input[@id="GLUXConfirmClose"]',
timeout=10)
if len(continue_btn) > 0:
continue_btn[0].click()
# 等待提交按钮消失(表示请求已发送)
print("等待邮编更新...")
time.sleep(2)
# 等待页面加载完成
self.tab.wait.doc_loaded(timeout=30, raise_err=False)
time.sleep(2)
# 验证邮编是否设置成功
zip_display_after = self.tab.ele('xpath://div[@id="glow-ingress-block"]', timeout=10)
if zip_display_after:
updated_text = zip_display_after.text
# print(f"更新后的地址信息: {updated_text}")
if zip_code in updated_text:
print(f"邮编设置成功: {zip_code}")
return True
else:
# print(f"邮编设置可能失败,当前显示: {updated_text}")
return False
return True
except Exception as e:
print(f"设置邮编时出错: {traceback.format_exc()}")
return False
def run(self,country):
"""
运行亚马逊详情采集任务
Args:
country: 国家名称(如:英国、德国、法国、西班牙、意大利)
asin: 亚马逊商品ASIN码
Returns:
dict: 包含采集到的数据
"""
try:
if country not in self.country_info:
error_msg = f"不支持的国家: {country},支持的国家有: {list(self.country_info.keys())}"
print(error_msg)
show_notification(error_msg, "error")
return None
# 获取国家配置
country_config = self.country_info[country]
zip_code = country_config["zip_code"]
mark = country_config.get("mark")
self._set_zip_code(zip_code,mark)
self.tab.wait.doc_loaded(timeout=5,raise_err=False)
self.tab.wait.doc_loaded(timeout=30, raise_err=False)
self.close_init_popup()
self.tab.wait.doc_loaded(timeout=5,raise_err=False)
# 3. 抓取数据
print("===================正在抓取商品数据...====================")
data = self._scrape_data()
data['timestamp'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(f"数据抓取完成: {json.dumps(data)}")
print("======================================================")
return data
except Exception as e:
error_msg = f"运行出错: {traceback.format_exc()}"
print(error_msg)
show_notification(f"采集失败: {str(e)}", "error")
return None
def _scrape_data(self):
"""
抓取商品数据
Returns:
dict: 抓取到的数据
"""
data = {
'top_sellers': [], # 前两名卖家信息
'cart_seller': None # 购物车所属卖家
}
try:
# 等待页面加载
time.sleep(3)
h4 = self.tab.eles('xpath://div[@id="rightCol"]//h4[text()="卖家精灵-库存监控"]',timeout=10)
print("【家精灵-库存监控】数量",len(h4))
# 1. 获取前两名卖家的价格和库存(来自 sellersprite 插件)
print("正在抓取卖家排名数据...")
surplus_tables = self.tab.eles(
'xpath://div[@id="sellersprite-extension-Inventory-surplus-count"]//div[@class="surplus-table"]',
timeout=10
)
if surplus_tables:
print(f"找到 {len(surplus_tables)} 个卖家数据")
# 只获取前两个
for idx, table in enumerate(surplus_tables[:2]):
try:
# 提取价格和库存信息
# 注意需要根据实际的HTML结构调整选择器
# print(f"第{idx+1}名卖家数据: {text_content}")
seller_info = {
'rank': idx + 1,
}
# 尝试提取更结构化的数据
# 这里需要根据实际HTML结构来解析
# 可能需要查找子元素
try:
# 示例:查找价格和库存的具体子节点
price_ele = table.ele('xpath:.//span[contains(@class,"price")]', timeout=2)
stock_ele = table.ele('xpath:.//span[@class="surplus-count-num"]', timeout=2)
shop_name_ele = table.ele('xpath:.//div[@class="surplus-table-item"][2]//a', timeout=2)
seller_info['price'] = remove_special_characters(price_ele.text.strip())
seller_info['stock'] = remove_special_characters(stock_ele.text.strip())
seller_info['shop_name'] = shop_name_ele.text.strip()
except Exception as e:
print("解析出错",e)
pass
data['top_sellers'].append(seller_info)
except Exception as e:
print(f"解析第{idx+1}名卖家数据失败: {str(e)}")
else:
print("未找到 sellersprite 插件数据,可能插件未启用")
show_notification("未找到 sellersprite 插件数据,可能插件未启用")
# 2. 获取购物车所属卖家
print("正在抓取购物车卖家信息...")
cart_seller = self.tab.ele(
'xpath://div[@data-csa-c-content-id="desktop-merchant-info"]//a[@id="sellerProfileTriggerId"]',
timeout=10
)
if cart_seller:
seller_name = cart_seller.text.strip()
print(f"购物车所属卖家: {seller_name}")
data['cart_seller'] = seller_name
else:
print("未找到购物车卖家信息")
# 尝试其他可能的选择器
try:
alt_seller = self.tab.ele('xpath://a[@id="sellerProfileTriggerId"]', timeout=5)
if alt_seller:
data['cart_seller'] = alt_seller.text.strip()
print(f"购物车所属卖家(备用方式): {data['cart_seller']}")
except:
pass
return data
except Exception as e:
print(f"抓取数据时出错: {traceback.format_exc()}")
return data
def close(self):
"""关闭浏览器"""
try:
self.tab.close()
except Exception as e:
print(f"关闭标签页时出错: {str(e)}")
class AmzonePriceMatch(AmamzonBase):
mark_name = "跟价"
def __init__(self, user_info: dict, socket_port: int = 19890):
super().__init__(user_info,socket_port)
self.already_asin = set()
def reset_already_asin(self):
self.already_asin = set()
self.log("already_asin 已重置")
def search_asin(self, asin):
search_region = self.tab.ele('xpath://div[@id="searchBoxContainer"]//kat-input-group')
search_region.wait.displayed(raise_err=False)
time.sleep(0.6)
search_input = self.tab.ele("xpath://kat-input[contains(@class,'SearchBox-module__searchInput')]").sr(
'xpath://span[@class="container"]//input[@part="input"]')
search_input.input(asin,clear=True)
sku_ls = []
for _ in range(3):
search_btn = self.tab.ele("xpath://kat-icon[@name='search']")
search_btn.click()
load_ele = self.tab.ele("xpath://div[contains(@class,'Loader-module__loader')]")
# load_ele.wait.hidden(timeout=3, raise_err=False)
load_ele.wait.deleted(timeout=3, raise_err=False)
time.sleep(0.5)
sku_ls = self.tab.eles("xpath://div[@data-sku]",timeout=3)
if len(sku_ls) > 0:
break
return sku_ls
def search_asin_action(self,asin:str):
load_ele = self.tab.eles("xpath://div[contains(@class,'Loader-module__loader')]", timeout=5)
if len(load_ele) > 0:
load_ele[0].wait.deleted(timeout=3, raise_err=False)
time.sleep(0.5)
sku_ls = self.search_asin(asin=asin)
print(f"{self.mark_name}{asin} 搜索到 {len(sku_ls)} 个SKU")
def clear_tab(self):
all_tab = self.browser.get_tabs()
close_tab = []
for tab in all_tab:
tab_id = tab if isinstance(tab,str) else tab.tab_id
if self.tab.tab_id == tab_id:
continue
close_tab.append(tab)
print("需要关闭的标签页",close_tab)
print("当前操作的tab_id",self.tab.tab_id)
self.browser.close_tabs(close_tab)
def run_page_action(self,current_shop_name:str,mode:str,
appoint_asin:str=None,skip_asin:list=[],miniprice_info:dict={}):
self.log(f"==================={self.mark_name}=======================")
self.log("开始执行...")
num = 0
retry_num = 0
already_asin = set()
get_page_faild = 0
#获取当前国家
current_country_ele = self.tab.ele('xpath://div[@class="dropdown-account-switcher-header-label"]/span[last()]',
timeout=20)
current_country = current_country_ele.text.strip()
max_retry_num = 5
while retry_num < max_retry_num: # 最多重试3次
try:
if appoint_asin is not None:
self.log(f"指定asin操作,{appoint_asin}")
self.search_asin_action(asin=appoint_asin)
load_ele = self.tab.eles("xpath://div[contains(@class,'Loader-module__loader')]", timeout=5)
if len(load_ele) > 0:
load_ele[0].wait.deleted(timeout=3, raise_err=False)
time.sleep(0.5)
# 获取当前页码
try:
page_pamel = self.tab.eles('xpath://kat-pagination', timeout=5)
if len(page_pamel) > 0:
current_page = page_pamel[0].sr('xpath:.//ul[@class="pages"]//li[@aria-current="true"]').text
#测试=====
# if int(current_page) > 1:
# break
# 测试===========
# yield (None,{"page":int(current_page.strip())})
# 总页数
total_page = page_pamel[0].sr.eles(
'xpath:.//ul[@class="pages"]//span[@class="page__inner"][last()]')
if len(total_page) > 0:
total_page = total_page[-1].text
else:
total_page = 0
self.log(f"{self.mark_name}】当前页码: {current_page} / 总页数: {total_page}")
get_page_faild = 0
except Exception as e:
self.log(f"获取页码失败,{e}")
get_page_faild += 1
if get_page_faild > 2:
show_notification(f"{self.mark_name}】获取页码失败超3次停止任务")
break
# 保存当前URL用于失败重试时访问
try:
self.url = self.tab.url
self.log(f"获取当前的链接:{self.url}")
except Exception as e:
self.url = None
self.log(f"获取当前的链接失败:{e}")
sku_ls = self.tab.eles("xpath://div[@data-sku]", timeout=10)
self.log(f"{self.mark_name}】获取到 {len(sku_ls)}")
if len(sku_ls) == 0:
if mode == "asin":
self.log(f"asin 模式查询不到,{appoint_asin}")
yield (appoint_asin, {
"statu": "查询不到"
})
break
retry_num += 1
self.log(f"没有获取到 ASIN 商品,重试{retry_num}/{max_retry_num}")
self.tab.refresh()
self.tab.wait.doc_loaded(raise_err=False, timeout=120)
if retry_num == max_retry_num:
raise RuntimeError(f"与页面的连接已断开,没有获取到 ASIN 商品,重试{retry_num}/{max_retry_num}")
continue
# for sku_ele in sku_ls[0:2]:
for sku_ele in sku_ls:
asin = sku_ele.ele(
'xpath:.//div[contains(@class,"JanusSplitBox-module__container")]//div[contains(@class,"JanusSplitBox-module__panel--") and contains(string(.),"ASIN")]/..//div[last()]',
timeout=3).text
self.log(f"{self.mark_name}】ASIN {asin} 找到....")
try:
# if asin in already_asin:
# print(f"【{self.mark_name}】{asin} 已经处理过了,跳过")
# continue
if asin in skip_asin:
yield (asin, {
"statu": "跳过,需要跳过的ASIN"
})
continue
bottom_price_ele = sku_ele.eles('xpath:.//div[@data-test-id="LowestPrice"]/div[2]',timeout=5)
bottom_price = "" #初始化为空
if len(bottom_price_ele) > 0:
try:
bottom_price_text = bottom_price_ele[0].text
# print("最低价格->>",bottom_price_text)
bottom_price = f"{sum(split_currency_values(bottom_price_text))}"
except Exception as e:
self.log(f"最低价提取失败,{e}")
current_price_ele = sku_ele.eles('xpath:.//b[text()="价格"]/../..//kat-input',timeout=5)
if len(current_price_ele) > 0:
current_price = current_price_ele[0].attr("value")
self.log(f"获取到当前价格为 ->{current_price}")
# 如果紫鸟里当前价格低于最低价则删除,否则跳过
# if mode == "status" and miniprice_info.get(asin):
if miniprice_info.get(asin):
backend_price = float(miniprice_info.get(asin))
if float(current_price) <= backend_price:
yield (asin, {
"statu": "跳过(当前价格低于或等于最低价)",
"currentPrice": current_price,
"minimumPrice": backend_price, # 最低价格
})
continue
else:
self.log(f"没有获取到当前价格")
yield (asin, {
"statu": "失败(没有获取到当前的价格)"
})
continue
self.clear_tab()
detail_url_ele = sku_ele.ele('xpath:.//div[contains(@class,"ProductDetails-module__titleContainer")]//a')
# detail_url_ele.click()
detail_url = detail_url_ele.attr("href")
self.log(f"详情链接,{detail_url}")
# time.sleep(1)
for _ in range(10):
try:
new_tab = self.browser.new_tab(url=detail_url)
print("获取新标签页成功",new_tab)
time.sleep(1)
break
except Exception as e:
time.sleep(1)
pass
chrome = ChromeAmzone(tab=new_tab)
front_end_data = chrome.run(country=current_country)
chrome.close()
self.clear_tab()
self.log(f"亚马逊前台抓取到数据,{front_end_data}")
if front_end_data is None or len(front_end_data.get("top_sellers")) == 0:
yield (asin, {
"statu": "失败(第一名获取失败,请检查卖家精灵是否启用)",
"currentPrice": current_price,
})
continue
cart_seller = front_end_data.get("cart_seller")
if cart_seller == current_shop_name and len(front_end_data.get("top_sellers"))< 2:
yield (asin, {
"statu": "跳过(自己的购物车,只有第一名)",
"currentPrice": current_price,
})
continue
recommend_price_ele= sku_ele.eles('xpath:.//div[@data-test-id="FeaturedOfferPrice"]/div[2]',timeout=5)
if len(recommend_price_ele) > 0:
try:
price_text = recommend_price_ele[0].text
# print("推荐价格 ->>",price_text)
recommend_price,shipping_fee = split_currency_values(price_text)
except Exception as e:
print("推荐价格和运费提取失败 ->>",e)
recommend_price, shipping_fee = 0, 0
else:
print(f"{self.mark_name} 没有查找有推荐价格和运费")
recommend_price,shipping_fee = 0,0
adjust_prices = calculate_target_price(
front_end_data, float(current_price), current_shop_name,
recommend_price, shipping_fee
)
# adjust_prices = 236.56
self.log(f"{asin}【逻辑计算后的价格】{adjust_prices}")
if adjust_prices is not None and adjust_prices != float(current_price):
#修改价格
self.log(f"准备填入的原始值:{adjust_prices}")
adjust_prices = round(adjust_prices, 2)
self.log(f"保留两位小数后的::{adjust_prices}")
self.tab.actions.click(current_price_ele[0])
time.sleep(1)
current_price_ele[0].input(f"{adjust_prices}", clear=True)
time.sleep(1)
# current_price_ele[0].sr('xpath:.//inpu[@part="input"]').input(f"{adjust_prices}",clear=True)
out_focus = sku_ele.ele('xpath:.//b[text()="价格"]/../..//kat-label',timeout=5)
out_focus.click()
time.sleep(1)
save_all_btn = self.tab.ele('xpath://kat-button[@label="保存所有"]', timeout=10)
save_all_btn.wait.displayed(timeout=10, raise_err=False)
save_all_btn.click()
save_all_btn.wait.deleted(timeout=10, raise_err=False)
recommendedPrice = recommend_price + shipping_fee
price_1 = float(front_end_data.get("top_sellers")[0].get("price")) if len(front_end_data.get("top_sellers")) >= 1 else "" # 实际第一名价格
price_2 = float(front_end_data.get("top_sellers")[1].get("price")) if len(front_end_data.get("top_sellers")) >= 2 else "" # 实际第二名价格
cartShopName = front_end_data.get("cart_seller")
yield (asin,{
"statu" : "改价成功",
"currentPrice" : current_price,
"recommendedPrice" : f"{recommendedPrice}",
"minimumPrice" : f"{miniprice_info.get(asin)}" if miniprice_info.get(asin) else "",#bottom_price, #最低价格
"firstPlace": price_1,
"secondPlace": price_2,
"cartShopName" : cartShopName,
"shippingFee" : f"{shipping_fee}",
"priceChangePrice" : f"{adjust_prices}",
"priceChangeStatus" : "改价成功",
})
else:
recommendedPrice = recommend_price + shipping_fee
price_1 = float(front_end_data.get("top_sellers")[0].get("price")) if len(
front_end_data.get("top_sellers")) >= 2 else "" # 实际第一名价格
price_2 = float(front_end_data.get("top_sellers")[1].get("price")) if len(
front_end_data.get("top_sellers")) >= 2 else "" # 实际第二名价格
cartShopName = front_end_data.get("cart_seller")
yield (asin, {
"statu": "跳过,无需改价",
"currentPrice": current_price,
"recommendedPrice": f"{recommendedPrice}",
# "minimumPrice": bottom_price, # 最低价格
"minimumPrice": f"{miniprice_info.get(asin)}" if miniprice_info.get(asin) else "",
"firstPlace": price_1,
"secondPlace": price_2,
"cartShopName": cartShopName,
"shippingFee": f"{shipping_fee}",
"priceChangeStatus": "跳过,无需改价",
"priceChangePrice": f"{adjust_prices}".replace("None",""),
})
except Exception as e:
self.log(f"{asin},操作出错,{e}")
continue
already_asin.add(asin)
# 判断是否存在需要翻页的情况
page_pamel = self.tab.eles('xpath://kat-pagination', timeout=5)
if len(page_pamel) == 0:
break
next_page_btn = page_pamel[0].sr('xpath:.//span[@part="pagination-nav-right"]')
class_str = next_page_btn.attr('class')
if "end" in class_str:
break
next_page_btn.click()
num += 1
self.log(f"【程序计算】正在翻页,已翻 {num} 页...")
already_asin = set()
retry_num = 0
except Exception as e:
self.log(f"处理跟价操作异常", e)
traceback.print_exc()
retry_num += 1
self.tab.refresh()
self.tab.wait.doc_loaded(raise_err=False, timeout=120)
class PriceTask(TaskBase):
task_name = "跟价-TASK"
def process_task(self, task_data: dict):
"""处理审批任务主入口
Args:
task_data: 任务数据
"""
try:
data = task_data.get("data", {})
task_id = data.get("task_id")
# items = data.get("items", [])
shop_name = data.get("shop_name")
country_codes = data.get("country_codes", [])
risk_listing_filter = data.get("risk_listing_filter", "Active")
user_id = data.get("user_id")
stage_index = data.get("stage_index")
final_stage = bool(data.get("final_stage", True))
# 用于测试
limit = data.get("limit", None)
if not task_id:
self.log("任务ID为空跳过", "WARNING")
return
# if not items:
# self.log("店铺列表为空,跳过", "WARNING")
# return
if not country_codes:
self.log("国家列表为空,跳过", "WARNING")
return
self.log(f"开始处理审批任务 {task_id},共 1 个店铺,{len(country_codes)} 个国家")
from config import runing_task
runing_task[task_id] = {
"status": "running",
"start_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"total_shops": 1,
"processed_shops": 0,
"total_countries": len(country_codes) ,
"processed_countries": 0,
"total_asins": 0,
"processed_asins": 0,
"success_count": 0,
"failed_count": 0,
"stop_requested": False
}
# 检查是否收到暂停请求
if task_id in runing_task and runing_task[task_id].get("stop_requested", False):
self.log(f"检测到任务 {task_id} 的暂停请求,停止处理", "WARNING")
runing_task[task_id]["status"] = "stopped"
return
self.log(f"开始处理店铺: {shop_name}")
show_notification(f"开始处理店铺: {shop_name}", "info")
try:
self.process_shop(data, country_codes, task_id, risk_listing_filter, user_id, stage_index,
final_stage, limit=limit)
# self.process_shop(shop_item, country_codes, task_id,risk_listing_filter)
# 更新已处理店铺数
if task_id in runing_task:
runing_task[task_id]["processed_shops"] += 1
except Exception as e:
self.log(f"处理店铺 {shop_name} 失败: {str(e)}", "ERROR")
self.log(traceback.format_exc(), "ERROR")
# 更新任务状态
if task_id in runing_task:
if runing_task[task_id].get("stop_requested", False):
runing_task[task_id]["status"] = "stopped"
self.log(f"任务 {task_id} 已被暂停!")
else:
runing_task[task_id]["status"] = "completed"
self.log(f"任务 {task_id} 处理完成!")
except Exception as e:
self.log(f"任务处理失败: {traceback.format_exc()}", "ERROR")
if task_id:
from config import runing_task
if task_id in runing_task:
runing_task[task_id]["status"] = "failed"
runing_task[task_id]["error"] = str(e)
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):
"""处理单个店铺
Args:
shop_item: 店铺信息
country_codes: 国家代码列表
task_id: 任务ID
risk_listing_filter: 风险商品筛选条件
"""
shop_name = shop_item.get("shopName", "未知店铺")
company_name = shop_item.get("companyName", "")
shopMallName = shop_item.get("shopMallName","")
skip_asins_by_country = shop_item.get("skip_asins_by_country",{})
asin_rows_by_country = shop_item.get("asin_rows_by_country",{})
skip_asin_details_by_country = shop_item.get("skip_asin_details_by_country",{})
minimum_price_by_country_and_asin = shop_item.get("minimum_price_by_country_and_asin",{})
if len(minimum_price_by_country_and_asin) > 0:
country_codes = minimum_price_by_country_and_asin.keys()
# 指定ASIN的情况
mode = shop_item.get("mode")
if not company_name:
self.log(f"店铺 {shop_name} 的公司名称为空,跳过", "WARNING")
return
if task_id in runing_task:
runing_task[task_id]["current_shop"] = shop_name
# 将店铺添加到正在执行中的店铺列表
start_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
runing_shop[shop_name] = start_time
self.log(f"店铺 {shop_name} 已添加到执行列表,账号: {company_name},开始时间: {start_time}")
# 店铺打开重试最多3次
driver = None
max_retries = 3
iskill = False
# 处理每个国家
for country_code in country_codes:
# 打开店铺
driver = self.open_shop(cls=AmzonePriceMatch,max_retries=max_retries, company_name=company_name,
shop_name=shop_name,iskill=iskill)
if driver is None:
self.log(f"任务 {task_id} 启动店铺失败,结束任务", "ERROR")
for country_code in country_codes:
self.post_result(task_id, shop_name, country_code, "", {}, shopMallName, is_done=True)
return
# 检查是否收到暂停请求
if task_id in runing_task and runing_task[task_id].get("stop_requested", False):
self.log(f"检测到任务 {task_id} 的暂停请求,停止处理国家", "ERROR")
driver.close_store()
break
skip_asin = skip_asins_by_country.get(country_code,[]) #需要跳过的asin
appoint_asin = asin_rows_by_country.get(country_code,[])
if mode == "status":
miniprice_info = {i.get('asin'):i.get('minimumPrice') for i in skip_asin_details_by_country.get(country_code,[])}
else:
miniprice_info = minimum_price_by_country_and_asin.get(country_code,{})
current_url = None
for _ in range(max_retries):
try:
self.process_country(driver, country_code, task_id, shop_name, risk_listing_filter,
shopMallName=shopMallName,skip_asin=skip_asin, limit=limit,
appoint_asin=appoint_asin,mode=mode,miniprice_info=miniprice_info,
target_url=current_url
)
driver.reset_already_asin()
driver.close_store()
break
except Exception as e:
self.log(f"处理国家 {country_code} 失败: {str(e)}", "ERROR")
self.log(traceback.format_exc(), "ERROR")
if "与页面的连接已断开" in str(e):
iskill = True
current_url = driver.url
# 更新已处理国家数
if task_id in runing_task:
runing_task[task_id]["processed_countries"] += 1
# 关闭店铺
driver.close_store()
# 最后回传,标记完成
try:
# self.post_result(task_id, shop_name, country_code, "", "", is_done=True)
if final_stage:
self.post_result(task_id, shop_name, country_code, "", {},shopMallName,is_done=True)
else:
self.post_stage_finished(task_id, user_id, stage_index)
except Exception as e:
self.log(f"回传结果失败: {str(e)}", "ERROR")
self.log(f"{task_id}任务处理完成")
# 从正在执行中的店铺列表中移除
if shop_name in runing_shop:
del runing_shop[shop_name]
self.log(f"店铺 {shop_name} 已从执行列表中移除")
def process_country(self, driver: AmzonePriceMatch, country_code: str, task_id: int, shop_name: str,
risk_listing_filter: str,shopMallName:str,skip_asin:list,appoint_asin:list,mode:str,
miniprice_info:dict={}, limit: str = None,target_url:str=None):
"""处理单个国家的审批任务
Args:
driver: AmzoneApprove驱动实例
country_code: 国家代码(如 UK, DE, FR 等)
task_id: 任务ID
shop_name: 店铺名称
risk_listing_filter: 风险商品筛选条件
"""
# 转换国家代码为中文名称
country_name = self.country_info.get(country_code, country_code)
info_mes = f"开始处理国家: {country_name} ({country_code}),需要跳过的asin {skip_asin}"
self.log(info_mes)
show_notification(f"开始处理国家:{country_name}", "info")
# 更新当前处理的国家
if task_id in runing_task:
runing_task[task_id]["current_country"] = country_name
# 切换国家最多重试3次
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 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
self.log(f"国家 {country_name} ,开始处理...")
if target_url is not None: #从失败的链接继续
self.log(f"开始访问:{target_url}")
driver.tab.get(url=target_url)
driver.tab.wait.doc_loaded(timeout=60,raise_err=False)
result = []
# 指定 asin
max_range = max(1,len(appoint_asin))
for i in range(max_range):
if len(appoint_asin) > i:
_shopMallName = appoint_asin[i]["shopMallName"]
ap_asin = appoint_asin[i]["asin"]
else:
_shopMallName = shopMallName
ap_asin = None
if not _shopMallName:
self.log(f"没有店铺名,不执行,{_shopMallName}","ERROR")
return
for _ in range(max_retries):
for asin, status in driver.run_page_action(
current_shop_name=_shopMallName,
appoint_asin=ap_asin,skip_asin=skip_asin,mode=mode,
miniprice_info=miniprice_info
):
if asin is None:
continue
# 检查是否收到暂停请求
if task_id in runing_task and runing_task[task_id].get("stop_requested", False):
self.log(f"检测到任务 {task_id} 的暂停请求停止处理ASIN", "WARNING")
break
self.log(f"ASIN {asin} 处理结果: {status}")
# 更新任务状态
if task_id in runing_task:
runing_task[task_id]["current_asin"] = asin
runing_task[task_id]["processed_asins"] += 1
runing_task[task_id]["failed_count"] += 1
result.append({
"shopMallName": shopMallName,
"asin": asin,
"price": status.get("currentPrice") if status.get("currentPrice") else "",
"recommendedPrice": status.get("recommendedPrice") if status.get(
"recommendedPrice") else "",
"minimumPrice": status.get("minimumPrice") if status.get("minimumPrice") else "",
"firstPlace": status.get("firstPlace") if status.get("firstPlace") else "",
"secondPlace": status.get("secondPlace") if status.get("secondPlace") else "",
"cartShopName": status.get("cartShopName") if status.get("cartShopName") else "",
# "priceChangeStatus": "UPDATED",
"deleteSkipAsin": status.get("deleteSkipAsin", False),
"removeAsin": status.get("removeAsin") if status.get("removeAsin") else "",
"modifyCount": "1",
"shippingFee": status.get("shippingFee") if status.get("shippingFee") else "",
"status": status.get("statu"),
"priceChangeStatus": status.get("priceChangeStatus") if status.get(
"priceChangeStatus") else "",
"priceChangePrice": status.get("priceChangePrice") if status.get(
"priceChangePrice") else "",
}
)
if len(result) > 20:
self.post_result_batch(task_id, shop_name, country_code, result)
result = []
break
if len(result) > 0:
self.post_result_batch(task_id, shop_name, country_code, result)
self.log(f"国家 {country_name} 处理完成")
def post_stage_finished(self, task_id: int, user_id, stage_index):
if user_id in (None, "", 0):
raise ValueError("user_id is required for stage completion callback")
if stage_index is None:
raise ValueError("stage_index is required for stage completion callback")
url = f"{DELETE_BRAND_API_BASE}/api/shop-match/tasks/{task_id}/stage-finished"
payload = {"stage_index": stage_index}
params = {"user_id": user_id}
max_retries = 3
for retry in range(max_retries):
try:
self.log(f"Attempting stage completion callback ({retry + 1}/{max_retries})")
response = requests.post(
url,
params=params,
json=payload,
headers={"Content-Type": "application/json"},
timeout=30,
verify=False,
)
self.log(f"Stage completion callback response: {response.text}")
data = response.json() if response.text else {}
if response.status_code == 200 and isinstance(data, dict) and data.get("success"):
self.log(f"Stage completion callback succeeded: task={task_id}, stage={stage_index}")
return
self.log(f"Stage completion callback failed, status={response.status_code}", "WARNING")
except Exception as e:
self.log(f"Stage completion callback exception: {str(e)}", "ERROR")
if retry < max_retries - 1:
time.sleep(2)
raise RuntimeError(f"Stage completion callback failed after retries: task={task_id}, stage={stage_index}")
def post_result(self, task_id: int, shop_name: str, country_code: str, asin: str, status: dict,shopMallName:str,
is_done: bool = False):
"""回传处理结果到API
Args:
task_id: 任务ID
shop_name: 店铺名称
country_code: 国家代码
asin: ASIN
status: 处理状态
"""
url = f"{DELETE_BRAND_API_BASE}/api/price-track/tasks/{task_id}/result"
country_aliases = {name: code for code, name in self.country_info.items()}
country_key = country_aliases.get(str(country_code).strip(), str(country_code).strip())
payload = {
"shops": [
{
"shopName": shop_name,
"countries": {
country_key : [
{
"shopMallName": shopMallName,
"asin": asin,
"price": status.get("currentPrice") if status.get("currentPrice") else "",
"recommendedPrice": status.get("recommendedPrice") if status.get("recommendedPrice") else "",
"minimumPrice": status.get("minimumPrice") if status.get("minimumPrice") else "",
"firstPlace": status.get("firstPlace") if status.get("firstPlace") else "",
"secondPlace": status.get("secondPlace") if status.get("secondPlace") else "",
"cartShopName": status.get("cartShopName") if status.get("cartShopName") else "",
# "priceChangeStatus": "UPDATED",
"deleteSkipAsin": status.get("deleteSkipAsin",False),
"removeAsin": status.get("removeAsin") if status.get("removeAsin") else "",
"modifyCount": "1",
"shippingFee" : status.get("shippingFee") if status.get("shippingFee") else "",
"status": status.get("statu"),
"priceChangeStatus" : status.get("priceChangeStatus") if status.get("priceChangeStatus") else "",
"priceChangePrice" : status.get("priceChangePrice") if status.get("priceChangePrice") else "",
}
]
},
"error": ""
}
]
}
if is_done:
payload["shops"][0]["success"] = is_done
max_retries = 3
for retry in range(max_retries):
try:
print("================【跟价】=====================")
self.log(f"尝试回传结果 (第 {retry + 1}/{max_retries} 次)")
self.log(f"回传URL: {url}")
self.log(f"回传数据: {payload}")
response = requests.post(
url,
json=payload,
headers={"Content-Type": "application/json"},
timeout=30,
verify=False
)
self.log(f"回传结果: {response.text}")
data = response.json() if response.text else {}
if response.status_code == 200 and isinstance(data, dict) and data.get("success"):
self.log(f"结果回传成功: {asin} - {status}")
return
else:
self.log(f"结果回传失败,状态码: {response.status_code}", "WARNING")
print("=====================================")
except Exception as e:
self.log(f"调用API异常: {str(e)}", "ERROR")
print("=====================================")
# 如果还有重试机会,等待后继续
if retry < max_retries - 1:
time.sleep(2)
self.log(f"已达到最大重试次数,结果回传最终失败", "ERROR")
# raise RuntimeError("已达到最大重试次数,结果回传最终失败")
def post_result_batch(self, task_id: int, shop_name: str, country_code: str, country_data,is_done: bool = False):
"""回传处理结果到API
"""
url = f"{DELETE_BRAND_API_BASE}/api/price-track/tasks/{task_id}/result"
country_aliases = {name: code for code, name in self.country_info.items()}
country_key = country_aliases.get(str(country_code).strip(), str(country_code).strip())
payload = {
"shops": [
{
"shopName": shop_name,
"countries": {
country_key: country_data
},
"error": ""
}
]
}
if is_done:
payload["shops"][0]["success"] = is_done
max_retries = 3
for retry in range(max_retries):
try:
self.log("================【跟价】=====================")
self.log(f"尝试回传结果 (第 {retry + 1}/{max_retries} 次)")
self.log(f"回传URL: {url}")
self.log(f"回传数据: {payload}")
response = requests.post(
url,
json=payload,
headers={"Content-Type": "application/json"},
timeout=30,
verify=False
)
self.log(f"回传结果: {response.text}")
data = response.json() if response.text else {}
if response.status_code == 200 and isinstance(data, dict) and data.get("success"):
self.log(f"结果回传成功")
return
else:
self.log(f"结果回传失败,状态码: {response.status_code}", "WARNING")
self.log("=====================================")
except Exception as e:
self.log(f"调用API异常: {str(e)}", "ERROR")
self.log("=====================================")
# 如果还有重试机会,等待后继续
if retry < max_retries - 1:
time.sleep(2)
self.log(f"已达到最大重试次数,结果回传最终失败", "ERROR")
if __name__ == '__main__':
# 使用示例
user_info = {
"company": "尾号5578的公司115",
"username": "自动化_Robot",
"password": "#20zsg25"
}
# shop_name = "周洪"
# country = "德国"
# kill_process('v6')
# driver = AmzonePriceMatch(user_info)
# browser = driver.open_shop(shop_name)
# sw_suc = driver.SwitchingCountries(country)
# driver.SwitchPage()
# risk_listing_filter = "Active"
# _shopMallName = "Zhou Hong 600"
# ap_asin ="B0FK574K91"
# skip_asin = []
# for _ in range(3):
# try:
# sku_ls = driver.search(filter_type=risk_listing_filter)
# break
# except Exception as e:
# print(e)
# driver.tab.refresh()
# if len(sku_ls) > 0:
# print("有数据,开始操作")
# for asin, status in driver.run_page_action(
# current_shop_name=_shopMallName,
# appoint_asin=ap_asin,skip_asin=skip_asin,mode="asin"
# ):
# print(f"ASIN {asin} 的处理结果: {status}")
# print("已完成操作")
# front_end_data = {'top_sellers': [{'rank': 1, 'price': '30.14', 'stock': '100', 'shop_name': 'Zhou Hong 600'}], 'cart_seller': 'Zhou Hong 600', 'timestamp': '2026-04-30 23:47:02'}
#
# current_Price = 30.14
# current_shop_name = "Zhou Hong 600"
# recommended_price = 30.14
# recommended_shipping =0.0
# res = calculate_target_price(
# front_end_data, current_Price, current_shop_name,
# recommended_price, recommended_shipping
# )
# print(res)
task_data = {'type': 'price-track-run', 'ts': 1777746140975, 'data': {'task_id': 5658, 'result_id': 7627, 'shop_name': '郭锋滨', 'shop_id': '27769139291498', 'platform': '亚马逊', 'company_name': '尾号5578的公司115', 'shop_mall_name': '', 'matched': True, 'match_status': 'MATCHED', 'match_message': None, 'success': False, 'error': None, 'output_filename': None, 'download_url': None, 'task_status': 'RUNNING', 'loop_run_id': 235, 'round_index': 1, 'country_codes': ['UK', 'DE', 'FR', 'ES', 'IT'], 'mode': 'status', 'skip_asins': {'DE': ['B0FMKM1BYH', 'B0DJT78FNR', 'B0DJLJ73RB', 'B0D6QL2JMY', 'B0CFKLPKF5', 'B09BMWX6Q1', 'B07C4MNWFL', 'B0FHDGLQK7', 'B0FHD9S7K7', 'B0FB2FB6G6', 'B0F9W8VXWQ', 'B0F9W81F2F', 'B0F9W7KLNM', 'B0F2ZJWJNC', 'B0D49F7LM4', 'B0CXSP3PDP', 'B0CLXZHM2G', 'B0CG8RNWL6', 'B0C4SZ8GZW', 'B0BVM53J3B', 'B0BNHN9N9X', 'B0BMXBNMP5', 'B0BLN7D2JZ', 'B09MYVN5YK', 'B09MBNG7P4', 'B0DXTSTZC6', 'B0D25871WL', 'B0CL69XRTY', 'B0CKXMDBN8', 'B0CGDF2G8V', 'B0CFTGXVYF', 'B0CFT6XPPD', 'B09YXTN8JP', 'B0DHX32XJH', 'B0DHL7FQJM', 'B0DHL63M79', 'B0CWXYY74V', 'B0CWXYRGZW', 'B0CPLR6YHB', 'B0BXP4RC25', 'B0BFRRZDCH', 'B0B65R3N47', 'B0F36ZSWTQ', 'B0DT1DYWC6', 'B0DNZ5WX1L', 'B0DNZ5N7HY', 'B0DCJJ3PCM', 'B0D8JV9MB9', 'B0D2KCRLJ1', 'B0CRVRDS8C', 'B0CQK7QWJB', 'B0CQK5SRXW', 'B0BCL2DLPC', 'B0B9JBHPFY', 'B09TVY4V8Z', 'B0FJBD6Q3D', 'B0DG8LQLXZ', 'B0CD7Q1BX3', 'B0BV1SR48Y', 'B0F29CFJJ9', 'B0DSL6PKR7', 'B0CPV21W4L', 'B0CNQZ7FXY', 'B0CLY9XT5M', 'B0CGTMZ8GP', 'B0CF881PG4', 'B0CF4K1G4R', 'B0CB5T79XG', 'B0C73PQ9KM', 'B0C28TBN79', 'B09T31ZRJF', 'B01LBOYWNO', 'B0DDTB25YZ', 'B0D1Q8GL1Y', 'B0CW9JC84B', 'B0CLGJG36H', 'B0CF9JWKHJ', 'B0C2J3V92Q', 'B0BVVYZ6TN', 'B0B8J8VF7C', 'B0B4BFVZD1', 'B09R1CPKVX', 'B0924BNVH2', 'B0F54M2147', 'B0F1BZNBY6', 'B0F1BXV9WG', 'B0DC957VHC', 'B0D8778SZB', 'B0CP9WVSRY', 'B0CKNQP1PT', 'B0CJ4PW758', 'B0BYFD87C6', 'B0B492K9KT', 'B09968XMC7', 'B0FGJ8RCW1', 'B0FGJ4WK8B', 'B0FFMYGWHP', 'B0FD3DLFKL', 'B0FBWRWXG2', 'B0F99RW38N', 'B0F62LZ4G3', 'B0F629FLVV', 'B0F2N88DS9', 'B0F23Y11GD', 'B0F1YV8T2S', 'B0DXK9PR5X', 'B0DRV7QZ85', 'B0DRV7LN4V', 'B0DR4QYC2M', 'B0D5QL869M', 'B0D41VK3YL', 'B0D3XBW4KT', 'B0D2KW1ZRL', 'B0CPPC6PDW', 'B0CHVPSJ61', 'B0C5C1V5JD', 'B0C232Z6C6', 'B0C22KBMJC', 'B0BZVL6Y9X', 'B0BX58MW7N', 'B0B9M86GMC', 'B08DQVJ2VB', 'B07WKYLJ3T', 'B092D7P9BP', 'B0F9W2MZJY', 'B09KXV2C3T', 'B092D7TM65', 'B0CR3P2F5L', 'B0BWCSCYFL', 'B08JLW8S3Y', 'B0D4H73BJH', 'B08D77WTYG', 'B08D73XW2J', 'B09H4RB4ZL', 'B09WMQ29GH', 'B0DJ2M2RYC', 'B0BGF2QCKT', 'B0DS6FC8M7', 'B098QFLVDZ', 'B0DMD16GTD', 'B0CNVLLQ3J', 'B0CP3JZ1P5', 'B0C1GR4K6W', 'B0CBM792D2', 'B09NJK6K5T', 'B0D8Q5MK31', 'B0CYSCV19T', 'B0C5D5XPLJ', 'B09R3NFGH2', 'B09BG1QD9M', 'B092QY1823', 'B0C55PGK51', 'B0DRN8MXRG', 'B08152JKFB', 'B09Y1P7GK7', 'B0CG62X5GT', 'B0DHJKKZDD', 'B0DYHZ59YL', 'B0D2D5WS2D', 'B0G6LHVRKG', 'B0DQ53F84K', 'ASDASD', 'B0CJTCGDB7232', 'B0CJTCGDB7213', 'B0CJTCGDB79', 'B0CJTCGDB78', 'B0CJTCGDB77', 'B0CJTCGDB76', 'B0CJTCGDB75', 'B0CJTCGDB74', 'B0CJTCGDB73', 'B0CJTCGDB72', 'B0CJTCGDB71', 'B0CJTCGDB7', '1'], 'UK': ['B0FGJD2P9Q', 'B0DKBSWJ93', 'B0DJT78FNR', 'B0DFCR79L5', 'B0DCBJ3WY5', 'B0D9LPW1YB', 'B0D7VDQG19', 'B0CP5K31TL', 'B0CG3RG7RQ', 'B0C8DSPMNC', 'B0B6H8RCHC', 'B08TVWB36K', 'B08FZMZQ11', 'B0G6LHVRKG', 'B0FF36SY6Q', 'B0DYTNBMB2', 'B0DQNLGSMQ', 'B0DNSNN7NH', 'B0DJWHHFBS', 'B0DJHSJ9LS', 'B0D2D5WS2D', 'B0CG8RNWL6', 'B0C5D5XPLJ', 'B09WHYGBSR', 'B09WHV9JCJ', 'B09P4VCL2V', 'B09MYVN5YK', 'B09MBNG7P4', 'B0DM63394K', 'B0D1Q4RR99', 'B0CZD1HLY7', 'B0CWD9R2FS', 'B0CS6WYRFW', 'B0CRVTSQGQ', 'B0CR8FTHYP', 'B0CCB5Q5ZY', 'B0CC94W5G7', 'B0CC948Q8Q', 'B0CC93R18S', 'B0CC92F33P', 'B0BZ4DNWPY', 'B0BZ4CMQDL', 'B07Q4RBT32', 'B0DHX32XJH', 'B0DHX1HR7X', 'B0DHTT1X71', 'B0DHTRLQ2L', 'B0DHL7FQJM', 'B0D3V1BJX9', 'B0D3TZ45C3', 'B0D2SDNYS5', 'B0CQY5SM94', 'B0CQLN2FC1', 'B0CQF6W2JT', 'B0BY85GDF5', 'B0BY82BRTZ', 'B0B73K6QZQ', 'B0B4MDDD7D', 'B0F1X5Q9Q6', 'B0DYHPWTVJ', 'B0DQNJPS5M', 'B0DQ4B5SF7', 'B0DNZ5WX1L', 'B0DKX28SNX', 'B0DHVTGXPD', 'B0DHDBN98L', 'B0DFXRP8X1', 'B0DFGPGXY6', 'B0D8JV9MB9', 'B0D2KCRLJ1', 'B0CW63X5XY', 'B0CRVRDS8C', 'B0CRHWLDY4', 'B0CLZBR5CM', 'B0CL67FJFL', 'B0CG2C89ZZ', 'B0BP7YMCXH', 'B0BM8Y94QC', 'B0BJKBRTK7', 'B0BCL2DLPC', 'B0B6PSLTPF', 'B0B6PS4RQ1', 'B0B5L4HC95', 'B08ZT1PJ2K', 'B0FGQ31VWT', 'B0FFT33WRF', 'B0FD3S6DRN', 'B0F2GBR7MP', 'B0F2G5TG4S', 'B0F2FZVS7X', 'B0F2FYW3HN', 'B0F2B6924H', 'B0DSJMMMXN', 'B0DJT68ZM3', 'B0DJT66VG3', 'B0DJT5YJXD', 'B0DCGSFTYX', 'B0D8C6KL4G', 'B0C9H8MJC3', 'B0C85JQNRC', 'B0C5QQFN1G', 'B0BZ8FXRZG', 'B0BS8SW341', 'B0FLVP9N4Y', 'B0F2MPWSCQ', 'B0F29CFJJ9', 'B0DSKC1GQB', 'B0DSCBZSGS', 'B0DSCB329P', 'B0DLNXW8W5', 'B0DJQHVBZZ', 'B0DGCW7WBY', 'B0DFTG85NG', 'B0D99N1DZY', 'B0D8B849BJ', 'B0D89YCGCR', 'B0D89WK6JF', 'B0D89PMKKP', 'B0D7X1634D', 'B0D7V3W7D1', 'B0CYT3R89Z', 'B0CY7P61VD', 'B0CQ8B9PZM', 'B0CNK1SV4P', 'B0CF4K1G4R', 'B0CF4JJXHY', 'B0CF4BJ42D', 'B0C6T346MQ', 'B0BX2KDVMY', 'B0BR4YWSF9', 'B0BR4XHP5Z', 'B09Z68FK4Q', 'B09SL3PTTM', 'B09JBQZQQL', 'B08PSSRS3C', 'B08G4P4F76', 'B0DRD7T6TQ', 'B0DQXT78DT', 'B0DQXRV47R', 'B0DQXRV18S', 'B0DQXRLK5X', 'B0DQXQNL6Z', 'B0D2KQVS2Y', 'B0CXJC74TK', 'B0CW9JC84B', 'B0CSYBNXWX', 'B0CRHSTGX6', 'B0CPPJTX5C', 'B0CJB9WFHD', 'B0CF9JWKHJ', 'B0BVVYZ6TN', 'B0BND2YKJF', 'B09TRCQNQH', 'B09H5J6YQX', 'B09CNRP5FJ', 'B08BZ9LW9Z', 'B0F54M2147', 'B0F388HQLY', 'B0F1BZNBY6', 'B0F1BXV9WG', 'B0DSD949P4', 'B0DFQ2FP96', 'B0D9YXGFQW', 'B0CP9WVSRY', 'B0CKZ35SJC', 'B0CHYNDX87', 'B0CH66SNFC', 'B0BHSWP8RD', 'B0BGRW6858', 'B0B6JKD25B', 'B0B1LJB3M5', 'B09P3S4SH5', 'B09NLSRHGV', 'B0FVDPV5NS', 'B0FQJ5CDL2', 'B0FLJLWTLV', 'B0FGQ1VP2J', 'B0FD6YL7MM', 'B0FBWP9GJL', 'B0F99RW38N', 'B0F3Y3M538', 'B0F27ZM2TG', 'B0F23Y11GD', 'B0F23WZ78P', 'B0F1MY4PF6', 'B0DXKC6H1G', 'B0DQLNTLF4', 'B0DM8DYG77', 'B0DHJNBFVH', 'B0DH1XKG95', 'B0DFYG7C4K', 'B0DFTR1CMN', 'B0DB8FM915', 'B0D5H65VW3', 'B0D3XBW4KT', 'B0CRKJWJ4X', 'B0CPPGX6FQ', 'B0CPPGSBHD', 'B0CL9PVZD1', 'B0C232Z6C6', 'B0C22KBMJC', 'B0BX58MW7N', 'B0B6T3N5MG', 'B0B4S9QYWM', 'B0B4S93T7Q', 'B09R1PMW3J', 'B08MLN92JM', 'B0BHN71FWM', 'B09NKRWXPC', 'B0C89TNVTN', 'B0D1VDMZR1', 'B0DS2QT1YZ', 'B09Y29P5YF', 'B0DBQDSHVZ', 'B0CFF62JY3', 'B0BHPGTWQR', 'B0D4F4D3W2', 'B0F13BRF4V', 'B0D1FXTY99', 'B00KY0LLFO', 'B0B7MJXDZC', 'B0B4DV8NLV', 'B0DJXRFCF7', 'B0BPHMFD7V', 'B0F281ZQWR', 'B0D7V2FNW3', 'B0D57X7KV9', 'B0CJ2SST5Z', 'B0CZ92LPP4', 'B0CG5Z2Z44', 'B0D6T9H5LX', 'B0CQJNR9MP', 'ZXCA', 'B0CJTGDB7232', 'B0CJTGDB7213', 'B0CJTGDB79', 'B0CJTGDB78', 'B0CJTGDB77', 'B0CJCGDB76', 'B0CJCGDB75', 'B0CJCGDB74', 'B0CJCGDB73', 'B0CJCGDB72', 'B0CJCGDB71', 'B0CJCGDB7', 'B0CTCGDB7', 'B0FGTNLTG3', 'WQDASDAS', 'SADAD', 'DFHFGH78979'], 'FR': ['B0FY6JY4BF', 'B0DZNRB5Q1', 'B0DNSKFLGK', 'B0DGLCQDTR', 'B0D9W93869', 'B0CG8RNWL6', 'B0BX94RYT1', 'B0BLN7D2JZ', 'B09WHV9JCJ', 'B0DKX28SNX', 'B0CZCVTMRJ', 'B0CC95H28M', 'B0CC942XSZ', 'B0CC93WW6S', 'B0CC93TDB9', 'B0816GGCFY', 'B0CQY5SM94', 'B0DQTKRNLH', 'B0DCB85F3J', 'B0D8JR3W53', 'B0D2KCRLJ1', 'B0CQK7QWJB', 'B0B9XM29C9', 'B0B5L4HC95', 'B0F9FCT8RD', 'B0BZ8J16JM', 'B0BV1TRMGN', 'B09G68LMB3', 'B0DCRJSMJP', 'B093Y447R2', 'B0D8Y5KWB8', 'B0BJK43Z6X', 'B0DXK7YZ5D', 'B0C232Z6C6', 'B0BZVL6Y9X', 'B0B4S98HLZ', 'B09VPMBMB8', 'B0D17L6YKN'], 'IT': ['B0DTK87KJ5', 'B0DNSNN7NH', 'B0D9W93869', 'B0CLXZHM2G', 'B0CG8RNWL6', 'B0BX94RYT1', 'B0BVM53J3B', 'B0BLN7D2JZ', 'B0F9KVS6Y2', 'B0F8QGHMLL', 'B0CY5KW8RY', 'B0CC94P4H1', 'B0CC94K2HN', 'B0CC922QN8', 'B0C7Q51PL1', 'B0D8JR3W53', 'B0B5L4HC95', 'B0C5C53444', 'B0F5PRVRLF', 'B0BJK43Z6X', 'B09WKFD3G8', 'B08NT2BNGH', 'B0DRV6D214', 'B08QRKHD3C', 'B09JMW3F1R', 'B0CKYHTDJ5', 'B098QFLVDZ', '32EGDFGS4', 'B087JP6PWL89'], 'ES': ['B0D2J11TKY', 'B0CLY2THTY', 'B0D8JS8NPH', 'B0CYGSBXSQ', 'B0CKXMDBN8', 'B0CJ5F9J4Z', 'B0CC95XMD4', 'B0CC93ZNH2', 'B07L281N1M', 'B0DNZ5N7HY', 'B0C7V4BFSZ', 'B0B5L4HC95', 'B0DZCC4B4T', 'B0DZBQ4ZNC', 'B0C5QQFN1G', 'B0BFXD4LYN', 'B0F3122Q81', 'B0BG73XTFC', 'B0CNM269LZ', 'B08QS37RHQ', 'B087JP6PWL89']}, 'skip_asins_by_country': {'DE': ['B0FMKM1BYH', 'B0DJT78FNR', 'B0DJLJ73RB', 'B0D6QL2JMY', 'B0CFKLPKF5', 'B09BMWX6Q1', 'B07C4MNWFL', 'B0FHDGLQK7', 'B0FHD9S7K7', 'B0FB2FB6G6', 'B0F9W8VXWQ', 'B0F9W81F2F', 'B0F9W7KLNM', 'B0F2ZJWJNC', 'B0D49F7LM4', 'B0CXSP3PDP', 'B0CLXZHM2G', 'B0CG8RNWL6', 'B0C4SZ8GZW', 'B0BVM53J3B', 'B0BNHN9N9X', 'B0BMXBNMP5', 'B0BLN7D2JZ', 'B09MYVN5YK', 'B09MBNG7P4', 'B0DXTSTZC6', 'B0D25871WL', 'B0CL69XRTY', 'B0CKXMDBN8', 'B0CGDF2G8V', 'B0CFTGXVYF', 'B0CFT6XPPD', 'B09YXTN8JP', 'B0DHX32XJH', 'B0DHL7FQJM', 'B0DHL63M79', 'B0CWXYY74V', 'B0CWXYRGZW', 'B0CPLR6YHB', 'B0BXP4RC25', 'B0BFRRZDCH', 'B0B65R3N47', 'B0F36ZSWTQ', 'B0DT1DYWC6', 'B0DNZ5WX1L', 'B0DNZ5N7HY', 'B0DCJJ3PCM', 'B0D8JV9MB9', 'B0D2KCRLJ1', 'B0CRVRDS8C', 'B0CQK7QWJB', 'B0CQK5SRXW', 'B0BCL2DLPC', 'B0B9JBHPFY', 'B09TVY4V8Z', 'B0FJBD6Q3D', 'B0DG8LQLXZ', 'B0CD7Q1BX3', 'B0BV1SR48Y', 'B0F29CFJJ9', 'B0DSL6PKR7', 'B0CPV21W4L', 'B0CNQZ7FXY', 'B0CLY9XT5M', 'B0CGTMZ8GP', 'B0CF881PG4', 'B0CF4K1G4R', 'B0CB5T79XG', 'B0C73PQ9KM', 'B0C28TBN79', 'B09T31ZRJF', 'B01LBOYWNO', 'B0DDTB25YZ', 'B0D1Q8GL1Y', 'B0CW9JC84B', 'B0CLGJG36H', 'B0CF9JWKHJ', 'B0C2J3V92Q', 'B0BVVYZ6TN', 'B0B8J8VF7C', 'B0B4BFVZD1', 'B09R1CPKVX', 'B0924BNVH2', 'B0F54M2147', 'B0F1BZNBY6', 'B0F1BXV9WG', 'B0DC957VHC', 'B0D8778SZB', 'B0CP9WVSRY', 'B0CKNQP1PT', 'B0CJ4PW758', 'B0BYFD87C6', 'B0B492K9KT', 'B09968XMC7', 'B0FGJ8RCW1', 'B0FGJ4WK8B', 'B0FFMYGWHP', 'B0FD3DLFKL', 'B0FBWRWXG2', 'B0F99RW38N', 'B0F62LZ4G3', 'B0F629FLVV', 'B0F2N88DS9', 'B0F23Y11GD', 'B0F1YV8T2S', 'B0DXK9PR5X', 'B0DRV7QZ85', 'B0DRV7LN4V', 'B0DR4QYC2M', 'B0D5QL869M', 'B0D41VK3YL', 'B0D3XBW4KT', 'B0D2KW1ZRL', 'B0CPPC6PDW', 'B0CHVPSJ61', 'B0C5C1V5JD', 'B0C232Z6C6', 'B0C22KBMJC', 'B0BZVL6Y9X', 'B0BX58MW7N', 'B0B9M86GMC', 'B08DQVJ2VB', 'B07WKYLJ3T', 'B092D7P9BP', 'B0F9W2MZJY', 'B09KXV2C3T', 'B092D7TM65', 'B0CR3P2F5L', 'B0BWCSCYFL', 'B08JLW8S3Y', 'B0D4H73BJH', 'B08D77WTYG', 'B08D73XW2J', 'B09H4RB4ZL', 'B09WMQ29GH', 'B0DJ2M2RYC', 'B0BGF2QCKT', 'B0DS6FC8M7', 'B098QFLVDZ', 'B0DMD16GTD', 'B0CNVLLQ3J', 'B0CP3JZ1P5', 'B0C1GR4K6W', 'B0CBM792D2', 'B09NJK6K5T', 'B0D8Q5MK31', 'B0CYSCV19T', 'B0C5D5XPLJ', 'B09R3NFGH2', 'B09BG1QD9M', 'B092QY1823', 'B0C55PGK51', 'B0DRN8MXRG', 'B08152JKFB', 'B09Y1P7GK7', 'B0CG62X5GT', 'B0DHJKKZDD', 'B0DYHZ59YL', 'B0D2D5WS2D', 'B0G6LHVRKG', 'B0DQ53F84K', 'ASDASD', 'B0CJTCGDB7232', 'B0CJTCGDB7213', 'B0CJTCGDB79', 'B0CJTCGDB78', 'B0CJTCGDB77', 'B0CJTCGDB76', 'B0CJTCGDB75', 'B0CJTCGDB74', 'B0CJTCGDB73', 'B0CJTCGDB72', 'B0CJTCGDB71', 'B0CJTCGDB7', '1'], 'UK': ['B0FGJD2P9Q', 'B0DKBSWJ93', 'B0DJT78FNR', 'B0DFCR79L5', 'B0DCBJ3WY5', 'B0D9LPW1YB', 'B0D7VDQG19', 'B0CP5K31TL', 'B0CG3RG7RQ', 'B0C8DSPMNC', 'B0B6H8RCHC', 'B08TVWB36K', 'B08FZMZQ11', 'B0G6LHVRKG', 'B0FF36SY6Q', 'B0DYTNBMB2', 'B0DQNLGSMQ', 'B0DNSNN7NH', 'B0DJWHHFBS', 'B0DJHSJ9LS', 'B0D2D5WS2D', 'B0CG8RNWL6', 'B0C5D5XPLJ', 'B09WHYGBSR', 'B09WHV9JCJ', 'B09P4VCL2V', 'B09MYVN5YK', 'B09MBNG7P4', 'B0DM63394K', 'B0D1Q4RR99', 'B0CZD1HLY7', 'B0CWD9R2FS', 'B0CS6WYRFW', 'B0CRVTSQGQ', 'B0CR8FTHYP', 'B0CCB5Q5ZY', 'B0CC94W5G7', 'B0CC948Q8Q', 'B0CC93R18S', 'B0CC92F33P', 'B0BZ4DNWPY', 'B0BZ4CMQDL', 'B07Q4RBT32', 'B0DHX32XJH', 'B0DHX1HR7X', 'B0DHTT1X71', 'B0DHTRLQ2L', 'B0DHL7FQJM', 'B0D3V1BJX9', 'B0D3TZ45C3', 'B0D2SDNYS5', 'B0CQY5SM94', 'B0CQLN2FC1', 'B0CQF6W2JT', 'B0BY85GDF5', 'B0BY82BRTZ', 'B0B73K6QZQ', 'B0B4MDDD7D', 'B0F1X5Q9Q6', 'B0DYHPWTVJ', 'B0DQNJPS5M', 'B0DQ4B5SF7', 'B0DNZ5WX1L', 'B0DKX28SNX', 'B0DHVTGXPD', 'B0DHDBN98L', 'B0DFXRP8X1', 'B0DFGPGXY6', 'B0D8JV9MB9', 'B0D2KCRLJ1', 'B0CW63X5XY', 'B0CRVRDS8C', 'B0CRHWLDY4', 'B0CLZBR5CM', 'B0CL67FJFL', 'B0CG2C89ZZ', 'B0BP7YMCXH', 'B0BM8Y94QC', 'B0BJKBRTK7', 'B0BCL2DLPC', 'B0B6PSLTPF', 'B0B6PS4RQ1', 'B0B5L4HC95', 'B08ZT1PJ2K', 'B0FGQ31VWT', 'B0FFT33WRF', 'B0FD3S6DRN', 'B0F2GBR7MP', 'B0F2G5TG4S', 'B0F2FZVS7X', 'B0F2FYW3HN', 'B0F2B6924H', 'B0DSJMMMXN', 'B0DJT68ZM3', 'B0DJT66VG3', 'B0DJT5YJXD', 'B0DCGSFTYX', 'B0D8C6KL4G', 'B0C9H8MJC3', 'B0C85JQNRC', 'B0C5QQFN1G', 'B0BZ8FXRZG', 'B0BS8SW341', 'B0FLVP9N4Y', 'B0F2MPWSCQ', 'B0F29CFJJ9', 'B0DSKC1GQB', 'B0DSCBZSGS', 'B0DSCB329P', 'B0DLNXW8W5', 'B0DJQHVBZZ', 'B0DGCW7WBY', 'B0DFTG85NG', 'B0D99N1DZY', 'B0D8B849BJ', 'B0D89YCGCR', 'B0D89WK6JF', 'B0D89PMKKP', 'B0D7X1634D', 'B0D7V3W7D1', 'B0CYT3R89Z', 'B0CY7P61VD', 'B0CQ8B9PZM', 'B0CNK1SV4P', 'B0CF4K1G4R', 'B0CF4JJXHY', 'B0CF4BJ42D', 'B0C6T346MQ', 'B0BX2KDVMY', 'B0BR4YWSF9', 'B0BR4XHP5Z', 'B09Z68FK4Q', 'B09SL3PTTM', 'B09JBQZQQL', 'B08PSSRS3C', 'B08G4P4F76', 'B0DRD7T6TQ', 'B0DQXT78DT', 'B0DQXRV47R', 'B0DQXRV18S', 'B0DQXRLK5X', 'B0DQXQNL6Z', 'B0D2KQVS2Y', 'B0CXJC74TK', 'B0CW9JC84B', 'B0CSYBNXWX', 'B0CRHSTGX6', 'B0CPPJTX5C', 'B0CJB9WFHD', 'B0CF9JWKHJ', 'B0BVVYZ6TN', 'B0BND2YKJF', 'B09TRCQNQH', 'B09H5J6YQX', 'B09CNRP5FJ', 'B08BZ9LW9Z', 'B0F54M2147', 'B0F388HQLY', 'B0F1BZNBY6', 'B0F1BXV9WG', 'B0DSD949P4', 'B0DFQ2FP96', 'B0D9YXGFQW', 'B0CP9WVSRY', 'B0CKZ35SJC', 'B0CHYNDX87', 'B0CH66SNFC', 'B0BHSWP8RD', 'B0BGRW6858', 'B0B6JKD25B', 'B0B1LJB3M5', 'B09P3S4SH5', 'B09NLSRHGV', 'B0FVDPV5NS', 'B0FQJ5CDL2', 'B0FLJLWTLV', 'B0FGQ1VP2J', 'B0FD6YL7MM', 'B0FBWP9GJL', 'B0F99RW38N', 'B0F3Y3M538', 'B0F27ZM2TG', 'B0F23Y11GD', 'B0F23WZ78P', 'B0F1MY4PF6', 'B0DXKC6H1G', 'B0DQLNTLF4', 'B0DM8DYG77', 'B0DHJNBFVH', 'B0DH1XKG95', 'B0DFYG7C4K', 'B0DFTR1CMN', 'B0DB8FM915', 'B0D5H65VW3', 'B0D3XBW4KT', 'B0CRKJWJ4X', 'B0CPPGX6FQ', 'B0CPPGSBHD', 'B0CL9PVZD1', 'B0C232Z6C6', 'B0C22KBMJC', 'B0BX58MW7N', 'B0B6T3N5MG', 'B0B4S9QYWM', 'B0B4S93T7Q', 'B09R1PMW3J', 'B08MLN92JM', 'B0BHN71FWM', 'B09NKRWXPC', 'B0C89TNVTN', 'B0D1VDMZR1', 'B0DS2QT1YZ', 'B09Y29P5YF', 'B0DBQDSHVZ', 'B0CFF62JY3', 'B0BHPGTWQR', 'B0D4F4D3W2', 'B0F13BRF4V', 'B0D1FXTY99', 'B00KY0LLFO', 'B0B7MJXDZC', 'B0B4DV8NLV', 'B0DJXRFCF7', 'B0BPHMFD7V', 'B0F281ZQWR', 'B0D7V2FNW3', 'B0D57X7KV9', 'B0CJ2SST5Z', 'B0CZ92LPP4', 'B0CG5Z2Z44', 'B0D6T9H5LX', 'B0CQJNR9MP', 'ZXCA', 'B0CJTGDB7232', 'B0CJTGDB7213', 'B0CJTGDB79', 'B0CJTGDB78', 'B0CJTGDB77', 'B0CJCGDB76', 'B0CJCGDB75', 'B0CJCGDB74', 'B0CJCGDB73', 'B0CJCGDB72', 'B0CJCGDB71', 'B0CJCGDB7', 'B0CTCGDB7', 'B0FGTNLTG3', 'WQDASDAS', 'SADAD', 'DFHFGH78979'], 'FR': ['B0FY6JY4BF', 'B0DZNRB5Q1', 'B0DNSKFLGK', 'B0DGLCQDTR', 'B0D9W93869', 'B0CG8RNWL6', 'B0BX94RYT1', 'B0BLN7D2JZ', 'B09WHV9JCJ', 'B0DKX28SNX', 'B0CZCVTMRJ', 'B0CC95H28M', 'B0CC942XSZ', 'B0CC93WW6S', 'B0CC93TDB9', 'B0816GGCFY', 'B0CQY5SM94', 'B0DQTKRNLH', 'B0DCB85F3J', 'B0D8JR3W53', 'B0D2KCRLJ1', 'B0CQK7QWJB', 'B0B9XM29C9', 'B0B5L4HC95', 'B0F9FCT8RD', 'B0BZ8J16JM', 'B0BV1TRMGN', 'B09G68LMB3', 'B0DCRJSMJP', 'B093Y447R2', 'B0D8Y5KWB8', 'B0BJK43Z6X', 'B0DXK7YZ5D', 'B0C232Z6C6', 'B0BZVL6Y9X', 'B0B4S98HLZ', 'B09VPMBMB8', 'B0D17L6YKN'], 'IT': ['B0DTK87KJ5', 'B0DNSNN7NH', 'B0D9W93869', 'B0CLXZHM2G', 'B0CG8RNWL6', 'B0BX94RYT1', 'B0BVM53J3B', 'B0BLN7D2JZ', 'B0F9KVS6Y2', 'B0F8QGHMLL', 'B0CY5KW8RY', 'B0CC94P4H1', 'B0CC94K2HN', 'B0CC922QN8', 'B0C7Q51PL1', 'B0D8JR3W53', 'B0B5L4HC95', 'B0C5C53444', 'B0F5PRVRLF', 'B0BJK43Z6X', 'B09WKFD3G8', 'B08NT2BNGH', 'B0DRV6D214', 'B08QRKHD3C', 'B09JMW3F1R', 'B0CKYHTDJ5', 'B098QFLVDZ', '32EGDFGS4', 'B087JP6PWL89'], 'ES': ['B0D2J11TKY', 'B0CLY2THTY', 'B0D8JS8NPH', 'B0CYGSBXSQ', 'B0CKXMDBN8', 'B0CJ5F9J4Z', 'B0CC95XMD4', 'B0CC93ZNH2', 'B07L281N1M', 'B0DNZ5N7HY', 'B0C7V4BFSZ', 'B0B5L4HC95', 'B0DZCC4B4T', 'B0DZBQ4ZNC', 'B0C5QQFN1G', 'B0BFXD4LYN', 'B0F3122Q81', 'B0BG73XTFC', 'B0CNM269LZ', 'B08QS37RHQ', 'B087JP6PWL89']}, 'skip_asin_details_by_country': {'DE': [{'asin': 'B0FMKM1BYH', 'minimumPrice': ''}, {'asin': 'B0DJT78FNR', 'minimumPrice': ''}, {'asin': 'B0DJLJ73RB', 'minimumPrice': ''}, {'asin': 'B0D6QL2JMY', 'minimumPrice': ''}, {'asin': 'B0CFKLPKF5', 'minimumPrice': ''}, {'asin': 'B09BMWX6Q1', 'minimumPrice': ''}, {'asin': 'B07C4MNWFL', 'minimumPrice': ''}, {'asin': 'B0FHDGLQK7', 'minimumPrice': ''}, {'asin': 'B0FHD9S7K7', 'minimumPrice': ''}, {'asin': 'B0FB2FB6G6', 'minimumPrice': ''}, {'asin': 'B0F9W8VXWQ', 'minimumPrice': ''}, {'asin': 'B0F9W81F2F', 'minimumPrice': ''}, {'asin': 'B0F9W7KLNM', 'minimumPrice': ''}, {'asin': 'B0F2ZJWJNC', 'minimumPrice': ''}, {'asin': 'B0D49F7LM4', 'minimumPrice': ''}, {'asin': 'B0CXSP3PDP', 'minimumPrice': ''}, {'asin': 'B0CLXZHM2G', 'minimumPrice': ''}, {'asin': 'B0CG8RNWL6', 'minimumPrice': ''}, {'asin': 'B0C4SZ8GZW', 'minimumPrice': ''}, {'asin': 'B0BVM53J3B', 'minimumPrice': ''}, {'asin': 'B0BNHN9N9X', 'minimumPrice': ''}, {'asin': 'B0BMXBNMP5', 'minimumPrice': ''}, {'asin': 'B0BLN7D2JZ', 'minimumPrice': ''}, {'asin': 'B09MYVN5YK', 'minimumPrice': ''}, {'asin': 'B09MBNG7P4', 'minimumPrice': ''}, {'asin': 'B09MBNG7P4', 'minimumPrice': '30.28'}, {'asin': 'B0DXTSTZC6', 'minimumPrice': ''}, {'asin': 'B0D25871WL', 'minimumPrice': ''}, {'asin': 'B0CL69XRTY', 'minimumPrice': ''}, {'asin': 'B0CKXMDBN8', 'minimumPrice': ''}, {'asin': 'B0CGDF2G8V', 'minimumPrice': ''}, {'asin': 'B0CFTGXVYF', 'minimumPrice': ''}, {'asin': 'B0CFT6XPPD', 'minimumPrice': ''}, {'asin': 'B09YXTN8JP', 'minimumPrice': ''}, {'asin': 'B0DHX32XJH', 'minimumPrice': ''}, {'asin': 'B0DHL7FQJM', 'minimumPrice': ''}, {'asin': 'B0DHL63M79', 'minimumPrice': ''}, {'asin': 'B0CWXYY74V', 'minimumPrice': ''}, {'asin': 'B0CWXYRGZW', 'minimumPrice': ''}, {'asin': 'B0CPLR6YHB', 'minimumPrice': ''}, {'asin': 'B0BXP4RC25', 'minimumPrice': ''}, {'asin': 'B0BFRRZDCH', 'minimumPrice': ''}, {'asin': 'B0B65R3N47', 'minimumPrice': ''}, {'asin': 'B0FB2FB6G6', 'minimumPrice': ''}, {'asin': 'B0F36ZSWTQ', 'minimumPrice': ''}, {'asin': 'B0DT1DYWC6', 'minimumPrice': ''}, {'asin': 'B0DNZ5WX1L', 'minimumPrice': ''}, {'asin': 'B0DNZ5N7HY', 'minimumPrice': ''}, {'asin': 'B0DCJJ3PCM', 'minimumPrice': ''}, {'asin': 'B0D8JV9MB9', 'minimumPrice': ''}, {'asin': 'B0D2KCRLJ1', 'minimumPrice': ''}, {'asin': 'B0CRVRDS8C', 'minimumPrice': ''}, {'asin': 'B0CQK7QWJB', 'minimumPrice': ''}, {'asin': 'B0CQK5SRXW', 'minimumPrice': ''}, {'asin': 'B0BCL2DLPC', 'minimumPrice': ''}, {'asin': 'B0B9JBHPFY', 'minimumPrice': ''}, {'asin': 'B09TVY4V8Z', 'minimumPrice': ''}, {'asin': 'B0FJBD6Q3D', 'minimumPrice': ''}, {'asin': 'B0DG8LQLXZ', 'minimumPrice': ''}, {'asin': 'B0CD7Q1BX3', 'minimumPrice': ''}, {'asin': 'B0BV1SR48Y', 'minimumPrice': ''}, {'asin': 'B0F29CFJJ9', 'minimumPrice': '26.70'}, {'asin': 'B0DSL6PKR7', 'minimumPrice': '8.80'}, {'asin': 'B0CPV21W4L', 'minimumPrice': '21.87'}, {'asin': 'B0CNQZ7FXY', 'minimumPrice': '74.46'}, {'asin': 'B0CLY9XT5M', 'minimumPrice': '19.72'}, {'asin': 'B0CGTMZ8GP', 'minimumPrice': '33.44'}, {'asin': 'B0CF881PG4', 'minimumPrice': '31.82'}, {'asin': 'B0CF4K1G4R', 'minimumPrice': '31.44'}, {'asin': 'B0CB5T79XG', 'minimumPrice': '16.59'}, {'asin': 'B0C73PQ9KM', 'minimumPrice': '20.92'}, {'asin': 'B0C28TBN79', 'minimumPrice': '12.70'}, {'asin': 'B09T31ZRJF', 'minimumPrice': '35.64'}, {'asin': 'B01LBOYWNO', 'minimumPrice': '11.21'}, {'asin': 'B0DDTB25YZ', 'minimumPrice': ''}, {'asin': 'B0D1Q8GL1Y', 'minimumPrice': ''}, {'asin': 'B0CW9JC84B', 'minimumPrice': ''}, {'asin': 'B0CLGJG36H', 'minimumPrice': ''}, {'asin': 'B0CF9JWKHJ', 'minimumPrice': ''}, {'asin': 'B0C2J3V92Q', 'minimumPrice': ''}, {'asin': 'B0BVVYZ6TN', 'minimumPrice': ''}, {'asin': 'B0B8J8VF7C', 'minimumPrice': ''}, {'asin': 'B0B4BFVZD1', 'minimumPrice': ''}, {'asin': 'B09R1CPKVX', 'minimumPrice': ''}, {'asin': 'B0924BNVH2', 'minimumPrice': ''}, {'asin': 'B0F54M2147', 'minimumPrice': ''}, {'asin': 'B0F1BZNBY6', 'minimumPrice': ''}, {'asin': 'B0F1BXV9WG', 'minimumPrice': ''}, {'asin': 'B0DC957VHC', 'minimumPrice': ''}, {'asin': 'B0D8778SZB', 'minimumPrice': ''}, {'asin': 'B0CP9WVSRY', 'minimumPrice': ''}, {'asin': 'B0CKNQP1PT', 'minimumPrice': ''}, {'asin': 'B0CJ4PW758', 'minimumPrice': ''}, {'asin': 'B0BYFD87C6', 'minimumPrice': ''}, {'asin': 'B0B492K9KT', 'minimumPrice': ''}, {'asin': 'B09968XMC7', 'minimumPrice': ''}, {'asin': 'B0FGJ8RCW1', 'minimumPrice': '12.09'}, {'asin': 'B0FGJ4WK8B', 'minimumPrice': '19.77'}, {'asin': 'B0FFMYGWHP', 'minimumPrice': '34.02'}, {'asin': 'B0FD3DLFKL', 'minimumPrice': '14.13'}, {'asin': 'B0FBWRWXG2', 'minimumPrice': '10.53'}, {'asin': 'B0F99RW38N', 'minimumPrice': '14.21'}, {'asin': 'B0F62LZ4G3', 'minimumPrice': '19.95'}, {'asin': 'B0F629FLVV', 'minimumPrice': '22.62'}, {'asin': 'B0F2N88DS9', 'minimumPrice': '18.43'}, {'asin': 'B0F23Y11GD', 'minimumPrice': '14.54'}, {'asin': 'B0F1YV8T2S', 'minimumPrice': '10.38'}, {'asin': 'B0DXK9PR5X', 'minimumPrice': '18.44'}, {'asin': 'B0DRV7QZ85', 'minimumPrice': '17.72'}, {'asin': 'B0DRV7LN4V', 'minimumPrice': '18.91'}, {'asin': 'B0DR4QYC2M', 'minimumPrice': '15.46'}, {'asin': 'B0D5QL869M', 'minimumPrice': '31.89'}, {'asin': 'B0D41VK3YL', 'minimumPrice': '15.94'}, {'asin': 'B0D3XBW4KT', 'minimumPrice': '26.18'}, {'asin': 'B0D2KW1ZRL', 'minimumPrice': '32.36'}, {'asin': 'B0CPPC6PDW', 'minimumPrice': '27.00'}, {'asin': 'B0CHVPSJ61', 'minimumPrice': '31.30'}, {'asin': 'B0C5C1V5JD', 'minimumPrice': '33.84'}, {'asin': 'B0C232Z6C6', 'minimumPrice': '42.55'}, {'asin': 'B0C22KBMJC', 'minimumPrice': '35.85'}, {'asin': 'B0BZVL6Y9X', 'minimumPrice': '50.46'}, {'asin': 'B0BX58MW7N', 'minimumPrice': '26.73'}, {'asin': 'B0B9M86GMC', 'minimumPrice': '15.93'}, {'asin': 'B08DQVJ2VB', 'minimumPrice': '37.30'}, {'asin': 'B07WKYLJ3T', 'minimumPrice': '64.75'}, {'asin': 'B092D7P9BP', 'minimumPrice': '28.12'}, {'asin': 'B0F9W2MZJY', 'minimumPrice': '77.28'}, {'asin': 'B09KXV2C3T', 'minimumPrice': '27.74'}, {'asin': 'B092D7TM65', 'minimumPrice': '29.44'}, {'asin': 'B0CR3P2F5L', 'minimumPrice': '47.54'}, {'asin': 'B0BWCSCYFL', 'minimumPrice': '45.18'}, {'asin': 'B08JLW8S3Y', 'minimumPrice': '28.56'}, {'asin': 'B0D4H73BJH', 'minimumPrice': '19.57'}, {'asin': 'B08D77WTYG', 'minimumPrice': '30.35'}, {'asin': 'B08D73XW2J', 'minimumPrice': '31.35'}, {'asin': 'B09H4RB4ZL', 'minimumPrice': '25.08'}, {'asin': 'B09WMQ29GH', 'minimumPrice': '29.45'}, {'asin': 'B0DJ2M2RYC', 'minimumPrice': '13.87'}, {'asin': 'B0BGF2QCKT', 'minimumPrice': '35.52'}, {'asin': 'B0DS6FC8M7', 'minimumPrice': '14.94'}, {'asin': 'B098QFLVDZ', 'minimumPrice': '66.04'}, {'asin': 'B0DMD16GTD', 'minimumPrice': '21.90'}, {'asin': 'B0CNVLLQ3J', 'minimumPrice': '42.27'}, {'asin': 'B0CP3JZ1P5', 'minimumPrice': '37.09'}, {'asin': 'B0C1GR4K6W', 'minimumPrice': '21.71'}, {'asin': 'B0CBM792D2', 'minimumPrice': '17.03'}, {'asin': 'B09NJK6K5T', 'minimumPrice': '22.51'}, {'asin': 'B0D8Q5MK31', 'minimumPrice': '21.37'}, {'asin': 'B0CYSCV19T', 'minimumPrice': '32.71'}, {'asin': 'B0C5D5XPLJ', 'minimumPrice': '50.72'}, {'asin': 'B09R3NFGH2', 'minimumPrice': '16.51'}, {'asin': 'B09BG1QD9M', 'minimumPrice': '23.84'}, {'asin': 'B092QY1823', 'minimumPrice': '16.86'}, {'asin': 'B0C55PGK51', 'minimumPrice': '13.77'}, {'asin': 'B0DRN8MXRG', 'minimumPrice': '29.13'}, {'asin': 'B08152JKFB', 'minimumPrice': '21.98'}, {'asin': 'B09Y1P7GK7', 'minimumPrice': '29.43'}, {'asin': 'B0CG62X5GT', 'minimumPrice': '16.88'}, {'asin': 'B0DHJKKZDD', 'minimumPrice': '17.96'}, {'asin': 'B0DYHZ59YL', 'minimumPrice': '20.74'}, {'asin': 'B0CG8RNWL6', 'minimumPrice': '28.08'}, {'asin': 'B0BLN7D2JZ', 'minimumPrice': '27.15'}, {'asin': 'B0D2D5WS2D', 'minimumPrice': '40.27'}, {'asin': 'B0G6LHVRKG', 'minimumPrice': '23.41'}, {'asin': 'B0DQ53F84K', 'minimumPrice': '53.79'}, {'asin': 'ASDASD', 'minimumPrice': '90.00'}, {'asin': 'B0CJTCGDB7232', 'minimumPrice': '32.00'}, {'asin': 'B0CJTCGDB7213', 'minimumPrice': '23.00'}, {'asin': 'B0CJTCGDB79', 'minimumPrice': '32.00'}, {'asin': 'B0CJTCGDB78', 'minimumPrice': '321.00'}, {'asin': 'B0CJTCGDB77', 'minimumPrice': '32.00'}, {'asin': 'B0CJTCGDB76', 'minimumPrice': '32.00'}, {'asin': 'B0CJTCGDB75', 'minimumPrice': '321.00'}, {'asin': 'B0CJTCGDB74', 'minimumPrice': '21.00'}, {'asin': 'B0CJTCGDB73', 'minimumPrice': '231.00'}, {'asin': 'B0CJTCGDB72', 'minimumPrice': '21.00'}, {'asin': 'B0CJTCGDB71', 'minimumPrice': '20.00'}, {'asin': 'B0CJTCGDB7', 'minimumPrice': '15.00'}, {'asin': '1', 'minimumPrice': '1.00'}, {'asin': 'ASDASD', 'minimumPrice': '50.00'}], 'UK': [{'asin': 'B0FGJD2P9Q', 'minimumPrice': ''}, {'asin': 'B0DKBSWJ93', 'minimumPrice': ''}, {'asin': 'B0DJT78FNR', 'minimumPrice': ''}, {'asin': 'B0DFCR79L5', 'minimumPrice': ''}, {'asin': 'B0DCBJ3WY5', 'minimumPrice': ''}, {'asin': 'B0D9LPW1YB', 'minimumPrice': ''}, {'asin': 'B0D7VDQG19', 'minimumPrice': ''}, {'asin': 'B0CP5K31TL', 'minimumPrice': ''}, {'asin': 'B0CG3RG7RQ', 'minimumPrice': ''}, {'asin': 'B0C8DSPMNC', 'minimumPrice': ''}, {'asin': 'B0B6H8RCHC', 'minimumPrice': ''}, {'asin': 'B08TVWB36K', 'minimumPrice': ''}, {'asin': 'B08FZMZQ11', 'minimumPrice': ''}, {'asin': 'B0G6LHVRKG', 'minimumPrice': ''}, {'asin': 'B0FF36SY6Q', 'minimumPrice': ''}, {'asin': 'B0DYTNBMB2', 'minimumPrice': ''}, {'asin': 'B0DQNLGSMQ', 'minimumPrice': ''}, {'asin': 'B0DNSNN7NH', 'minimumPrice': ''}, {'asin': 'B0DJWHHFBS', 'minimumPrice': ''}, {'asin': 'B0DJHSJ9LS', 'minimumPrice': ''}, {'asin': 'B0D2D5WS2D', 'minimumPrice': ''}, {'asin': 'B0CG8RNWL6', 'minimumPrice': ''}, {'asin': 'B0C5D5XPLJ', 'minimumPrice': ''}, {'asin': 'B09WHYGBSR', 'minimumPrice': ''}, {'asin': 'B09WHV9JCJ', 'minimumPrice': ''}, {'asin': 'B09P4VCL2V', 'minimumPrice': ''}, {'asin': 'B09MYVN5YK', 'minimumPrice': ''}, {'asin': 'B09MBNG7P4', 'minimumPrice': ''}, {'asin': 'B0DM63394K', 'minimumPrice': ''}, {'asin': 'B0D1Q4RR99', 'minimumPrice': ''}, {'asin': 'B0CZD1HLY7', 'minimumPrice': ''}, {'asin': 'B0CWD9R2FS', 'minimumPrice': ''}, {'asin': 'B0CS6WYRFW', 'minimumPrice': ''}, {'asin': 'B0CRVTSQGQ', 'minimumPrice': ''}, {'asin': 'B0CR8FTHYP', 'minimumPrice': ''}, {'asin': 'B0CCB5Q5ZY', 'minimumPrice': ''}, {'asin': 'B0CC94W5G7', 'minimumPrice': ''}, {'asin': 'B0CC948Q8Q', 'minimumPrice': ''}, {'asin': 'B0CC93R18S', 'minimumPrice': ''}, {'asin': 'B0CC92F33P', 'minimumPrice': ''}, {'asin': 'B0BZ4DNWPY', 'minimumPrice': ''}, {'asin': 'B0BZ4CMQDL', 'minimumPrice': ''}, {'asin': 'B07Q4RBT32', 'minimumPrice': ''}, {'asin': 'B0DHX32XJH', 'minimumPrice': ''}, {'asin': 'B0DHX1HR7X', 'minimumPrice': ''}, {'asin': 'B0DHTT1X71', 'minimumPrice': ''}, {'asin': 'B0DHTRLQ2L', 'minimumPrice': ''}, {'asin': 'B0DHL7FQJM', 'minimumPrice': ''}, {'asin': 'B0D3V1BJX9', 'minimumPrice': ''}, {'asin': 'B0D3TZ45C3', 'minimumPrice': ''}, {'asin': 'B0D2SDNYS5', 'minimumPrice': ''}, {'asin': 'B0CQY5SM94', 'minimumPrice': ''}, {'asin': 'B0CQLN2FC1', 'minimumPrice': ''}, {'asin': 'B0CQF6W2JT', 'minimumPrice': ''}, {'asin': 'B0BY85GDF5', 'minimumPrice': ''}, {'asin': 'B0BY82BRTZ', 'minimumPrice': ''}, {'asin': 'B0B73K6QZQ', 'minimumPrice': ''}, {'asin': 'B0B4MDDD7D', 'minimumPrice': ''}, {'asin': 'B0F1X5Q9Q6', 'minimumPrice': ''}, {'asin': 'B0DYHPWTVJ', 'minimumPrice': ''}, {'asin': 'B0DQNJPS5M', 'minimumPrice': ''}, {'asin': 'B0DQ4B5SF7', 'minimumPrice': ''}, {'asin': 'B0DNZ5WX1L', 'minimumPrice': ''}, {'asin': 'B0DKX28SNX', 'minimumPrice': ''}, {'asin': 'B0DHVTGXPD', 'minimumPrice': ''}, {'asin': 'B0DHDBN98L', 'minimumPrice': ''}, {'asin': 'B0DFXRP8X1', 'minimumPrice': ''}, {'asin': 'B0DFGPGXY6', 'minimumPrice': ''}, {'asin': 'B0D8JV9MB9', 'minimumPrice': ''}, {'asin': 'B0D2KCRLJ1', 'minimumPrice': ''}, {'asin': 'B0CW63X5XY', 'minimumPrice': ''}, {'asin': 'B0CRVRDS8C', 'minimumPrice': ''}, {'asin': 'B0CRHWLDY4', 'minimumPrice': ''}, {'asin': 'B0CLZBR5CM', 'minimumPrice': ''}, {'asin': 'B0CL67FJFL', 'minimumPrice': ''}, {'asin': 'B0CG2C89ZZ', 'minimumPrice': ''}, {'asin': 'B0BP7YMCXH', 'minimumPrice': ''}, {'asin': 'B0BM8Y94QC', 'minimumPrice': ''}, {'asin': 'B0BJKBRTK7', 'minimumPrice': ''}, {'asin': 'B0BCL2DLPC', 'minimumPrice': ''}, {'asin': 'B0B6PSLTPF', 'minimumPrice': ''}, {'asin': 'B0B6PS4RQ1', 'minimumPrice': ''}, {'asin': 'B0B5L4HC95', 'minimumPrice': ''}, {'asin': 'B08ZT1PJ2K', 'minimumPrice': ''}, {'asin': 'B0FGQ31VWT', 'minimumPrice': ''}, {'asin': 'B0FFT33WRF', 'minimumPrice': ''}, {'asin': 'B0FD3S6DRN', 'minimumPrice': ''}, {'asin': 'B0F2GBR7MP', 'minimumPrice': ''}, {'asin': 'B0F2G5TG4S', 'minimumPrice': ''}, {'asin': 'B0F2FZVS7X', 'minimumPrice': ''}, {'asin': 'B0F2FYW3HN', 'minimumPrice': ''}, {'asin': 'B0F2B6924H', 'minimumPrice': ''}, {'asin': 'B0DSJMMMXN', 'minimumPrice': ''}, {'asin': 'B0DJT68ZM3', 'minimumPrice': ''}, {'asin': 'B0DJT66VG3', 'minimumPrice': ''}, {'asin': 'B0DJT5YJXD', 'minimumPrice': ''}, {'asin': 'B0DCGSFTYX', 'minimumPrice': ''}, {'asin': 'B0D8C6KL4G', 'minimumPrice': ''}, {'asin': 'B0C9H8MJC3', 'minimumPrice': ''}, {'asin': 'B0C85JQNRC', 'minimumPrice': ''}, {'asin': 'B0C5QQFN1G', 'minimumPrice': ''}, {'asin': 'B0BZ8FXRZG', 'minimumPrice': ''}, {'asin': 'B0BS8SW341', 'minimumPrice': ''}, {'asin': 'B0FLVP9N4Y', 'minimumPrice': '6.16'}, {'asin': 'B0F2MPWSCQ', 'minimumPrice': '7.51'}, {'asin': 'B0F29CFJJ9', 'minimumPrice': '21.91'}, {'asin': 'B0DSKC1GQB', 'minimumPrice': '25.52'}, {'asin': 'B0DSCBZSGS', 'minimumPrice': '18.23'}, {'asin': 'B0DSCB329P', 'minimumPrice': '19.00'}, {'asin': 'B0DLNXW8W5', 'minimumPrice': '6.44'}, {'asin': 'B0DJQHVBZZ', 'minimumPrice': '17.62'}, {'asin': 'B0DGCW7WBY', 'minimumPrice': '24.73'}, {'asin': 'B0DFTG85NG', 'minimumPrice': '8.54'}, {'asin': 'B0D99N1DZY', 'minimumPrice': '37.69'}, {'asin': 'B0D8B849BJ', 'minimumPrice': '38.90'}, {'asin': 'B0D89YCGCR', 'minimumPrice': '38.97'}, {'asin': 'B0D89WK6JF', 'minimumPrice': '37.82'}, {'asin': 'B0D89PMKKP', 'minimumPrice': '36.47'}, {'asin': 'B0D7X1634D', 'minimumPrice': '15.56'}, {'asin': 'B0D7V3W7D1', 'minimumPrice': '76.14'}, {'asin': 'B0CYT3R89Z', 'minimumPrice': '68.79'}, {'asin': 'B0CY7P61VD', 'minimumPrice': '32.79'}, {'asin': 'B0CQ8B9PZM', 'minimumPrice': '31.31'}, {'asin': 'B0CNK1SV4P', 'minimumPrice': '16.61'}, {'asin': 'B0CF4K1G4R', 'minimumPrice': '48.07'}, {'asin': 'B0CF4JJXHY', 'minimumPrice': '34.72'}, {'asin': 'B0CF4BJ42D', 'minimumPrice': '24.82'}, {'asin': 'B0C6T346MQ', 'minimumPrice': '11.52'}, {'asin': 'B0BX2KDVMY', 'minimumPrice': '23.14'}, {'asin': 'B0BR4YWSF9', 'minimumPrice': '24.32'}, {'asin': 'B0BR4XHP5Z', 'minimumPrice': '24.71'}, {'asin': 'B09Z68FK4Q', 'minimumPrice': '17.34'}, {'asin': 'B09SL3PTTM', 'minimumPrice': '21.86'}, {'asin': 'B09JBQZQQL', 'minimumPrice': '13.87'}, {'asin': 'B08PSSRS3C', 'minimumPrice': '8.06'}, {'asin': 'B08G4P4F76', 'minimumPrice': '11.61'}, {'asin': 'B0DRD7T6TQ', 'minimumPrice': ''}, {'asin': 'B0DQXT78DT', 'minimumPrice': ''}, {'asin': 'B0DQXRV47R', 'minimumPrice': ''}, {'asin': 'B0DQXRV18S', 'minimumPrice': ''}, {'asin': 'B0DQXRLK5X', 'minimumPrice': ''}, {'asin': 'B0DQXQNL6Z', 'minimumPrice': ''}, {'asin': 'B0D2KQVS2Y', 'minimumPrice': ''}, {'asin': 'B0CXJC74TK', 'minimumPrice': ''}, {'asin': 'B0CW9JC84B', 'minimumPrice': ''}, {'asin': 'B0CSYBNXWX', 'minimumPrice': ''}, {'asin': 'B0CRHSTGX6', 'minimumPrice': ''}, {'asin': 'B0CPPJTX5C', 'minimumPrice': ''}, {'asin': 'B0CJB9WFHD', 'minimumPrice': ''}, {'asin': 'B0CF9JWKHJ', 'minimumPrice': ''}, {'asin': 'B0BVVYZ6TN', 'minimumPrice': ''}, {'asin': 'B0BND2YKJF', 'minimumPrice': ''}, {'asin': 'B09TRCQNQH', 'minimumPrice': ''}, {'asin': 'B09H5J6YQX', 'minimumPrice': ''}, {'asin': 'B09CNRP5FJ', 'minimumPrice': ''}, {'asin': 'B08BZ9LW9Z', 'minimumPrice': ''}, {'asin': 'B0F54M2147', 'minimumPrice': ''}, {'asin': 'B0F388HQLY', 'minimumPrice': ''}, {'asin': 'B0F1BZNBY6', 'minimumPrice': ''}, {'asin': 'B0F1BXV9WG', 'minimumPrice': ''}, {'asin': 'B0DSD949P4', 'minimumPrice': ''}, {'asin': 'B0DFQ2FP96', 'minimumPrice': ''}, {'asin': 'B0D9YXGFQW', 'minimumPrice': ''}, {'asin': 'B0CP9WVSRY', 'minimumPrice': ''}, {'asin': 'B0CKZ35SJC', 'minimumPrice': ''}, {'asin': 'B0CHYNDX87', 'minimumPrice': ''}, {'asin': 'B0CH66SNFC', 'minimumPrice': ''}, {'asin': 'B0BHSWP8RD', 'minimumPrice': ''}, {'asin': 'B0BGRW6858', 'minimumPrice': ''}, {'asin': 'B0B6JKD25B', 'minimumPrice': ''}, {'asin': 'B0B1LJB3M5', 'minimumPrice': ''}, {'asin': 'B09P3S4SH5', 'minimumPrice': ''}, {'asin': 'B09NLSRHGV', 'minimumPrice': ''}, {'asin': 'B0FVDPV5NS', 'minimumPrice': '16.54'}, {'asin': 'B0FQJ5CDL2', 'minimumPrice': '16.44'}, {'asin': 'B0FLJLWTLV', 'minimumPrice': '14.91'}, {'asin': 'B0FGQ1VP2J', 'minimumPrice': '18.19'}, {'asin': 'B0FD6YL7MM', 'minimumPrice': '10.10'}, {'asin': 'B0FBWP9GJL', 'minimumPrice': '11.34'}, {'asin': 'B0F99RW38N', 'minimumPrice': '21.47'}, {'asin': 'B0F3Y3M538', 'minimumPrice': '16.85'}, {'asin': 'B0F27ZM2TG', 'minimumPrice': '15.78'}, {'asin': 'B0F23Y11GD', 'minimumPrice': '16.44'}, {'asin': 'B0F23WZ78P', 'minimumPrice': '12.64'}, {'asin': 'B0F1MY4PF6', 'minimumPrice': '5.96'}, {'asin': 'B0DXKC6H1G', 'minimumPrice': '16.49'}, {'asin': 'B0DQLNTLF4', 'minimumPrice': '7.20'}, {'asin': 'B0DM8DYG77', 'minimumPrice': '13.80'}, {'asin': 'B0DHJNBFVH', 'minimumPrice': '11.19'}, {'asin': 'B0DH1XKG95', 'minimumPrice': '19.34'}, {'asin': 'B0DFYG7C4K', 'minimumPrice': '10.85'}, {'asin': 'B0DFTR1CMN', 'minimumPrice': '15.79'}, {'asin': 'B0DB8FM915', 'minimumPrice': '24.17'}, {'asin': 'B0D5H65VW3', 'minimumPrice': '9.83'}, {'asin': 'B0D3XBW4KT', 'minimumPrice': '19.21'}, {'asin': 'B0CRKJWJ4X', 'minimumPrice': '17.66'}, {'asin': 'B0CPPGX6FQ', 'minimumPrice': '40.53'}, {'asin': 'B0CPPGSBHD', 'minimumPrice': '32.58'}, {'asin': 'B0CL9PVZD1', 'minimumPrice': '24.79'}, {'asin': 'B0C232Z6C6', 'minimumPrice': '32.87'}, {'asin': 'B0C22KBMJC', 'minimumPrice': '25.72'}, {'asin': 'B0BX58MW7N', 'minimumPrice': '22.04'}, {'asin': 'B0B6T3N5MG', 'minimumPrice': '15.33'}, {'asin': 'B0B4S9QYWM', 'minimumPrice': '14.36'}, {'asin': 'B0B4S93T7Q', 'minimumPrice': '14.57'}, {'asin': 'B09R1PMW3J', 'minimumPrice': '14.07'}, {'asin': 'B08MLN92JM', 'minimumPrice': '9.63'}, {'asin': 'B0BHN71FWM', 'minimumPrice': '18.09'}, {'asin': 'B09NKRWXPC', 'minimumPrice': '12.53'}, {'asin': 'B0C89TNVTN', 'minimumPrice': '39.64'}, {'asin': 'B0D1VDMZR1', 'minimumPrice': '21.46'}, {'asin': 'B0DS2QT1YZ', 'minimumPrice': '23.49'}, {'asin': 'B09Y29P5YF', 'minimumPrice': '20.23'}, {'asin': 'B0DBQDSHVZ', 'minimumPrice': '31.03'}, {'asin': 'B0CFF62JY3', 'minimumPrice': '21.88'}, {'asin': 'B0BHPGTWQR', 'minimumPrice': '28.06'}, {'asin': 'B0D4F4D3W2', 'minimumPrice': '18.17'}, {'asin': 'B0F13BRF4V', 'minimumPrice': '14.89'}, {'asin': 'B0D1FXTY99', 'minimumPrice': '14.36'}, {'asin': 'B00KY0LLFO', 'minimumPrice': '16.48'}, {'asin': 'B0B7MJXDZC', 'minimumPrice': '18.28'}, {'asin': 'B0B4DV8NLV', 'minimumPrice': '18.09'}, {'asin': 'B0DJXRFCF7', 'minimumPrice': '34.13'}, {'asin': 'B0BPHMFD7V', 'minimumPrice': '17.16'}, {'asin': 'B0F281ZQWR', 'minimumPrice': '24.51'}, {'asin': 'B0D7V2FNW3', 'minimumPrice': '49.89'}, {'asin': 'B0D57X7KV9', 'minimumPrice': '15.04'}, {'asin': 'B0CJ2SST5Z', 'minimumPrice': '21.25'}, {'asin': 'B0CZ92LPP4', 'minimumPrice': '8.74'}, {'asin': 'B0CG5Z2Z44', 'minimumPrice': '13.24'}, {'asin': 'B0D6T9H5LX', 'minimumPrice': '14.42'}, {'asin': 'B0CQJNR9MP', 'minimumPrice': '10.64'}, {'asin': 'ZXCA', 'minimumPrice': '60.00'}, {'asin': 'B0CJTGDB7232', 'minimumPrice': '854.00'}, {'asin': 'B0CJTGDB7213', 'minimumPrice': '54.00'}, {'asin': 'B0CJTGDB79', 'minimumPrice': '54.00'}, {'asin': 'B0CJTGDB78', 'minimumPrice': '54.00'}, {'asin': 'B0CJTGDB77', 'minimumPrice': '4.00'}, {'asin': 'B0CJCGDB76', 'minimumPrice': '458.00'}, {'asin': 'B0CJCGDB75', 'minimumPrice': '45.00'}, {'asin': 'B0CJCGDB74', 'minimumPrice': '45.00'}, {'asin': 'B0CJCGDB73', 'minimumPrice': '485.00'}, {'asin': 'B0CJCGDB72', 'minimumPrice': '545.00'}, {'asin': 'B0CJCGDB71', 'minimumPrice': '545.00'}, {'asin': 'B0CJCGDB7', 'minimumPrice': '854.00'}, {'asin': 'B0CTCGDB7', 'minimumPrice': '84.00'}, {'asin': 'B0FGTNLTG3', 'minimumPrice': '56.00'}, {'asin': 'B0D57X7KV9', 'minimumPrice': '11.07'}, {'asin': 'B0D1VDMZR1', 'minimumPrice': '23.73'}, {'asin': 'B0DS2QT1YZ', 'minimumPrice': '19.36'}, {'asin': 'WQDASDAS', 'minimumPrice': '60.00'}, {'asin': 'B0BHPGTWQR', 'minimumPrice': '28.48'}, {'asin': 'SADAD', 'minimumPrice': '50.00'}, {'asin': 'DFHFGH78979', 'minimumPrice': '34.00'}], 'FR': [{'asin': 'B0FY6JY4BF', 'minimumPrice': ''}, {'asin': 'B0DZNRB5Q1', 'minimumPrice': ''}, {'asin': 'B0DNSKFLGK', 'minimumPrice': ''}, {'asin': 'B0DGLCQDTR', 'minimumPrice': ''}, {'asin': 'B0D9W93869', 'minimumPrice': ''}, {'asin': 'B0CG8RNWL6', 'minimumPrice': ''}, {'asin': 'B0BX94RYT1', 'minimumPrice': ''}, {'asin': 'B0BLN7D2JZ', 'minimumPrice': ''}, {'asin': 'B09WHV9JCJ', 'minimumPrice': ''}, {'asin': 'B0DKX28SNX', 'minimumPrice': ''}, {'asin': 'B0CZCVTMRJ', 'minimumPrice': ''}, {'asin': 'B0CC95H28M', 'minimumPrice': ''}, {'asin': 'B0CC942XSZ', 'minimumPrice': ''}, {'asin': 'B0CC93WW6S', 'minimumPrice': ''}, {'asin': 'B0CC93TDB9', 'minimumPrice': ''}, {'asin': 'B0816GGCFY', 'minimumPrice': ''}, {'asin': 'B0CQY5SM94', 'minimumPrice': ''}, {'asin': 'B0DQTKRNLH', 'minimumPrice': ''}, {'asin': 'B0DCB85F3J', 'minimumPrice': ''}, {'asin': 'B0D8JR3W53', 'minimumPrice': ''}, {'asin': 'B0D2KCRLJ1', 'minimumPrice': ''}, {'asin': 'B0CQK7QWJB', 'minimumPrice': ''}, {'asin': 'B0B9XM29C9', 'minimumPrice': ''}, {'asin': 'B0B5L4HC95', 'minimumPrice': ''}, {'asin': 'B0F9FCT8RD', 'minimumPrice': ''}, {'asin': 'B0BZ8J16JM', 'minimumPrice': ''}, {'asin': 'B0BV1TRMGN', 'minimumPrice': ''}, {'asin': 'B09G68LMB3', 'minimumPrice': ''}, {'asin': 'B0DCRJSMJP', 'minimumPrice': '10.72'}, {'asin': 'B093Y447R2', 'minimumPrice': '79.17'}, {'asin': 'B0D8Y5KWB8', 'minimumPrice': ''}, {'asin': 'B0BJK43Z6X', 'minimumPrice': ''}, {'asin': 'B0DXK7YZ5D', 'minimumPrice': '15.06'}, {'asin': 'B0C232Z6C6', 'minimumPrice': '48.25'}, {'asin': 'B0BZVL6Y9X', 'minimumPrice': '54.37'}, {'asin': 'B0B4S98HLZ', 'minimumPrice': '14.61'}, {'asin': 'B09VPMBMB8', 'minimumPrice': '18.01'}, {'asin': 'B0D17L6YKN', 'minimumPrice': '16.95'}], 'IT': [{'asin': 'B0DTK87KJ5', 'minimumPrice': ''}, {'asin': 'B0DNSNN7NH', 'minimumPrice': ''}, {'asin': 'B0D9W93869', 'minimumPrice': ''}, {'asin': 'B0CLXZHM2G', 'minimumPrice': ''}, {'asin': 'B0CG8RNWL6', 'minimumPrice': ''}, {'asin': 'B0BX94RYT1', 'minimumPrice': ''}, {'asin': 'B0BVM53J3B', 'minimumPrice': ''}, {'asin': 'B0BLN7D2JZ', 'minimumPrice': ''}, {'asin': 'B0F9KVS6Y2', 'minimumPrice': ''}, {'asin': 'B0F8QGHMLL', 'minimumPrice': ''}, {'asin': 'B0CY5KW8RY', 'minimumPrice': ''}, {'asin': 'B0CC94P4H1', 'minimumPrice': ''}, {'asin': 'B0CC94K2HN', 'minimumPrice': ''}, {'asin': 'B0CC922QN8', 'minimumPrice': ''}, {'asin': 'B0C7Q51PL1', 'minimumPrice': ''}, {'asin': 'B0D8JR3W53', 'minimumPrice': ''}, {'asin': 'B0B5L4HC95', 'minimumPrice': ''}, {'asin': 'B0C5C53444', 'minimumPrice': ''}, {'asin': 'B0F5PRVRLF', 'minimumPrice': ''}, {'asin': 'B0BJK43Z6X', 'minimumPrice': ''}, {'asin': 'B09WKFD3G8', 'minimumPrice': ''}, {'asin': 'B08NT2BNGH', 'minimumPrice': ''}, {'asin': 'B0DRV6D214', 'minimumPrice': '20.50'}, {'asin': 'B08QRKHD3C', 'minimumPrice': '38.36'}, {'asin': 'B09JMW3F1R', 'minimumPrice': '28.64'}, {'asin': 'B0CKYHTDJ5', 'minimumPrice': '24.05'}, {'asin': 'B098QFLVDZ', 'minimumPrice': '77.89'}, {'asin': '32EGDFGS4', 'minimumPrice': '56.00'}, {'asin': 'B087JP6PWL89', 'minimumPrice': ''}], 'ES': [{'asin': 'B0D2J11TKY', 'minimumPrice': ''}, {'asin': 'B0CLY2THTY', 'minimumPrice': ''}, {'asin': 'B0D8JS8NPH', 'minimumPrice': ''}, {'asin': 'B0CYGSBXSQ', 'minimumPrice': ''}, {'asin': 'B0CKXMDBN8', 'minimumPrice': ''}, {'asin': 'B0CJ5F9J4Z', 'minimumPrice': ''}, {'asin': 'B0CC95XMD4', 'minimumPrice': ''}, {'asin': 'B0CC93ZNH2', 'minimumPrice': ''}, {'asin': 'B07L281N1M', 'minimumPrice': ''}, {'asin': 'B0DNZ5N7HY', 'minimumPrice': ''}, {'asin': 'B0C7V4BFSZ', 'minimumPrice': ''}, {'asin': 'B0B5L4HC95', 'minimumPrice': ''}, {'asin': 'B0DZCC4B4T', 'minimumPrice': ''}, {'asin': 'B0DZBQ4ZNC', 'minimumPrice': ''}, {'asin': 'B0C5QQFN1G', 'minimumPrice': ''}, {'asin': 'B0BFXD4LYN', 'minimumPrice': '33.02'}, {'asin': 'B0F3122Q81', 'minimumPrice': ''}, {'asin': 'B0BG73XTFC', 'minimumPrice': ''}, {'asin': 'B0CNM269LZ', 'minimumPrice': '9.24'}, {'asin': 'B08QS37RHQ', 'minimumPrice': '42.40'}, {'asin': 'B087JP6PWL89', 'minimumPrice': ''}]}, 'minimum_price_by_country_and_asin': {}, 'skip_asin_delete_policy': {'enabled': True, 'mode': 'DELETE_WHEN_PRICE_BELOW_MINIMUM', 'deleteWhenPriceBelowMinimum': True, 'compareField': 'price', 'thresholdField': 'minimumPrice', 'target': 'skip_asin', 'source': 'frontend-price-track'}, 'delete_skip_asin_when_price_below_minimum': True, 'deleteSkipAsinWhenPriceBelowMinimum': True, 'asin_rows_by_country': {}, 'taskId': 5658, 'resultId': 7627, 'shopName': '郭锋滨', 'shopId': '27769139291498', 'platformName': '亚马逊', 'companyName': '尾号5578的公司115', 'shopMallName': '', 'matchStatus': 'MATCHED', 'matchMessage': None, 'outputFilename': None, 'downloadUrl': None, 'taskStatus': 'RUNNING', 'loopRunId': 235, 'roundIndex': 1}}
price_cls = PriceTask(user_info)
price_cls.process_task(task_data)