电子元件(如电阻、电容、IC 芯片、传感器等)的 item_get 接口(非官方命名)是获取单款元件完整详情的核心入口,数据覆盖型号规格、电气参数、封装尺寸、品牌批次、供应商资质、库存价格等关键信息,对电子制造采购、研发选型、供应链风控等场景至关重要。由于电子元件交易平台(如立创商城、贸泽电子、Digi-Key、Arrow)无统一公开 API,需通过 详情页解析 + 动态接口逆向 实现对接,且需重点适配电子行业的 型号标准化、参数精细化、批次追溯性 等特性。本文系统讲解接口逻辑、技术实现、行业痛点解决方案,助你构建稳定的电子元件详情获取系统。
一、接口基础认知(核心功能与场景)
1. 核心功能
2. 典型应用场景
3. 接口特性
4. 主流电子元件平台详情页特性对比
二、对接前置准备(环境与 URL 结构)
1. 开发环境
2. 详情页 URL 结构
3. 前置准备要点
4. 页面结构分析(以立创商城为例)
三、接口调用流程(静态 HTML + 动态 API)
1. URL 构建与请求头伪装
2. 静态数据解析(基础信息 + 核心参数)
3. 动态接口补充(实时库存 + 阶梯价)
4. 供应商信息提取
5. 数据整合(标准化输出)
四、代码实现示例(Python)
import requests
import time
import random
import re
import json
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
from typing import List, Dict, Tuple
class ElectronicItemGetApi:
def __init__(self, platform: str = "szlcsc", proxy_pool: List[str] = None, cookie: str = ""):
"""
初始化电子元件商品详情API
:param platform: 平台类型(szlcsc=立创商城,mouser=贸泽电子,digikey=Digi-Key)
:param proxy_pool: 代理池列表(如["http://ip:port", ...])
:param cookie: 登录态Cookie(授权平台必需)
"""
self.platform = platform.lower()
self.proxy_pool = proxy_pool
self.cookie = cookie
self.ua = UserAgent()
# 平台基础配置(可扩展多平台)
self.platform_config = {
"szlcsc": {
"detail_url": "https://item.szlcsc.com/{product_id}.html",
"api_url": "https://item.szlcsc.com/api/product/detail",
"param_table_selector": "table.parameter-table",
"spec_selector": "a.spec-download",
"compliance_selector": "div.compliance-tag"
},
"mouser": {
"detail_url": "https://www.mouser.cn/ProductDetail/{brand}/{model}",
"api_url": "https://www.mouser.cn/api/v1/products/details",
"param_table_selector": ".product-specs-table",
"spec_selector": ".technical-datasheet-link",
"compliance_selector": ".compliance-badges"
},
"digikey": {
"detail_url": "https://www.digikey.com/en/products/detail/{brand}/{model}/{product_id}",
"api_url": "https://www.digikey.com/api/products/details",
"param_table_selector": ".product-attributes-table",
"spec_selector": ".datasheet-link",
"compliance_selector": ".compliance-icons"
}
}
self.config = self.platform_config.get(self.platform, self.platform_config["szlcsc"])
def _get_headers(self) -> Dict[str, str]:
"""生成随机请求头(模拟真实浏览器访问)"""
headers = {
"User-Agent": self.ua.random,
"Referer": self.config["detail_url"].split("/item")[0] if self.platform == "szlcsc" else self.config["detail_url"].split("/ProductDetail")[0],
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"X-Requested-With": "XMLHttpRequest",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-Mode": "navigate"
}
if self.cookie:
headers["Cookie"] = self.cookie
return headers
def _get_proxy(self) -> Dict[str, str]:
"""随机获取代理(每次请求切换)"""
if self.proxy_pool and len(self.proxy_pool) > 0:
proxy = random.choice(self.proxy_pool)
return {"http": proxy, "https": proxy}
return None
def _parse_parameters(self, soup) -> Dict:
"""解析核心参数(电气参数+物理参数,标准化输出)"""
params = {
# 通用参数
"model": "", "brand": "", "package": "", "tolerance": "",
# 电阻专用
"resistance": "", "resistance_value": "", "resistance_unit": "",
# 电容专用
"capacitance": "", "capacitance_value": "", "capacitance_unit": "", "voltage": "", "material": "",
# 通用电气参数
"operating_temperature": "", "power": "",
# 物理参数
"dimension": "", "pin_count": ""
}
param_table = soup.select_one(self.config["param_table_selector"])
if not param_table:
return params
for row in param_table.select("tr"):
th = row.select_one("th")?.text.strip().lower() # 统一转为小写,便于匹配
td = row.select_one("td")?.text.strip()
if not th or not td:
continue
# 型号(核心标识)
if any(keyword in th for keyword in ["型号", "part number", "product code"]):
params["model"] = td
# 品牌
elif any(keyword in th for keyword in ["品牌", "manufacturer", "brand"]):
params["brand"] = td
# 封装
elif any(keyword in th for keyword in ["封装", "package", "footprint"]):
params["package"] = td
# 精度/容差
elif any(keyword in th for keyword in ["精度", "容差", "tolerance"]):
params["tolerance"] = td
# 电阻值
elif any(keyword in th for keyword in ["电阻", "resistance", "ohms"]):
params["resistance"] = td
value_match = re.search(r"\d+\.?\d*", td)
unit_match = re.search(r"[a-zA-ZμΩkM]+", td)
params["resistance_value"] = value_match.group() if value_match else ""
params["resistance_unit"] = unit_match.group() if unit_match else ""
# 容值
elif any(keyword in th for keyword in ["容值", "电容", "capacitance", "farad"]):
params["capacitance"] = td
value_match = re.search(r"\d+\.?\d*", td)
unit_match = re.search(r"[a-zA-ZμnFpF]+", td)
params["capacitance_value"] = value_match.group() if value_match else ""
params["capacitance_unit"] = unit_match.group() if unit_match else ""
# 电压
elif any(keyword in th for keyword in ["电压", "额定电压", "voltage", "rating"]):
params["voltage"] = td
# 材质
elif any(keyword in th for keyword in ["材质", "dielectric", "material"]):
params["material"] = td
# 工作温度
elif any(keyword in th for keyword in ["工作温度", "temperature", "operating temp"]):
params["operating_temperature"] = td
# 功率
elif any(keyword in th for keyword in ["功率", "power", "watt"]):
params["power"] = td
# 尺寸
elif any(keyword in th for keyword in ["尺寸", "dimension", "size"]):
params["dimension"] = td
# 引脚数
elif any(keyword in th for keyword in ["引脚", "pin count", "pins"]):
params["pin_count"] = td
return params
def _parse_ladder_prices(self, api_data: Dict) -> Tuple[float, List[Dict]]:
"""解析批量阶梯价(结构化)"""
ladder_prices = []
base_price = 0.0
if self.platform == "szlcsc":
ladder_data = api_data.get("data", {}).get("priceLadder", [])
for item in ladder_data:
ladder_prices.append({
"min_quantity": int(item.get("minNum", 0)),
"max_quantity": int(item.get("maxNum", 999999)),
"price": float(item.get("price", 0)),
"unit": "元/个"
})
# 基础单价(最小采购量价格)
base_price = ladder_prices[0]["price"] if ladder_prices else 0.0
elif self.platform == "mouser":
# 贸泽电子动态接口数据格式(简化版,真实需逆向)
ladder_data = api_data.get("data", {}).get("priceBreaks", [])
for item in ladder_data:
ladder_prices.append({
"min_quantity": int(item.get("quantity", 0)),
"max_quantity": 999999,
"price": float(item.get("unitPrice", 0)),
"unit": "元/个"
})
base_price = ladder_prices[0]["price"] if ladder_prices else 0.0
# 按采购量升序排序
ladder_prices.sort(key=lambda x: x["min_quantity"])
return base_price, ladder_prices
def _parse_stock(self, api_data: Dict, soup) -> Dict:
"""解析库存信息(实时库存+状态)"""
stock_info = {
"total_stock": 0,
"stock_status": "缺货",
"min_order": 1
}
if self.platform == "szlcsc":
total_stock = api_data.get("data", {}).get("stock", 0)
stock_info["total_stock"] = int(total_stock)
stock_info["stock_status"] = "现货" if total_stock > 0 else "预售"
stock_info["min_order"] = int(api_data.get("data", {}).get("minBuyNum", 1))
elif self.platform == "mouser":
stock_status = api_data.get("data", {}).get("availability", "")
stock_info["stock_status"] = "现货" if "In Stock" in stock_status else "预售"
stock_info["total_stock"] = int(api_data.get("data", {}).get("stockQuantity", 0))
stock_info["min_order"] = 1
return stock_info
def _parse_compliance(self, soup) -> Dict:
"""解析合规信息(RoHS、REACH、质量等级)"""
compliance_info = {
"rohs": False,
"reach": False,
"quality_grade": "消费级",
"batch_number": ""
}
compliance_tag = soup.select_one(self.config["compliance_selector"])
if compliance_tag:
compliance_text = compliance_tag.text.lower()
compliance_info["rohs"] = "rohs" in compliance_text
compliance_info["reach"] = "reach" in compliance_text
# 质量等级(工业级/车规级/消费级)
grade_tag = soup.select_one("div.grade-tag, .quality-grade")
if grade_tag:
grade_text = grade_tag.text.lower()
if "工业" in grade_text or "industrial" in grade_text:
compliance_info["quality_grade"] = "工业级"
elif "车规" in grade_text or "automotive" in grade_text:
compliance_info["quality_grade"] = "车规级"
elif "军工" in grade_text or "military" in grade_text:
compliance_info["quality_grade"] = "军工级"
# 批次号(部分平台显示在详情页)
batch_tag = soup.select_one("div.batch-number, .lot-code")
if batch_tag:
compliance_info["batch_number"] = batch_tag.text.strip()
return compliance_info
def _parse_spec(self, soup) -> Dict:
"""解析规格书信息(下载URL)"""
spec_info = {
"has_spec": False,
"spec_url": "",
"spec_name": ""
}
spec_a = soup.select_one(self.config["spec_selector"])
if spec_a and spec_a.get("href"):
spec_url = spec_a.get("href")
# 补全相对URL
if not spec_url.startswith("http"):
base_domain = "https://item.szlcsc.com" if self.platform == "szlcsc" else "https://www.mouser.cn"
spec_url = f"{base_domain}{spec_url}"
spec_info["has_spec"] = True
spec_info["spec_url"] = spec_url
spec_info["spec_name"] = spec_a.text.strip() or "规格书.pdf"
return spec_info
def _fetch_api_data(self, product_id: str, headers: Dict, proxy: Dict) -> Dict:
"""获取动态接口数据(库存、阶梯价)"""
api_data = {}
timestamp = int(time.time() * 1000)
try:
if self.platform == "szlcsc":
api_params = {"productId": product_id, "t": timestamp}
response = requests.get(
self.config["api_url"],
params=api_params,
headers=headers,
proxies=proxy,
timeout=15
)
api_data = response.json()
elif self.platform == "mouser":
# 贸泽电子需品牌和型号,此处简化(真实场景需从product_id反向解析)
brand = "STMicroelectronics"
model = product_id # 假设product_id为型号(实际需调整)
api_params = {"brand": brand, "partNumber": model, "timestamp": timestamp}
response = requests.get(
self.config["api_url"],
params=api_params,
headers=headers,
proxies=proxy,
timeout=15
)
api_data = response.json()
except Exception as e:
print(f"动态接口请求失败:{str(e)}")
return api_data
def item_get(self, product_id: str, brand: str = "", model: str = "") -> Dict:
"""
获取电子元件商品详情
:param product_id: 商品ID(平台唯一标识)
:param brand: 品牌(贸泽、Digi-Key等平台必需)
:param model: 型号(部分平台必需)
:return: 标准化商品详情数据
"""
try:
# 1. 构建详情页URL(适配不同平台)
if self.platform == "szlcsc":
detail_url = self.config["detail_url"].format(product_id=product_id)
elif self.platform == "mouser":
if not brand or not model:
return {"success": False, "error_msg": "贸泽电子需传入brand和model", "code": -2}
detail_url = self.config["detail_url"].format(brand=brand, model=model)
else:
detail_url = self.config["detail_url"].format(brand=brand, model=model, product_id=product_id)
headers = self._get_headers()
proxy = self._get_proxy()
# 2. 随机延迟(避免反爬)
time.sleep(random.uniform(3, 6))
# 3. 请求详情页主HTML
response = requests.get(
url=detail_url,
headers=headers,
proxies=proxy,
timeout=15
)
response.raise_for_status() # 抛出HTTP错误(403/404等)
soup = BeautifulSoup(response.text, "lxml")
# 4. 验证商品是否存在(型号为空则视为不存在)
model = soup.select_one("h1.product-model, .part-number")?.text.strip() or ""
if not model:
return {"success": False, "error_msg": "商品不存在或已下架", "code": 404}
# 5. 解析静态数据
base_info = {
"product_id": product_id,
"model": model,
"brand": soup.select_one("div.brand-name, .manufacturer-name")?.text.strip() or brand,
"title": soup.select_one("h1.product-title, .product-name")?.text.strip() or "",
"url": detail_url,
"main_image": soup.select_one("div.main-img img, .product-image")?.get("src") or "",
"category": soup.select_one("div.breadcrumb a:last-of-type, .category-path")?.text.strip() or "",
"update_time": time.strftime("%Y-%m-%d %H:%M:%S")
}
params = self._parse_parameters(soup)
compliance_info = self._parse_compliance(soup)
spec_info = self._parse_spec(soup)
# 6. 请求并解析动态接口数据(库存、阶梯价)
api_data = self._fetch_api_data(product_id, headers, proxy)
base_price, ladder_prices = self._parse_ladder_prices(api_data)
stock_info = self._parse_stock(api_data, soup)
# 7. 解析供应商信息
seller_info = self._parse_seller(soup, api_data)
# 8. 整合最终数据
final_data = {
"success": True,
"data": {
"base_info": base_info,
"parameters": params,
"price_info": {
"base_price": base_price,
"ladder_prices": ladder_prices,
"currency": "CNY" if self.platform == "szlcsc" else "USD"
},
"stock_info": stock_info,
"seller_info": seller_info,
"compliance_info": compliance_info,
"spec_info": spec_info
}
}
return final_data
except requests.exceptions.HTTPError as e:
if "403" in str(e):
return {"success": False, "error_msg": "触发反爬,建议更换代理、Cookie或降低访问频率", "code": 403}
if "401" in str(e):
return {"success": False, "error_msg": "Cookie失效,请重新登录", "code": 401}
if "404" in str(e):
return {"success": False, "error_msg": "商品不存在", "code": 404}
return {"success": False, "error_msg": f"HTTP错误:{str(e)}", "code": response.status_code}
except Exception as e:
return {"success": False, "error_msg": f"详情获取失败:{str(e)}", "code": -1}
def _parse_seller(self, soup, api_data: Dict) -> Dict:
"""解析供应商信息"""
seller_info = {
"name": "",
"type": "",
"auth_status": False,
"shipping_place": "",
"delivery_time": ""
}
if self.platform == "szlcsc":
seller_info["name"] = "立创商城"
seller_info["type"] = "授权经销商"
seller_info["auth_status"] = True
seller_info["shipping_place"] = api_data.get("data", {}).get("warehouse", "深圳")
seller_info["delivery_time"] = "1-3天"
elif self.platform == "mouser":
seller_info["name"] = "贸泽电子(Mouser)"
seller_info["type"] = "原厂授权经销商"
seller_info["auth_status"] = True
seller_info["shipping_place"] = "香港/上海"
seller_info["delivery_time"] = "3-7天"
return seller_info
def calculate_purchase_cost(self, quantity: int) -> Tuple[float, str]:
"""
根据采购量计算总成本
:param quantity: 采购量
:return: (总成本, 单价单位)
"""
if not hasattr(self, "data") or not self.data.get("price_info", {}).get("ladder_prices"):
return 0.0, ""
ladder_prices = self.data["price_info"]["ladder_prices"]
# 匹配对应阶梯价
target_price = ladder_prices[-1]["price"] # 默认最高档价格
unit = ladder_prices[-1]["unit"]
for ladder in ladder_prices:
if ladder["min_quantity"] ≤ quantity ≤ ladder["max_quantity"]:
target_price = ladder["price"]
unit = ladder["unit"]
break
total_cost = quantity * target_price
return total_cost, unit
# 使用示例
if __name__ == "__main__":
# 配置参数(替换为实际值)
PROXIES = [
"http://123.45.67.89:8888",
"http://98.76.54.32:8080"
] # 高匿动态代理池
COOKIE = "" # 立创商城无需登录,留空;贸泽电子需填写企业账号Cookie
PRODUCT_ID = "123456" # 立创商城商品ID(0402 100nF 16V X7R 电容)
# 初始化API客户端(默认立创商城)
item_api = ElectronicItemGetApi(
platform="szlcsc",
proxy_pool=PROXIES,
cookie=COOKIE
)
# 获取商品详情
result = item_api.item_get(product_id=PRODUCT_ID)
# 结果输出
if result["success"]:
item_api.data = result["data"] # 保存数据供成本计算使用
data = result["data"]
print("=" * 80)
print(f"商品型号:{data['base_info']['model']} | 品牌:{data['base_info']['brand']}")
print(f"商品标题:{data['base_info']['title'][:80]}...")
print(f"详情页:{data['base_info']['url']}")
print("-" * 80)
print("核心参数:")
print(f" 封装:{data['parameters']['package']} | 材质:{data['parameters']['material']}")
print(f" 容值:{data['parameters']['capacitance']} | 电压:{data['parameters']['voltage']} | 精度:{data['parameters']['tolerance']}")
print(f" 工作温度:{data['parameters']['operating_temperature']} | 尺寸:{data['parameters']['dimension']}")
print("-" * 80)
print("价格信息:")
print(f" 基础单价:¥{data['price_info']['base_price']}/{data['price_info']['ladder_prices'][0]['unit']}")
if data['price_info']['ladder_prices']:
print(" 批量阶梯价:")
for ladder in data['price_info']['ladder_prices'][:5]: # 显示前5个阶梯
max_qty = "∞" if ladder['max_quantity'] == 999999 else ladder['max_quantity']
print(f" {ladder['min_quantity']}-{max_qty}个:¥{ladder['price']}/{ladder['unit']}")
# 计算采购1000个的成本
total_cost, unit = item_api.calculate_purchase_cost(1000)
print(f" 采购1000个总成本:¥{total_cost:.2f}(单价:¥{total_cost/1000:.3f}/{unit})")
print("-" * 80)
print("库存信息:")
print(f" 库存状态:{data['stock_info']['stock_status']} | 库存数量:{data['stock_info']['total_stock']}个")
print(f" 起订量:{data['stock_info']['min_order']}个")
print("-" * 80)
print("供应商信息:")
print(f" 名称:{data['seller_info']['name']} | 类型:{data['seller_info']['type']} | 授权状态:{'是' if data['seller_info']['auth_status'] else '否'}")
print(f" 发货地:{data['seller_info']['shipping_place']} | 配送时效:{data['seller_info']['delivery_time']}")
print("-" * 80)
print("合规信息:")
print(f" RoHS合规:{'是' if data['compliance_info']['rohs'] else '否'} | REACH合规:{'是' if data['compliance_info']['reach'] else '否'}")
print(f" 质量等级:{data['compliance_info']['quality_grade']} | 批次号:{data['compliance_info']['batch_number'] or '未公开'}")
print("-" * 80)
print("规格书信息:")
print(f" 是否提供:{'是' if data['spec_info']['has_spec'] else '否'}")
if data['spec_info']['has_spec']:
print(f" 下载链接:{data['spec_info']['spec_url']}")
print("=" * 80)
else:
print(f"获取失败:{result['error_msg']}(错误码:{result.get('code')})")