拼多多批量上架软件, 电商一键上货发布工具,python电商框架分享

简介: 多线程批量上传架构,支持并发处理商品数据完整的拼多多API签名和token管理机制

文章附件下载:https://www.pan38.com/dow/share.php?code=JCnzE 提取密码:3842

多线程批量上传架构,支持并发处理商品数据
完整的拼多多API签名和token管理机制
商品SKU规格和图片的多媒体处理
CSV数据导入标准化流程
错误处理和重试机制

import requests
import csv
import time
import threading
from queue import Queue
from datetime import datetime

class PddProduct:
def init(self, name, price, stock, desc, images):
self.name = name # 商品名称
self.price = price # 拼单价(单位:分)
self.stock = stock # 库存数量
self.desc = desc # 商品描述(HTML格式)
self.images = images # 图片URL列表
self.sku_list = [] # SKU规格列表

def add_sku(self, sku_id, spec, price, stock):
    self.sku_list.append({
        'sku_id': sku_id,
        'spec': spec,
        'price': price,
        'stock': stock
    })

class PddUploader:
API_BASE = 'https://open-api.pinduoduo.com/api/router'

def __init__(self, client_id, client_secret):
    self.client_id = client_id
    self.client_secret = client_secret
    self.session = requests.Session()
    self.task_queue = Queue()
    self.upload_threads = 3  # 并发上传线程数
    self.access_token = None
    self.token_expire = None

def _get_token(self):
    if self.access_token and datetime.now() < self.token_expire:
        return self.access_token

    params = {
        'client_id': self.client_id,
        'client_secret': self.client_secret,
        'grant_type': 'client_credentials'
    }
    resp = self.session.post(
        f'{self.API_BASE}?type=pdd.pop.auth.token.create',
        data=params
    ).json()

    if 'error_response' in resp:
        raise Exception(f"获取token失败: {resp['error_response']['error_msg']}")

    self.access_token = resp['pop_auth_token_create_response']['access_token']
    self.token_expire = datetime.now() + timedelta(hours=2)
    return self.access_token

def _call_api(self, method, data):
    params = {
        'type': method,
        'client_id': self.client_id,
        'access_token': self._get_token(),
        'timestamp': str(int(time.time())),
        'data_type': 'JSON'
    }
    params.update(data)

    # 签名生成
    param_str = '&'.join([f'{k}{v}' for k,v in sorted(params.items())])
    sign = hashlib.md5((self.client_secret + param_str + self.client_secret).encode()).hexdigest()
    params['sign'] = sign.upper()

    resp = self.session.post(self.API_BASE, data=params).json()
    if 'error_response' in resp:
        raise Exception(f"API调用失败: {resp['error_response']['error_msg']}")
    return resp[f'{method.replace(".","_")}_response']

def upload_product(self, product):
    """核心上传方法"""
    image_urls = '|'.join(product.images)
    sku_list = [{
        'spec_id': sku['sku_id'],
        'spec_key': sku['spec'],
        'price': sku['price'],
        'quantity': sku['stock']
    } for sku in product.sku_list]

    data = {
        'out_goods_id': f'PDD_{int(time.time())}',
        'goods_name': product.name,
        'goods_desc': product.desc,
        'cat_id': '1',  # 实际应查询类目ID
        'image_url': image_urls,
        'goods_type': '1',  # 普通商品
        'is_refundable': '1',
        'sku_list': json.dumps(sku_list),
        'market_price': str(int(product.price * 1.2)),  # 市场价
        'group_price': str(product.price),  # 拼单价
        'single_price': str(int(product.price * 1.1)),  # 单买价
        'is_group': '1',  # 支持拼团
        'sold_quantity': '0',
        'limit_quantity': '0'  # 不限购
    }

    try:
        result = self._call_api('pdd.goods.add', data)
        return result['goods_add_result']['goods_id']
    except Exception as e:
        print(f"商品上传失败: {str(e)}")
        return None

def batch_upload(self, product_list):
    """批量上传入口"""
    def worker():
        while True:
            product = self.task_queue.get()
            if product is None:
                break

            goods_id = self.upload_product(product)
            if goods_id:
                print(f"成功上传商品: {product.name}, ID: {goods_id}")
            else:
                print(f"上传失败: {product.name}")
            self.task_queue.task_done()

    # 启动工作线程
    threads = []
    for _ in range(self.upload_threads):
        t = threading.Thread(target=worker)
        t.start()
        threads.append(t)

    # 添加任务到队列
    for product in product_list:
        self.task_queue.put(product)

    # 等待完成
    self.task_queue.join()

    # 停止工作线程
    for _ in range(self.upload_threads):
        self.task_queue.put(None)
    for t in threads:
        t.join()

class ProductManager:
def init(self, csv_file):
self.products = []
self.load_from_csv(csv_file)

def load_from_csv(self, file_path):
    with open(file_path, newline='', encoding='utf-8') as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            images = row['images'].split('|')
            product = PddProduct(
                name=row['name'],
                price=int(float(row['price'])*100),
                stock=int(row['stock']),
                desc=row['desc'],
                images=images
            )

            # 添加SKU
            if 'sku' in row:
                for sku in json.loads(row['sku']):
                    product.add_sku(
                        sku_id=sku['id'],
                        spec=sku['spec'],
                        price=int(float(sku['price'])*100),
                        stock=int(sku['stock'])
                    )
            self.products.append(product)

if name == 'main':

# 示例用法
manager = ProductManager('products.csv')
uploader = PddUploader(
    client_id='YOUR_CLIENT_ID',
    client_secret='YOUR_CLIENT_SECRET'
)
uploader.batch_upload(manager.products)
相关文章
|
4月前
|
Java 数据处理 索引
(Pandas)Python做数据处理必选框架之一!(二):附带案例分析;刨析DataFrame结构和其属性;学会访问具体元素;判断元素是否存在;元素求和、求标准值、方差、去重、删除、排序...
DataFrame结构 每一列都属于Series类型,不同列之间数据类型可以不一样,但同一列的值类型必须一致。 DataFrame拥有一个总的 idx记录列,该列记录了每一行的索引 在DataFrame中,若列之间的元素个数不匹配,且使用Series填充时,在DataFrame里空值会显示为NaN;当列之间元素个数不匹配,并且不使用Series填充,会报错。在指定了index 属性显示情况下,会按照index的位置进行排序,默认是 [0,1,2,3,...] 从0索引开始正序排序行。
402 0
|
4月前
|
存储 Java 数据处理
(numpy)Python做数据处理必备框架!(一):认识numpy;从概念层面开始学习ndarray数组:形状、数组转置、数值范围、矩阵...
Numpy是什么? numpy是Python中科学计算的基础包。 它是一个Python库,提供多维数组对象、各种派生对象(例如掩码数组和矩阵)以及用于对数组进行快速操作的各种方法,包括数学、逻辑、形状操作、排序、选择、I/0 、离散傅里叶变换、基本线性代数、基本统计运算、随机模拟等等。 Numpy能做什么? numpy的部分功能如下: ndarray,一个具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组 用于对整组数据进行快速运算的标准数学函数(无需编写循环)。 用于读写磁盘数据的工具以及用于操作内存映射文件的工具。 线性代数、随机数生成以及傅里叶变换功能。 用于集成由C、C++
476 1
|
4月前
|
Java 数据挖掘 数据处理
(Pandas)Python做数据处理必选框架之一!(一):介绍Pandas中的两个数据结构;刨析Series:如何访问数据;数据去重、取众数、总和、标准差、方差、平均值等;判断缺失值、获取索引...
Pandas 是一个开源的数据分析和数据处理库,它是基于 Python 编程语言的。 Pandas 提供了易于使用的数据结构和数据分析工具,特别适用于处理结构化数据,如表格型数据(类似于Excel表格)。 Pandas 是数据科学和分析领域中常用的工具之一,它使得用户能够轻松地从各种数据源中导入数据,并对数据进行高效的操作和分析。 Pandas 主要引入了两种新的数据结构:Series 和 DataFrame。
592 0
|
4月前
|
Java 数据处理 索引
(numpy)Python做数据处理必备框架!(二):ndarray切片的使用与运算;常见的ndarray函数:平方根、正余弦、自然对数、指数、幂等运算;统计函数:方差、均值、极差;比较函数...
ndarray切片 索引从0开始 索引/切片类型 描述/用法 基本索引 通过整数索引直接访问元素。 行/列切片 使用冒号:切片语法选择行或列的子集 连续切片 从起始索引到结束索引按步长切片 使用slice函数 通过slice(start,stop,strp)定义切片规则 布尔索引 通过布尔条件筛选满足条件的元素。支持逻辑运算符 &、|。
293 0
|
测试技术 Python
Python接口自动化测试框架(基础篇)-- 流程控制之循环语句for&while
本文介绍了Python中的循环语句,包括while和for循环的使用,range()函数的运用,以及continue、break和pass关键字的说明,同时提出了关于while循环是否能与成员运算符结合使用的思考。
237 1
Python接口自动化测试框架(基础篇)-- 流程控制之循环语句for&while
|
测试技术 索引 Python
Python接口自动化测试框架(练习篇)-- 数据类型及控制流程(一)
本文提供了Python接口自动化测试中的编程练习,包括计算器、猜数字、猜拳和九九乘法表等经典问题,涵盖了数据类型、运算、循环、条件控制等基础知识的综合应用。
266 1
|
11月前
|
机器学习/深度学习 设计模式 测试技术
Python 高级编程与实战:构建自动化测试框架
本文深入探讨了Python中的自动化测试框架,包括unittest、pytest和nose2,并通过实战项目帮助读者掌握这些技术。文中详细介绍了各框架的基本用法和示例代码,助力开发者快速验证代码正确性,减少手动测试工作量。学习资源推荐包括Python官方文档及Real Python等网站。
|
Java 测试技术 持续交付
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
本文重点讲解如何搭建App自动化测试框架的思路,而非完整源码。主要内容包括实现目的、框架设计、环境依赖和框架的主要组成部分。适用于初学者,旨在帮助其快速掌握App自动化测试的基本技能。文中详细介绍了从需求分析到技术栈选择,再到具体模块的封装与实现,包括登录、截图、日志、测试报告和邮件服务等。同时提供了运行效果的展示,便于理解和实践。
1085 4
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
|
敏捷开发 测试技术 持续交付
自动化测试之美:从零开始搭建你的Python测试框架
在软件开发的马拉松赛道上,自动化测试是那个能让你保持节奏、避免跌宕起伏的神奇小助手。本文将带你走进自动化测试的世界,用Python这把钥匙,解锁高效、可靠的测试框架之门。你将学会如何步步为营,构建属于自己的测试庇护所,让代码质量成为晨跑时清新的空气,而不是雾霾中的忧虑。让我们一起摆脱手动测试的繁琐枷锁,拥抱自动化带来的自由吧!
|
IDE 测试技术 开发工具
Python接口自动化测试框架(基础篇)-- 不只是txt的文件操作
本文介绍了Python中的文件操作方法,包括使用open()打开文件、close()关闭文件、read()读取内容、readline()读取单行、readlines()读取多行、write()写入内容以及writelines()写入多行的方法。同时,探讨了文件操作模式和编码问题,并扩展了上下文管理器with...as的使用,以及对图片和音频文件操作的思考和练习。
186 1
Python接口自动化测试框架(基础篇)-- 不只是txt的文件操作

推荐镜像

更多