分享原因
terry很认真回答了我很多问题,真是非常感谢的,刚好我自己需要做批量导入商品,就写了python脚本来做这件事,现在分享处理当感谢terry的支持啦,需要的同学拿到脚本一看就知道怎么做了的,简单改下就可以用了的
完整代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf8')
import requests
import json
import random
import time
import copy
"""产品分类"""
types_jp = [u"時計", u"財布", u"バッグ", u"ファッション、靴", u"ジュエリー", u"ベルト"]
"""分别对应【手表,钱包,包包,时尚/鞋子 ,珠宝,皮带】"""
types_en = ["watch", "wallet", "bag", "shoe", "jewelry", "belt"]
"""产品分类的key"""
category = [
"5b0c366ed88e3300cc4a4da8" ,
"5b078fe4d88e330007051a46",
"5b078ffad88e330007051a48",
"5b07901ed88e330007051a4a",
"5b079035d88e330007051a4c",
"5b079069d88e330007051a4e"
]
"""产品分类及其子类"""
category_attr = {
"5b0c366ed88e3300cc4a4da8":{"type":u"時計"},
"5b078fe4d88e330007051a46":{"type":u"財布"},
"5b078ffad88e330007051a48":{"type":u"バッグ"},
"5b07901ed88e330007051a4a":{"type":u"ファッション、靴"},
"5b079035d88e330007051a4c":{"type":u"ジュエリー"},
"5b079069d88e330007051a4e":{"type":u"ベルト"}
}
def get_token():
"""
获取appserver的token
:return:
"""
url = "http://appapi.xxx.com/v1/account/login"
data = {"username":"admin","password":"admin123"}
res = requests.post(url,data) #{"access-token":"yTaDxsvRv6fPCg0Abbtb_5fb6fl7MIXd","status":"success","code":200}
print(res.text,type(res.text))
res = json.loads(res.text)
print type(res),res["access-token"]
if res and res.has_key("access-token"):
return res["access-token"]
else:
return None
def process_category_data(category_data):
"""
处理分类数据,便于请求
:param category_data:
:return:
"""
post = {
"parent_id": "0",
"name": {
"name_en": "",
"name_fr": "",
"name_de": "",
"name_es": "",
"name_ru": "",
"name_pt": "",
"name_zh": "",
"name_jp": ""
},
"status": 1,
"menu_show": 1,
"url_key": "/wedding",
"level": 1,
"filter_product_attr_selected": "",
"filter_product_attr_unselected": "",
"description": {
"description_en": "",
"description_fr": "",
"description_de": "",
"description_es": "",
"description_ru": "",
"description_pt": "",
"description_zh": "",
"description_jp": ""
},
"menu_custom": {
"menu_custom_en": "<a href=\"//fecshop.appfront.fancyecommerce.com/wedding\"><img alt=\"\" src=\"//img.fancyecommerce.com/custom/menu/what_a.jpg\" width=\"24\" /></a><a style=\"margin-left: 20px;\" href=\"//fecshop.appfront.fancyecommerce.com/wedding\"><img alt=\"\" src=\"//img.fancyecommerce.com/custom/menu/what_b.jpg\" width=\"24\" /></a>",
"menu_custom_fr": "<a href=\"//fecshop.appfront.fancyecommerce.com/fr/wedding\"><img alt=\"\" src=\"//img.fancyecommerce.com/custom/menu/what_a.jpg\" width=\"24\" /></a><a style=\"margin-left: 20px;\" href=\"//fecshop.appfront.fancyecommerce.com/fr/wedding\"><img alt=\"\" src=\"//img.fancyecommerce.com/custom/menu/what_b.jpg\" width=\"24\" /></a>",
"menu_custom_de": "",
"menu_custom_es": "",
"menu_custom_ru": "",
"menu_custom_pt": "",
"menu_custom_zh": "",
"menu_custom_jp": ""
},
"title": {
"title_en": "",
"title_fr": "",
"title_de": "",
"title_es": "",
"title_ru": "",
"title_pt": "",
"title_zh": "",
"title_jp": ""
},
"meta_description": {
"meta_description_en": "",
"meta_description_fr": "",
"meta_description_de": "",
"meta_description_es": "",
"meta_description_ru": "",
"meta_description_pt": "",
"meta_description_zh": ""
},
"meta_keywords": {
"meta_keywords_en": "",
"meta_keywords_fr": "",
"meta_keywords_de": "",
"meta_keywords_es": "",
"meta_keywords_ru": "",
"meta_keywords_pt": "",
"meta_keywords_zh": ""
}
}
post["parent_id"] = category_data["parent_id"]
post["name"]["name_en"] = category_data["name"]["name_en"]
#post["name"]["name_zh"] = "劳力士"
post["name"]["name_jp"] = category_data["name"]["name_jp"]
post["url_key"]=category_data["url_key"]
post["title"]["title_en"] = category_data["title"]["title_en"]
post["title"]["title_jp"] = category_data["title"]["title_jp"]
#post["menu_custom_en"]= category_data["menu_custom_en"]
#post["menu_custom_fr"]= category_data["menu_custom_fr"]
return post
def addc_cateory_item(category_data,mytoken = ""):
"""
:param category_data:
:param mytoken:
:return:
"""
#print "category_data:",category_data
if mytoken == '':
mytoken = get_token()
headers = {'content-type': 'application/json',
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0',
"access-token":mytoken}
url = "http://appapi.xxx.com/v1/category/addone"
data = process_category_data(category_data)
result = {}
if data != -1:
r = ""
#print(data)
try:
r = requests.post(url,json=data,headers=headers)
except Exception,e:
print e
time.sleep(5 * 60)
r = requests.post(url, json=data, headers=headers)
result = json.loads(r.text)
#print result["data"]["addData"]["id"]
if result and result.has_key("data") and result["data"].has_key("addData") and result["data"]["addData"].has_key("id"):
result = result["data"]["addData"]["id"]
else:
print("data is -1")
return result
def is_in_attr(types_list,attr_index,level,index):
"""
判断当前属性是属于那个类别
:param types_list: [u'\u6642\u8a08', u'\u30a6\u30d6\u30ed', u'\u30d3\u30c3\u30b0\u30d0\u30f3']
:param attr_index: 最顶层的key:5b078fcad88e330007051a44
:param level:
:return: 返回列别id,如:3viqIZ8bgiOY4TTc8XIuAbmwWvSAGcW2
"""
# 创建用于添加一个产品分类的请求数据
category_data = {"parent_id": "",
"name":{"name_en" : "",
"name_jp":"",
"name_fr":""},
"url_key":"",
"title":{"title_en":"",
"title_jp":"",
"title_fr": ""},
"menu_custom_en": "",
"menu_custom_fr": ""
}
# 本例子产品分类只有三层
if level == 1:
for k,v in category_attr[attr_index].iteritems():
if isinstance(v,dict) and v.has_key("type") and v["type"] == types_list[level]:
return k
else:
category_data["parent_id"] = attr_index
category_data["name"]["name_en"] = types_list[level]
category_data["name"]["name_jp"] = types_list[level]
category_data["name"]["name_fr"] = types_list[level]
category_data["url_key"] = "/"+types_en[index]+"-"+str(random.randint(10000000, 99999999))
category_data["title"]["title_en"] = types_list[level]
category_data["title"]["title_jp"] = types_list[level]
category_data["title"]["title_fr"] = types_list[level]
cateory_id = addc_cateory_item(category_data,token)
if cateory_id:
category_attr[attr_index][cateory_id] = {"type":types_list[level]}
return cateory_id
elif level >= 2:
# 先找出父类的类型
father_key = ""
for k,v in category_attr[attr_index].iteritems():
if isinstance(v,dict) and v.has_key("type") and v["type"] == types_list[level-1]:
father_key = k
break
# 再去子类里面找
if father_key != "":
for k, v in category_attr[attr_index][father_key].iteritems():
if isinstance(v,dict) and v.has_key("type") and v["type"] == types_list[level]:
return k
else:
category_data["parent_id"] = father_key
category_data["name"]["name_en"] = types_list[level]
category_data["name"]["name_jp"] = types_list[level]
category_data["name"]["name_fr"] = types_list[level]
category_data["url_key"] = "/" + types_en[index] + "-" + str(random.randint(10000000, 99999999))
category_data["title"]["title_en"] = types_list[level]
category_data["title"]["title_jp"] = types_list[level]
category_data["title"]["title_fr"] = types_list[level]
cateory_id = addc_cateory_item(category_data,token)
if cateory_id:
category_attr[attr_index][father_key][cateory_id] = {"type": types_list[level]}
return cateory_id
def process_product_data(data):
"""
数据从sqlite里面读取及预处理
:param data:
:return:
"""
at_time = int(time.time())
# 用于新增产品的数据
post = {
"name": {
"name_en": "test my computer",
"name_fr": "",
"name_de": "",
"name_es": "",
"name_ru": "",
"name_pt": "",
"name_zh": "",
"name_jp": "日本名字"
},
"spu": "computer001",
"sku": "computer001-xinghao1-cpu42",
"weight": 1,
"status": 1,
"qty": 99,
"is_in_stock": 1,
"url_key": "/test-shoe-98383376",
"category": [
"5b057ec4d88e330005600cf5"
],
"price": 333,
"special_price": 32,
"special_from": "2017-09-09",
"special_to": "2018-09-09",
"cost_price": 10,
"new_product_from": "2017-11-05",
"new_product_to": "2017-12-05",
"meta_title": {
"meta_title_en": "",
"meta_title_fr": "",
"meta_title_de": "",
"meta_title_es": "",
"meta_title_ru": "",
"meta_title_pt": "",
"meta_title_zh": "",
"meta_title_jp": ""
},
"meta_keywords": {
"meta_keywords_en": "",
"meta_keywords_fr": "",
"meta_keywords_de": "",
"meta_keywords_es": "",
"meta_keywords_ru": "",
"meta_keywords_pt": "",
"meta_keywords_zh": "",
"meta_keywords_jp": ""
},
"meta_description": {
"meta_description_en": "",
"meta_description_fr": "",
"meta_description_de": "",
"meta_description_es": "",
"meta_description_ru": "",
"meta_description_pt": "",
"meta_description_zh": "",
"meta_description_jp": ""
},
"image": {
"main": {
"image": "/1/11/111147807271192428.jpg",
"label": "",
"sort_order": "",
"is_thumbnails": "1",
"is_detail": "1"
},
"gallery": [
{
"image": "/2/01/20161024170457_13851.jpg",
"label": "",
"is_thumbnails": "1",
"is_detail": "1",
"sort_order": ""
},
{
"image": "/2/01/20161024170457_21098.jpg",
"label": "",
"is_thumbnails": "1",
"is_detail": "1",
"sort_order": ""
},
{
"image": "/2/01/20161101155240_26690.jpg",
"label": "",
"is_thumbnails": "1",
"is_detail": "1",
"sort_order": ""
},
{
"image": "/2/01/20161101155240_56328.jpg",
"label": "",
"is_thumbnails": "1",
"is_detail": "1",
"sort_order": ""
},
{
"image": "/2/01/20161101155240_94256.jpg",
"label": "",
"is_thumbnails": "1",
"is_detail": "1",
"sort_order": ""
}
]
},
"description": {
"description_en": "",
"description_fr": "",
"description_de": "",
"description_es": "",
"description_ru": "",
"description_pt": "",
"description_zh": "",
"description_jp": ""
},
"short_description": {
"short_description_en": "",
"short_description_fr": "",
"short_description_de": "",
"short_description_es": "",
"short_description_ru": "",
"short_description_pt": "",
"short_description_zh": "",
"short_description_jp": ""
},
"remark": "script_insert", #备注
"attr_group": "test_group",
"my_remark": "",
"my_email": "sifu520@126.com",
"my_date": "",
"style": "",
"dresses-length": "",
"pattern-type": "",
"sleeve-length": "",
"collar": "",
"relation_sku": "", #产品相关产品
"buy_also_buy_sku": "",
"see_also_see_sku": ""
}
post["name"]["name_en"] = data["type"][-1]
post["name"]["name_jp"] = data["type"][-1]
post["name"]["name_fr"] = data["type"][-1]
#根据属性选择对应的值
if data["type"]:
del data["type"][0]
types_list = copy.deepcopy(data["type"])
del types_list[-1]
if data["type"][0] in types_jp:
index = types_jp.index(data["type"][0])
else:
print data["type"][0],data["page_name"]
return -1
# 判读types_list里面的值是否在category_attr属性里面
lengh = len(types_list)
post["category"] = [] # 产品的分类id。可以多个
post["category"].append(category[index])
for i in range(1,lengh):
#print("i:",i)
category_id = is_in_attr(types_list,category[index],i,index)
if category_id:
post["category"].append(category_id)
# 以下是普通得属性
post["spu"] = types_en[index]+ "-1"+"-"+data["page_name"][9:].split(".")[0]
url = "/"+types_en[index]+ "-1"+"-"+data["page_name"][9:].split(".")[0]
post["sku"] = types_en[index] + "-1"+"-"+data["page_name"][9:].split(".")[0]
post["url_key"] = url+"-"+str(random.randint(10000000, 99999999))
post["price"] = float(data["price"][:-1])
post["special_price"] = float(data["price"][:-1])
post["meta_keywords"]["meta_keywords_jp"] = data["type"][-1]
post["meta_keywords"]["meta_keywords_en"] = data["type"][-1]
post["meta_keywords"]["meta_keywords_fr"] = data["type"][-1]
post["meta_title"]["meta_title_jp"] = data["type"][-1]
post["meta_title"]["meta_title_en"] = data["type"][-1]
post["meta_title"]["meta_title_fr"] = data["type"][-1]
# 处理描述图片的
post["image"]["gallery"] = []
for pic in data["picture"]:
if pic[:22] == "http://www.jp-kopi.com":
pic = pic[22:]
elif pic[:7] == "images/" and pic[:1] != "/":
pic = "/"+pic
else:
print "picture error"
continue
tmp = {
"image": pic,
"label": "",
"sort_order": "",
"is_thumbnails": "1",
"is_detail": "1"
}
post["image"]["gallery"].append(tmp)
if data["picture"] and data["picture"][0]:
#print "====>",data["picture"]
pic = data["picture"][0]
if pic[:22] == "http://www.jp-kopi.com":
pic = pic[22:]
elif pic[:7] == "images/" and pic[:1] != "/":
pic = "/" + pic
else:
print "picture error"
post["image"]["main"] = {
"image": pic,
"label": "",
"sort_order": "",
"is_thumbnails": "1",
"is_detail": "1"
}
post["meta_description"]["meta_description_en"] = data["type"][-1]
post["meta_description"]["meta_description_jp"] = data["type"][-1]
post["meta_description"]["meta_description_fr"] = data["type"][-1]
post["description"]["description_en"] = "\n".join(data["text"])
post["description"]["description_jp"] = "\n".join(data["text"])
post["description"]["description_fr"] = "\n".join(data["text"])
post["short_description"]["short_description_en"] = data["type"][-1]
post["short_description"]["short_description_jp"] = data["type"][-1]
post["short_description"]["short_description_fr"] = data["type"][-1]
#产品属性组
post["attr_group"] = "test_group"
#post["final_price"] = float(data["price"][:-1]) #这个属性不需要
post["qty"] = 88 #这个值写了也没用
post["name"]["name_en"] = types_en[index] + "-"+data["page_name"][9:].split(".")[0]
#print post["price"],post["url_key"],post["sku"],data["page_name"],
return post
def add_one():
"""
增加一个产品数据
:return:
"""
headers = {'content-type': 'application/json',
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0',
"access-token":token}
url = "http://appapi.xxx.com/v1/product/addone"
# 测试单条数据
res = {'picture': u"[u'images/20140908/0311/sh101-6352-1913.jpg', u'images/20140908/0311/sh101-6352-8178.jpg']",
'text': u"[u'\\u30d6\\u30e9\\u30f3\\u30c9\\u9774\\u30d0\\u30fc\\u30d0\\u30ea\\u30fc ']",
'price': u'12600\u5186', 'page_name': u'repurika-1.html',
'type': u"[u'\\u30db\\u30fc\\u30e0', u'\\u30d5\\u30a1\\u30c3\\u30b7\\u30e7\\u30f3\\u3001\\u9774', u'\\u30d0\\u30fc\\u30d0\\u30ea\\u30fc \\u9774', u' \\u30d0\\u30fc\\u30d0\\u30ea\\u30fc \\u9774 sh101 ']", 'id': 1}
#print(res["type"])
res["type"] = eval(res["type"])
res["text"] = eval(res["text"])
res["picture"] = eval(res["picture"])
print res
data = process_product_data(res)
if data != -1:
#print(data)
try:
r = requests.post(url,json=data,headers=headers)
print "rrrrrr",r.text
except Exception, e:
print e # 这是出现反爬虫报错时的情况,再请求一次就可以了
if str(e).find("requests.exceptions.ConnectionError: HTTPConnectionPool") > 0:
time.sleep(5 * 60)
r = requests.post(url, json=data, headers=headers)
else:
print("data is -1")
token = get_token() """ 一开始先取好token"""
if __name__=='__main__':
add_one()