app.py 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. import requests
  2. import json
  3. import os
  4. from urllib.parse import urlparse
  5. from typing import Optional, Dict, Any
  6. from PIL import Image
  7. import io
  8. token = "Bearer eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiQURNSU4iLCJ1c2VySWQiOjEsImlhdCI6MTc3MjYxOTA2NiwiZXhwIjoxNzczMjIzODY2fQ.IatRhEStT5IUXHsN8_tvxuijNFO0tNkIADYIV79dWMo"
  9. def get_product_detail(mer_id: str, product_id: str) -> Optional[Dict[str, Any]]:
  10. global token
  11. """
  12. 获取产品详情
  13. Args:
  14. mer_id: 商户ID
  15. product_id: 产品ID
  16. Returns:
  17. 返回JSON格式的产品详情数据,如果请求失败则返回None
  18. """
  19. # 构建URL
  20. base_url = "https://api.tiki-int.site/api/product/detail"
  21. params = {
  22. "mer_id": mer_id,
  23. "product_id": product_id
  24. }
  25. # 设置请求头
  26. headers = {
  27. "accept": "application/json, text/plain, */*",
  28. "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7",
  29. "cache-control": "no-cache",
  30. "lang": "en",
  31. "pragma": "no-cache",
  32. "priority": "u=1, i",
  33. "sec-ch-ua": '"Not:A-Brand";v="99", "Google Chrome";v="145", "Chromium";v="145"',
  34. "sec-ch-ua-mobile": "?0",
  35. "sec-ch-ua-platform": '"Windows"',
  36. "sec-fetch-dest": "empty",
  37. "sec-fetch-mode": "cors",
  38. "sec-fetch-site": "cross-site",
  39. "Referer": "https://tiki.fashion11.top/",
  40. "Referrer-Policy": "strict-origin-when-cross-origin"
  41. }
  42. try:
  43. # 发送GET请求
  44. response = requests.get(
  45. url=base_url,
  46. params=params,
  47. headers=headers,
  48. timeout=10 # 设置10秒超时
  49. )
  50. # 检查响应状态
  51. response.raise_for_status()
  52. # 返回JSON数据
  53. return response.json()
  54. except requests.exceptions.RequestException as e:
  55. print(f"请求失败: {e}")
  56. return None
  57. except json.JSONDecodeError as e:
  58. print(f"JSON解析失败: {e}")
  59. return None
  60. import os
  61. from urllib.parse import urlparse
  62. import requests
  63. from PIL import Image
  64. import io
  65. def download_and_upload_image(image_url):
  66. """
  67. 下载图片并上传到指定地址,webp格式自动转换为jpg
  68. Args:
  69. image_url: 图片的URL地址
  70. Returns:
  71. 上传结果的JSON响应
  72. """
  73. # 默认上传地址
  74. upload_url = "https://www.as1688.vip/api/v1/file/upload"
  75. # 从URL中提取文件名和后缀
  76. parsed_url = urlparse(image_url)
  77. filename = os.path.basename(parsed_url.path)
  78. if not filename or '.' not in filename:
  79. filename = "image.jpg"
  80. # 获取文件后缀
  81. ext = os.path.splitext(filename)[1].lower()
  82. # 临时文件路径
  83. temp_file = f"temp_{filename}"
  84. try:
  85. # 1. 下载图片
  86. # print(f"正在下载图片: {image_url}")
  87. img_response = requests.get(image_url, timeout=30)
  88. img_response.raise_for_status()
  89. # 2. 处理webp格式
  90. need_convert = False
  91. if ext == '.webp':
  92. need_convert = True
  93. # print("检测到webp格式,正在转换为jpg...")
  94. # 使用PIL转换webp为jpg
  95. image = Image.open(io.BytesIO(img_response.content))
  96. # 如果是RGBA模式,转换为RGB(去除alpha通道)
  97. if image.mode == 'RGBA':
  98. # 创建白色背景
  99. rgb_image = Image.new('RGB', image.size, (255, 255, 255))
  100. # 粘贴webp图像,使用alpha通道作为掩码
  101. rgb_image.paste(image, mask=image.split()[3])
  102. image = rgb_image
  103. elif image.mode != 'RGB':
  104. image = image.convert('RGB')
  105. # 保存为jpg到临时文件
  106. image.save(temp_file, 'JPEG', quality=85)
  107. # 更新文件名和MIME类型
  108. base_name = os.path.splitext(filename)[0]
  109. filename = f"{base_name}.jpg"
  110. mime_type = 'image/jpeg'
  111. print(f"已转换为: {filename}")
  112. else:
  113. # 普通图片,直接保存
  114. with open(temp_file, 'wb') as f:
  115. f.write(img_response.content)
  116. # 设置MIME类型
  117. mime_types = {
  118. '.jpg': 'image/jpeg',
  119. '.jpeg': 'image/jpeg',
  120. '.png': 'image/png',
  121. '.gif': 'image/gif',
  122. '.bmp': 'image/bmp',
  123. '.ico': 'image/x-icon',
  124. '.svg': 'image/svg+xml'
  125. }
  126. mime_type = mime_types.get(ext, 'image/jpeg')
  127. # print(f"图片已保存到: {temp_file}")
  128. # 3. 准备上传
  129. headers = {
  130. "accept": "application/json",
  131. "accept-language": "zh-CN,zh;q=0.9",
  132. "authorization": token,
  133. "sec-ch-ua": '"Not:A-Brand";v="99", "Google Chrome";v="145", "Chromium";v="145"',
  134. "sec-ch-ua-mobile": "?0",
  135. "sec-ch-ua-platform": '"Windows"'
  136. }
  137. # 准备文件上传
  138. with open(temp_file, 'rb') as f:
  139. files = {
  140. 'file': (filename, f, mime_type)
  141. }
  142. # print(f"正在上传到: {upload_url}")
  143. # print(f"文件名: {filename}, 类型: {mime_type}")
  144. upload_response = requests.post(
  145. upload_url,
  146. headers=headers,
  147. files=files,
  148. timeout=30
  149. )
  150. upload_response.raise_for_status()
  151. result = upload_response.json()
  152. print("上传成功!")
  153. return result
  154. except requests.exceptions.RequestException as e:
  155. print(f"网络请求错误: {e}")
  156. return {"error": str(e)}
  157. except ImportError:
  158. print("错误: 请安装PIL库: pip install Pillow")
  159. return {"error": "缺少PIL库,无法转换webp格式"}
  160. except Exception as e:
  161. print(f"其他错误: {e}")
  162. return {"error": str(e)}
  163. finally:
  164. # 清理临时文件
  165. if os.path.exists(temp_file):
  166. os.remove(temp_file)
  167. # print(f"临时文件已删除: {temp_file}")
  168. def batch_create_products(body_data):
  169. """
  170. 批量创建商品
  171. Args:
  172. body_data: 可以是字典或JSON字符串
  173. token: 授权token,如果不提供则使用默认token
  174. Returns:
  175. 接口返回的JSON结果
  176. """
  177. # 上传地址
  178. url = "https://www.as1688.vip/api/v1/product-management/products/batch"
  179. # 请求头
  180. headers = {
  181. "accept": "application/json",
  182. "accept-language": "zh-CN,zh;q=0.9",
  183. "authorization": token,
  184. "content-type": "application/json",
  185. "sec-ch-ua": '"Not:A-Brand";v="99", "Google Chrome";v="145", "Chromium";v="145"',
  186. "sec-ch-ua-mobile": "?0",
  187. "sec-ch-ua-platform": '"Windows"',
  188. "sec-fetch-dest": "empty",
  189. "sec-fetch-mode": "cors",
  190. "sec-fetch-site": "same-origin"
  191. }
  192. # 处理body数据
  193. if isinstance(body_data, dict):
  194. json_body = body_data
  195. elif isinstance(body_data, str):
  196. json_body = json.loads(body_data)
  197. else:
  198. raise ValueError("body_data必须是字典或JSON字符串")
  199. try:
  200. # 发送POST请求
  201. response = requests.post(
  202. url,
  203. headers=headers,
  204. json=json_body,
  205. timeout=30
  206. )
  207. # 检查响应
  208. response.raise_for_status()
  209. # 返回JSON结果
  210. return response.json()
  211. except requests.exceptions.RequestException as e:
  212. print(f"请求错误: {e}")
  213. if hasattr(e, 'response') and e.response:
  214. print(f"响应内容: {e.response.text}")
  215. return {"error": str(e)}
  216. except json.JSONDecodeError as e:
  217. print(f"JSON解析错误: {e}")
  218. return {"error": str(e)}
  219. def get_product_list(category_id, page=1):
  220. """最简单的版本,只返回商品列表"""
  221. url = f"https://api.tiki-int.site/api/product/search?category_id={category_id}&page={page}&limit=15&type=1"
  222. try:
  223. return requests.get(url).json()
  224. except:
  225. return []
  226. # 使用示例
  227. if __name__ == "__main__":
  228. for index in range(1, 214):
  229. listData = get_product_list(24, index)
  230. for item in listData['data']['list']:
  231. print(index,item['product_id'], item['mer_id'])
  232. # 测试函数
  233. result = get_product_detail(item['mer_id'],item['product_id'])
  234. print(result['data']['goods'])
  235. content = result['data']['goods']['content']
  236. title = result['data']['goods']['title']
  237. stock = result['data']['goods']['stock']
  238. images = result['data']['goods']['images'].split(",")
  239. market_price = result['data']['goods']['sales_price']
  240. # 上传图片获取URL
  241. uploaded_image_urls = []
  242. for image_url in images:
  243. print(f"处理图片: {image_url}")
  244. resultFile = download_and_upload_image(image_url)
  245. if ('data' in resultFile):
  246. uploadFileURL = resultFile['data']
  247. uploaded_image_urls.append(uploadFileURL)
  248. print(title, stock, market_price)
  249. if (len(uploaded_image_urls) > 0 and market_price > 0):
  250. #
  251. uploadInfo = {"products":[{"name":title,"category":"全球购","price":str(market_price),"stock":stock,"description":content,"images":uploaded_image_urls}]}
  252. print(uploadInfo["products"][0]["category"])
  253. uploadInfoReturn = batch_create_products(uploadInfo)
  254. print(uploadInfoReturn)