文章附件下载:www.pan38.com/dow/share.p… 提取密码:3722
代码功能说明:
- 使用Selenium实现浏览器自动化操作,模拟人工发布商品流程
- 支持从CSV文件批量读取商品数据,包含标题、价格、库存等关键信息
- 实现完整的登录流程,自动跳转到商品发布页面
- 包含商品类目选择、基本信息填写、图片上传等完整发布流程
- 完善的异常处理和日志记录功能,便于排查问题
- 代码结构清晰,模块化设计,易于维护和扩展
import csv import time import logging from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException, NoSuchElementException
配置日志记录
logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', filename='taobao_upload.log' )
class TaobaoBulkUploader: def init(self, username, password, csv_file): self.username = username self.password = password self.csv_file = csv_file self.driver = None self.wait_time = 30
# 商品字段映射
self.field_mapping = {
'title': '商品标题',
'price': '价格',
'stock': '库存',
'description': '商品描述',
'images': '图片路径',
'category': '商品类目'
}
def init_driver(self):
"""初始化浏览器驱动"""
options = webdriver.ChromeOptions()
options.add_argument('--disable-notifications')
options.add_argument('--start-maximized')
self.driver = webdriver.Chrome(options=options)
self.driver.implicitly_wait(10)
def login(self):
"""登录淘宝卖家中心"""
try:
self.driver.get('https://login.taobao.com/')
# 切换到账号密码登录
switch_btn = WebDriverWait(self.driver, self.wait_time).until(
EC.presence_of_element_located((By.XPATH, '//*[@id="login"]/div[1]/i'))
)
switch_btn.click()
# 输入用户名和密码
username_field = self.driver.find_element(By.NAME, 'fm-login-id')
password_field = self.driver.find_element(By.NAME, 'fm-login-password')
username_field.send_keys(self.username)
password_field.send_keys(self.password)
# 点击登录
login_btn = self.driver.find_element(By.XPATH, '//*[@id="login-form"]/div[4]/button')
login_btn.click()
# 等待登录成功
WebDriverWait(self.driver, self.wait_time).until(
EC.url_contains('https://www.taobao.com/')
)
logging.info('登录成功')
return True
except Exception as e:
logging.error(f'登录失败: {str(e)}')
return False
def navigate_to_product_upload(self):
"""导航到商品发布页面"""
try:
# 进入卖家中心
self.driver.get('https://seller.taobao.com/')
# 点击商品管理
product_menu = WebDriverWait(self.driver, self.wait_time).until(
EC.presence_of_element_located((By.XPATH, '//*[contains(text(),"商品管理")]'))
)
product_menu.click()
# 点击发布商品
upload_btn = WebDriverWait(self.driver, self.wait_time).until(
EC.presence_of_element_located((By.XPATH, '//*[contains(text(),"发布商品")]'))
)
upload_btn.click()
# 切换到新窗口
self.driver.switch_to.window(self.driver.window_handles[-1])
logging.info('成功进入商品发布页面')
return True
except Exception as e:
logging.error(f'导航到商品发布页面失败: {str(e)}')
return False
def upload_product(self, product_data):
"""上传单个商品"""
try:
# 选择商品类目
category_input = WebDriverWait(self.driver, self.wait_time).until(
EC.presence_of_element_located((By.XPATH, '//input[@placeholder="请输入商品类目"]'))
)
category_input.clear()
category_input.send_keys(product_data['category'])
time.sleep(2) # 等待类目加载
# 点击搜索按钮
search_btn = self.driver.find_element(By.XPATH, '//button[contains(text(),"搜索")]')
search_btn.click()
time.sleep(1)
# 选择第一个匹配的类目
first_category = self.driver.find_element(By.XPATH, '//div[@class="category-list"]/div[1]')
first_category.click()
# 点击确认按钮
confirm_btn = self.driver.find_element(By.XPATH, '//button[contains(text(),"确认")]')
confirm_btn.click()
# 填写商品标题
title_field = WebDriverWait(self.driver, self.wait_time).until(
EC.presence_of_element_located((By.XPATH, '//input[@placeholder="请输入商品标题"]'))
)
title_field.send_keys(product_data['title'])
# 填写价格
price_field = self.driver.find_element(By.XPATH, '//input[@placeholder="请输入价格"]')
price_field.send_keys(product_data['price'])
# 填写库存
stock_field = self.driver.find_element(By.XPATH, '//input[@placeholder="请输入库存数量"]')
stock_field.send_keys(product_data['stock'])
# 上传图片
if 'images' in product_data:
image_paths = product_data['images'].split('|')
for img_path in image_paths:
upload_input = self.driver.find_element(By.XPATH, '//input[@type="file"]')
upload_input.send_keys(img_path)
time.sleep(1) # 等待图片上传
# 填写商品描述
self.driver.switch_to.frame('ueditor_0')
desc_editor = self.driver.find_element(By.XPATH, '//body')
desc_editor.send_keys(product_data['description'])
self.driver.switch_to.default_content()
# 点击发布按钮
publish_btn = self.driver.find_element(By.XPATH, '//button[contains(text(),"发布商品")]')
publish_btn.click()
# 等待发布成功
WebDriverWait(self.driver, self.wait_time).until(
EC.presence_of_element_located((By.XPATH, '//*[contains(text(),"发布成功")]'))
)
logging.info(f'商品发布成功: {product_data["title"]}')
return True
except Exception as e:
logging.error(f'商品发布失败: {product_data["title"]}, 错误: {str(e)}')
return False
def process_csv(self):
"""处理CSV文件并批量上传商品"""
try:
with open(self.csv_file, mode='r', encoding='utf-8') as file:
reader = csv.DictReader(file)
for row in reader:
product_data = {
'title': row.get(self.field_mapping['title'], ''),
'price': row.get(self.field_mapping['price'], '0'),
'stock': row.get(self.field_mapping['stock'], '0'),
'description': row.get(self.field_mapping['description'], ''),
'images': row.get(self.field_mapping['images'], ''),
'category': row.get(self.field_mapping['category'], '')
}
if not all(product_data.values()):
logging.warning(f'商品数据不完整: {row}')
continue
self.upload_product(product_data)
time.sleep(3) # 间隔时间避免频繁操作
logging.info('所有商品处理完成')
return True
except Exception as e:
logging.error(f'处理CSV文件失败: {str(e)}')
return False
def run(self):
"""执行批量上传流程"""
try:
self.init_driver()
if not self.login():
return False
if not self.navigate_to_product_upload():
return False
if not self.process_csv():
return False
return True
except Exception as e:
logging.error(f'程序运行异常: {str(e)}')
return False
finally:
if self.driver:
self.driver.quit()
if name == 'main': # 示例用法 uploader = TaobaoBulkUploader( username='your_taobao_username', password='your_taobao_password', csv_file='products.csv' ) uploader.run()