def save_to_paytm(sku_info): CB = ChinaBrandResource() try: category = int(sku_info.get('lazada_cid', 99999)) except: category = 99999 lz_sku_spec = CB.get_sku_specification(sku_info['goods_desc']) p_sku = "CM01-" + sku_info['sku'] p_name = get_clean_title(sku_info, lz_sku_spec, category) p_weight = float(sku_info['ship_weight']) p_price = round(177.3 * float(sku_info['price']) + 118.2+675.4 * p_weight + 101.3*int((p_weight/0.5)+0.5), 2) p_mrp = round(p_price/0.3) p_color = sku_info['color'] p_size = sku_info['size'] p_psku = p_sku[:-2] p_imgs = ",".join([img.replace("https://glodimg.chinabrands.com", "http://cbimg.chaotiinfo.com") for img in sku_info['original_img']]) p_desc = get_clean_desc(sku_info['goods_desc']) p_rpi = '34' p_mdt = '12' # p_gender = "Women" return [p_sku, p_name, p_mrp, p_price, p_color, p_size, p_psku, p_weight*1000, p_imgs, p_desc, p_rpi, p_mdt]
def create_product_from_CB_Sub(self, category, cb_product_info): #为啥category变成了浮点型 category = int(category) CB = ChinaBrandResource() try: #下一句是我注释掉的 #float(cb_product_info[0]['size']) # if size is pure number do not use that if 'pant' in cb_product_info[0]['title'].lower(): return except: pass test_p = self.get_account_id() print(test_p) country = test_p[0:2] #country = self.get_account_id()[0:2] #country == MY? cb_product = cb_product_info[0] #cb_product大体等于从cb抓取出来的一系列数据了 lz_description = cb_product['goods_desc'] # replace desc image to lazada # for desc_image in cb_product['desc_img']: # lz_description = lz_description.replace( # desc_image, self.upload_image(desc_image)) lz_short_description = CB.get_li_feature(lz_description) if cb_product['color']: short_desc_extra = "<ul><li><strong>It is %s!</strong></li>" % cb_product[ 'color'] # 若cb中抓取到color则在title中补充到颜色属性 cb_product['title'] = cb_product[ 'title'] + "(%s)" % cb_product['color'].replace("&", "and") else: short_desc_extra = "there is no color from cb" #新添的 # if cb_product['size']: # short_desc_extra += "<li>Its size is %s!</strong></li>" % cb_product['size'] # 在简短描述里面加上颜色属性 lz_short_description = lz_short_description.replace( '<ul>', short_desc_extra) cb_product['color'] = self.adapt_color(cb_product['color']) lz_brand = cb_product['goods_brand'] if self.check_brand_exist( cb_product['goods_brand']) else 'OEM' # 得到Package Content放入lz_sku_spec中 lz_sku_spec = CB.get_sku_specification(lz_description) cb_product['title'] = self.get_clean_title(cb_product, lz_sku_spec, category) print("----------------------\n\n%s\n\n------------------" % cb_product['title']) if country != "MY": cb_product['title'] += " - intl" # add statics pictrure to description #对html来说,<, > , ?, & 和引号等有特殊意义 , 例如<a>表示连接 ,如果你确实需要在网页显示 '<a>'这一个东东,就必须escape(转义),变成 '& lt;a& gt;' lz_product = { "category": category, "name": cb_product['title'], "brand": lz_brand, "model": int(time.time()), "color": cb_product['color'], "description": html.escape( lz_description.replace('max-width:1000px', 'max-width:100%')), "short_description": html.escape(lz_short_description) } product_schema = etree.XML("""<Request> <Product> <PrimaryCategory>{category}</PrimaryCategory> <SPUId></SPUId> <Attributes> <name>{name}</name> <name_ms>{name}</name_ms> <color_family>{color}</color_family> <short_description>{short_description}</short_description> <brand>{brand}</brand> <model>{model}</model> <warranty_type>No Warranty</warranty_type> <description>{description}</description> </Attributes> <Skus id="skus"> </Skus> </Product> </Request> """.format(**lz_product)) variation = True c_skus = [] for cb_sku in cb_product_info: # c_skus used for complete_sku意思是加上c_skus[]之后表示已经完成sku了? c_skus.append(cb_sku['sku']) cb_sku['encrypted_sku'] = self.encrypt_sku(cb_sku['sku']) # package content cb_sku['special_price'] = get_special_price(cb_sku['price'], cb_sku['ship_weight'], country=country) if float(cb_sku['ship_weight']) > 0.5: return cb_sku['price'] = get_sale_price(cb_sku['special_price']) start_date = arrow.now() cb_sku['special_from_date'] = start_date.strftime("%Y-%m-%d") cb_sku['special_to_date'] = start_date.replace( days=+365).strftime("%Y-%m-%d") cb_sku['package_content'] = lz_sku_spec.get( 'Package Content', '1 x see product description') # quantity cb_sku['quantity'] = random.randrange(3, 50) cb_sku['keywords'] = self.get_key_words(cb_sku, category) product_sku = etree.XML("""<Sku> <SellerSku>{encrypted_sku}</SellerSku> <tax_class>default</tax_class> <quantity>{quantity}</quantity> <price>{price}</price> <special_price>{special_price}</special_price> <special_from_date>{special_from_date}</special_from_date> <special_to_date>{special_to_date}</special_to_date> <color_family>{color}</color_family> <model>LA{encrypted_sku}</model> <package_length>{package_length}</package_length> <package_height>{package_height}</package_height> <package_weight>{ship_weight}</package_weight> <package_width>{package_width}</package_width> <package_width>{package_width}</package_width> <package_content>{package_content}</package_content> <std_search_keywords>{keywords}</std_search_keywords> <Images> </Images> <Image></Image> </Sku>""".format(**cb_sku)) # extra SKU attrs # extra_attr_str = get_extra_attrs(category) cattrs = self.get_mandatory_attributes(category) extra_attr = {} for ck, cv in cattrs.items(): if cb_sku['size'] in cv: extra_attr[ck] = cb_sku['size'] elif ck == 'ring_size': if cb_sku['size'] and cb_sku['size'].isdigit(): sku_size = cb_sku['size'] else: cb_sku['title'] = cb_sku[ 'title'] + "(Size:%s)" % cb_sku['size'].replace( "&", "and") product_schema.xpath( "//name")[0].text = cb_sku['title'] sku_size = 'Not Specified' # do not associated product if no size variation = False extra_attr[ck] = sku_size elif ck == 'size': if cb_sku['size']: format_size = re.sub('2', 'X', cb_sku['size']).upper() if category in self.shoes: sku_size = "EU:" + cb_sku['size'] elif format_size in self.__size and format_size in cv: sku_size = 'Int:' + format_size else: cb_sku['title'] = cb_sku[ 'title'] + "(Size:%s)" % cb_sku[ 'size'].replace("&", "and") product_schema.xpath( "//name")[0].text = cb_sku['title'] sku_size = "Int: One size" # do not associated product if no size variation = False else: sku_size = 'Not Specified' variation = False extra_attr[ck] = sku_size else: if 'One Size' in cv: extra_attr[ck] = 'One Size' elif 'Int:One Size' in cv: extra_attr[ck] = 'Int:One Size' elif 'Int: One Size' in cv: extra_attr[ck] = 'Int: One Size' elif 'color' in ck: extra_attr[ck] = 'Multicolor' else: extra_attr[ck] = 'Not Specified' variation = False for tag, tv in extra_attr.items(): new_tag = etree.Element(tag) new_tag.text = str(tv) attr_type = self.check_attrs_type(category, tag) if attr_type == 'sku': product_sku.xpath("//Sku")[0].append(new_tag) else: product_schema.xpath("//Attributes")[0].append(new_tag) # check if image exist mongodb images = self.__mongodb.all_cb_sku.find_one({ "sku": cb_sku["sku"] }).get("limages") if images: self.remove_elements_by_tag(product_sku, 'Images') product_sku.append(etree.XML(images)) else: # image for image_src in cb_sku['original_img'][:8]: image_src = self.upload_image(image_src, strict=True) if not image_src: continue e_image_src = etree.Element("Image") e_image_src.text = image_src product_sku.find("Images").append(e_image_src) # save image to mongodb self.__mongodb.all_cb_sku.update({'sku': cb_sku['sku']}, { "$set": { "limages": etree.tostring(product_sku.find("Images")) } }) if not variation: self.remove_elements_by_tag(product_schema, "Sku") product_schema.xpath("//Skus")[0].append(product_sku) result = self._post("CreateProduct", data=etree.tostring(product_schema)) # if have been upload to lazada save it. if result: self.complete_sku(cb_sku['sku'], 10) else: product_schema.xpath("//Skus")[0].append(product_sku) print("\n\n\n\nthe API model of CreateProduct: \n%s" % product_schema) #import pdb;pdb.set_trace() result = self._post("CreateProduct", data=etree.tostring(product_schema)) # if have been upload to lazada save it. if result: self.complete_sku(c_skus, 10)
class Wish(): def __init__(self): self.___key = b'6946b89c23d2cabbf3be1b5f63b1d41a3de990da' self.__url = 'https://merchant.wish.com/api/v2' config = ConfigParser() config.read('config.ini') self.token = dict(config._sections['WISH']) self.token['client_secret'] = '8a3fdde1f9304cf282a1ebafcdf42898' self.config = config self.CB = ChinaBrandResource() self.__mongodb = pymongo.MongoClient( "mongodb://localhost:55088/").cb_info self.__color = colors self.__forbid_sku = [ "163650601", "164819701", "164787801", "163114002", "159407701", "159470704", "123595401", "123583503", "173235502", "187859601", "187860403", "155817701", "180558905" ] def adapt_color(self, o_color): colors = self.__color pre_color = { c: o_color.lower().find(c.lower()) - len(c) for c in colors if o_color.lower().find(c.lower()) != -1 } if pre_color: return min(pre_color, key=pre_color.get) return 'Multicolor' def get_sku_infos(self, sku): db = pymongo.MongoClient("mongodb://localhost:5/").cb_info all_sku = db.all_cb_sku.find({"sku": {"$regex": "^%s.*" % sku[:-2]}}) if not all_sku.count(): cbt = ChinaBrandTools() main_url = cbt.fetch_cb_product_from_sku(sku) cbt.fetch_product_detail(main_url) all_sku = db.all_cb_sku.find( {"sku": { "$regex": "^%s.*" % sku[:-2] }}) if all_sku.count(): return all_sku @timeout_decorator.timeout(2000) def create_product_from_CB(self, cb_product_info): """ adpter schema: data map """ cb_product_info = self.CB.get_product_info(sku) if not cb_product_info: print("URL %s is not online") return # remove skus before update again skus = [cb for cb in cb_product_info if int(cb['status']) == 1] if not skus and skus[0].get('sku') in self.__forbid_sku: self.complete_sku(sku, -1) return # defaultdict parent_sku = "" for inx, cb_sku in enumerate(skus): if cb_sku.get('quantity_new') > 0: cb_sku['quantity'] = int(random.randint(10, 100)) else: continue category = cb_sku['category'] cb_sku['category'] = category cb_sku['encrypted_sku'] = self.encrypt_sku(cb_sku['sku']) cb_sku['name'] = self.get_clean_title(cb_sku) cb_sku['color'] = self.adapt_color(cb_sku['color']) cb_sku['tags'] = category # self.get_tags(cb_sku['name'], category) cb_sku[ 'special_price'] = 49 #self.get_special_price(cb_sku['price'], self.CB.get_shipping_fee(weight=cb_sku['ship_weight'])) cb_sku[ 'price'] = 89 # self.get_sale_price(cb_sku['special_price']) cb_sku['main_image'] = cb_sku['original_img'][0].replace( 'https', 'http') extra_images = cb_sku['original_img'][1:] + cb_sku['desc_img'] cb_sku['extra_images'] = [ img.replace('https', 'http') for img in extra_images ] cb_sku['parent_sku'] = parent_sku if inx == 0: parent_sku = cb_sku['encrypted_sku'] cb_sku['parent_sku'] = parent_sku cb_sku['desc'] = self.get_clean_desc(cb_sku['goods_desc']) cb_sku['wish_uploaded'] = self.create_product( **cb_sku) or False else: cb_sku['wish_uploaded'] = self.create_variant( **cb_sku) or False # if have been upload to lazada save it. self.complete_sku(cb_sku['sku'], -1) def get_clean_desc(self, desc): text = BeautifulSoup(desc, "lxml") [x.extract() for x in text.findAll('img')] return html2text.html2text(str(text)).replace("**", "") def get_sale_price(self, origin_price): x = random.randint(2, 8) / 10 return round(origin_price / x, 2) def get_special_price(self, origin_price, ship_fee): origin_price = float(origin_price) if origin_price <= 5: x = 1.4 elif (origin_price > 5 and origin_price <= 10): x = 2.6 elif (origin_price > 10 and origin_price <= 20): x = 5 elif (origin_price > 20): return round((origin_price * 1.8 + 1.2 * ship_fee) - 1) return round((origin_price * 1.2 + 1.2 * ship_fee) + x) def get_suggest_tags(self, kw=''): c = requests.post('https://merchant.wish.com/api/contest-tag/search', data={'q': kw}) result = json.loads(c.text) tags = result.get('data', {}).get('tags') if not tags: return [ kw, ] l_tags = [t['tag'] for t in tags] l_tags.sort(key=len) return l_tags def get_tags(self, title="", category=""): c_str = category.lower() lc_str = c_str.split(">") l_tags = lc_str[1:] lendest_c = lc_str[-1].split('&') for endest_c in lendest_c: endest_c = endest_c.strip() if 'women' in c_str or 'woman' in c_str: l_tags.extend(self.get_suggest_tags('womens ' + endest_c)[:3]) elif 'men' in c_str or 'man' in c_str: l_tags.extend(self.get_suggest_tags('mens ' + endest_c)[:3]) else: l_tags.extend(self.get_suggest_tags(endest_c)[:3]) l_tags.append(lc_str[-2].strip()) l_tags.append(self.get_promotion_word() + lc_str[-1]) l_tags.append(" ".join(title.split(" ")[-8:]).strip()) l_tags.extend( self.get_suggest_tags(" ".join( title.split("for")[0].split(" ")[-3:]).strip())[:2]) return ",".join(l_tags) def get_clean_title(self, cb_sku): spec = self.CB.get_sku_specification(cb_sku['goods_desc']) re.sub("%s |%s " % (cb_sku.get('goods_brand'), spec.get('model')), "", cb_sku['title'], flags=re.I) clean_title = self.get_promotion_word() + \ cb_sku['category'].split('>')[-1].strip() + " " + cb_sku['title'] clean_title = re.sub(' +', ' ', clean_title) return clean_title.strip().lower().title() def get_promotion_word(self): words = [ "Fashion", "New", "Save", "More", "Luxury", "The", "High Quality", "Quality", "Sale", "Hot Sale", "Awesome", "Gift", "Nice", "New Arrival", "professional", "Beautiful", "cheap", "discount", "outlet", "wonders" ] return random.choice(words) + " " def complete_sku(self, cb_sku, status): if isinstance(cb_sku, str): cb_sku = [ cb_sku, ] self.__mongodb.all_cb_sku.update_many({'sku': { "$in": cb_sku }}, {"$set": { "wish": status }}, True) def remove_product(self, sku=None): action = '/product/disable' data = { "parent_sku": sku, } result = self._post(action, data=data) print(result) def update_tags(self, sku=None): if not sku: return print(sku) db = pymongo.MongoClient("mongodb://localhost:27017/").cb_info sku_info = db.all_cb_sku.find_one({ "sku": sku.split('-')[-1], "status": 1 }) if not sku_info: self.remove_product(sku=sku) print("no reltive product, remove") return l_tags = db.wish_tags.find_one({"cid": sku_info['cid']}) if not l_tags: print("no reltive tags") return tags = random.choice(l_tags['tags']) print(tags) data = {"parent_sku": sku, "tags": tags} print(self.update_product(**data)) def update_product(self, **kwargs): # update need kwargs key equal wish api keys action = '/product/update' result = self._post(action, data=kwargs) return bool(result) def create_product(self, **kwargs): action = '/product/add' data = { "name": kwargs['name'], "parent_sku": kwargs['parent_sku'], "description": kwargs['desc'], "tags": kwargs['tags'], "sku": kwargs['encrypted_sku'], "inventory": kwargs['quantity'], "price": kwargs['special_price'] + 3, "shipping": 5, "color": kwargs['color'], "size": kwargs['size'], "msrp": kwargs['price'] + 10, "shipping_time": '5-25', "main_image": kwargs['main_image'], "brand": kwargs['goods_brand'], "extra_images": "|".join(kwargs['extra_images'][:19]) } result = self._post(action, data=data) return bool(result) def create_variant(self, **kwargs): action = '/variant/add' data = { "parent_sku": kwargs['parent_sku'], "sku": kwargs['encrypted_sku'], "inventory": kwargs['quantity'], "price": kwargs['special_price'], "shipping": 1, "color": kwargs['color'], "size": kwargs['size'], "msrp": kwargs['price'], "shipping_time": '10-25', "main_image": kwargs['main_image'] } result = self._post(action, data=data) return bool(result) def encrypt_sku(self, sku): return 'COM01-' + str(sku) def remove_empty_elements(self, doc): for element in doc.xpath('//*[not(node())]'): element.getparent().remove(element) def get_access_token(self): data = self.token if datetime.now() > datetime.fromtimestamp(int(data['expiry_time'])): data = self.refresh_token() return data.get('access_token') def refresh_token(self): action = '/oauth/refresh_token' url = self.__url + action data = { k: self.token.get(k) for k in ['refresh_token', 'client_secret', 'client_id'] } data['grant_type'] = 'refresh_token' result = requests.post(url, data=data) result = json.loads(result.text) print(result) new_token = result['data'] new_token.pop("reason", None) config = ConfigParser() config["WISH"] = new_token with open('config.ini', 'w') as configfile: config.write(configfile) return new_token def get_pending_orders(self): action = '/order/get-fulfill' result = self._post(action) return result['data'] def put_order(self, supply, ship_method=None): ship_method = ship_method or 'WISHDLE' orders = self.get_pending_orders() if not orders: return all_order_result = {} for o in orders: o = o['Order'] oadpter = {} oadpter['user_order_sn'] = 'rolandarts' + str(o['order_id']) oadpter['country'] = o['ShippingDetail']['country'] oadpter['firstname'] = o['ShippingDetail']['name'] oadpter['lastname'] = '' oadpter['shipping_method'] = ship_method oadpter['addressline1'] = o['ShippingDetail']['street_address1'] oadpter['city'] = o['ShippingDetail']['city'] oadpter['zip'] = o['ShippingDetail']['zipcode'] oadpter['goods_info'] = [] goods_sn = o['sku'].split('-')[-1] if '187860403' in goods_sn: goods_sn = "187860404" if '181874902' in goods_sn: goods_sn = "181874901" if '17835870' in goods_sn: goods_sn = '178358701' if '20216200' in goods_sn: goods_sn = '202162005' oadpter['goods_info'].append({ 'goods_sn': str(goods_sn), 'goods_number': o['quantity'] }) print(oadpter) result = supply.put_order(**oadpter) print(result) all_order_result.update(result) return all_order_result def _post(self, action, extra_param=None, data=None): data = data or {} # remove empty values data = {k: v for k, v in data.items() if v} url = self.__url + action parameters = {} if extra_param: parameters.update(extra_param) data['access_token'] = self.get_access_token() data['format'] = 'json' result = requests.post(url, params=parameters, data=data) # print(result.text) result = json.loads(result.text) self.__mongodb.wish_result.insert(result) time.sleep(0.2) print(url) return result
def create_product_from_CB_Sub(self, category, cb_product_info): CB = ChinaBrandResource() try: if 'pant' in cb_product_info[0]['title'].lower: return except: pass country = self.get_account_id() country = country[:2] cb_product = cb_product_info[0] lz_description = cb_product['goods_desc'] lz_short_description = CB.get_li_feature(lz_description) if cb_product['color']: short_desc_extra = "<ul><li><strong>It is %s!</strong></li></ul>" % cb_product['color'] cb_product['title'] = cb_product['title'] + "(%s)" % cb_product['color'].replace("&", "and") else: short_desc_extra = "there is no color from cb" lz_short_description = lz_short_description.replace('<ul>', short_desc_extra) cb_product['color'] = self.adapt_color(cb_product['color']) lz_brand = cb_product['goods_brand'] if self.check_brand_exist(cb_product['goods_brand']) else 'OEM' lz_sku_spec = CB.get_sku_specification(lz_description) cb_product['title'] = self.get_clean_title(cb_product, lz_sku_spec, category) print("-------------------\n\n\n%s\n\n\n----------------" % cb_product['title']) if country != "MY": cb_product['title'] += " - init" lz_product = {"category": category, "name": cb_product['title'], "brand": lz_brand, "model": int(time.time()), "color": cb_product['color'], "description": html.escape(lz_description.replace('max-width: 1000px' 'max-width: 100%')) "short_description": html.escape(lz_short_description)} product_schema = etree.XML("""<Request> <product> <PrimaryCategory>{category}</PrimaryCategory> <SPUId></SPUId> <Attributes> <name>{name}</name> <name_ms>{name}</name_ms> <color_famliy>{color}</color_famliy> <short_description>{short_description}</short_description> <brand>{brand}</brand> <model>{model}</model> <warranty_type>No warrenty</warranty_type> </Attributes> <Skus id="skus"> </SKus> </Product> </Request> """.format(**lz_product)) variation = True c_skus = [] for cb_sku in cb_product_info: c_skus.append(cb_sku['sku']) cb_sku['encrypted'] = self.encrypt_sku(cb_sku['sku']) cb_sku['special_price'] = get_special_price(cb_sku['price'], cb_sku['ship_weight'], country = country) cb_sku['price'] = get_sale_price(cb_sku['special_price']) start_date = arrow.now() cb_sku['special_from_date'] = start_date.strftime("%Y-%m-%d") cb_sku['special_to_date'] = start_date.replace(days=+365).strftime("%Y-%m-%d") cb_sku['package_content'] = lz_sku_spec.get('Package Content', '1 x see product description' ) cb_sku['quantity'] = random.randrange(3,50) cb_sku['keyword'] = self.get_key_words(cb_sku, category) product_sku = etree.XML() cattrs = self.get_mandatory_attributes(category) extra_attr = {} for ck, cv in cattrs.items(): if cb_sku['size'] and cb_sku['size'].isdigit(): sku_size = cb_sku['size'] else: cb_sku['title'] = cb_sku['title'] + "(Size: %s)" % cb_sku['size'].replace("&", "and") product_schema.xpath("//name")[0].text = cb_sku['title'] sku_size = 'Not Specified' variation = False extra_attr[ck] = sku_size pass