diff --git a/reply_server.py b/reply_server.py index f4cb163..1c9df63 100644 --- a/reply_server.py +++ b/reply_server.py @@ -2851,32 +2851,6 @@ async def search_multiple_pages( raise HTTPException(status_code=500, detail=f"多页商品搜索失败: {error_msg}") -@app.get("/items/detail/{item_id}") -async def get_public_item_detail( - item_id: str, - current_user: Optional[Dict[str, Any]] = Depends(get_current_user_optional) -): - """获取公开商品详情(通过外部API)""" - try: - from utils.item_search import get_item_detail_from_api - - # 从外部API获取商品详情 - detail = await get_item_detail_from_api(item_id) - - if detail: - return { - "success": True, - "data": detail - } - else: - raise HTTPException(status_code=404, detail="商品详情获取失败") - - except HTTPException: - raise - except Exception as e: - logger.error(f"获取商品详情失败: {str(e)}") - raise HTTPException(status_code=500, detail=f"获取商品详情失败: {str(e)}") - @app.get("/items/cookie/{cookie_id}") def get_items_by_cookie(cookie_id: str, current_user: Dict[str, Any] = Depends(get_current_user)): diff --git a/utils/item_search.py b/utils/item_search.py index d9cb54c..dc1e622 100644 --- a/utils/item_search.py +++ b/utils/item_search.py @@ -57,23 +57,6 @@ class XianyuSearcher: return default return data - async def test_browser_launch(self): - """测试浏览器是否能正常启动""" - try: - if not PLAYWRIGHT_AVAILABLE: - return False, "Playwright 未安装" - - playwright = await async_playwright().start() - browser = await playwright.chromium.launch(headless=True) - context = await browser.new_context() - page = await context.new_page() - await page.goto("https://www.baidu.com") - await asyncio.sleep(2) - await browser.close() - return True, "浏览器测试成功" - except Exception as e: - return False, f"浏览器测试失败: {str(e)}" - async def get_first_valid_cookie(self): """获取第一个有效的cookie""" try: @@ -889,123 +872,6 @@ class XianyuSearcher: } - - - async def _parse_item_old(self, item_data: Dict[str, Any]) -> Optional[Dict[str, Any]]: - """ - 解析单个商品数据 - - Args: - item_data: 商品原始数据 - - Returns: - 解析后的商品信息 - """ - try: - # 基本信息 - 适配多种可能的字段名 - item_id = (item_data.get('id') or - item_data.get('itemId') or - item_data.get('item_id') or - item_data.get('spuId') or '') - - title = (item_data.get('title') or - item_data.get('name') or - item_data.get('itemTitle') or - item_data.get('subject') or '') - - # 价格处理 - price_raw = (item_data.get('price') or - item_data.get('priceText') or - item_data.get('currentPrice') or - item_data.get('realPrice') or '') - - # 清理价格格式 - if isinstance(price_raw, (int, float)): - price = str(price_raw) - elif isinstance(price_raw, str): - price = price_raw.replace('¥', '').replace('元', '').strip() - else: - price = '价格面议' - - # 卖家信息 - seller_info = (item_data.get('seller') or - item_data.get('user') or - item_data.get('owner') or {}) - - seller_name = '' - if seller_info: - seller_name = (seller_info.get('nick') or - seller_info.get('nickname') or - seller_info.get('name') or - seller_info.get('userName') or '匿名用户') - - # 商品链接 - if item_id: - item_url = f"https://www.goofish.com/item?id={item_id}" - else: - item_url = item_data.get('url', item_data.get('link', '')) - - # 发布时间 - publish_time = (item_data.get('publishTime') or - item_data.get('createTime') or - item_data.get('gmtCreate') or - item_data.get('time') or '') - - # 格式化时间 - if publish_time and isinstance(publish_time, (int, float)): - import datetime - publish_time = datetime.datetime.fromtimestamp(publish_time / 1000).strftime('%Y-%m-%d') - - # 商品标签 - tags = item_data.get('tags', item_data.get('labels', [])) - tag_names = [] - if isinstance(tags, list): - for tag in tags: - if isinstance(tag, dict): - tag_name = (tag.get('name') or - tag.get('text') or - tag.get('label') or '') - if tag_name: - tag_names.append(tag_name) - elif isinstance(tag, str): - tag_names.append(tag) - - # 图片 - images = (item_data.get('images') or - item_data.get('pics') or - item_data.get('pictures') or - item_data.get('imgList') or []) - - main_image = '' - if images and len(images) > 0: - if isinstance(images[0], str): - main_image = images[0] - elif isinstance(images[0], dict): - main_image = (images[0].get('url') or - images[0].get('src') or - images[0].get('image') or '') - - # 如果没有图片,使用默认占位图 - if not main_image: - main_image = f'https://via.placeholder.com/200x200?text={title[:10] if title else "商品"}...' - - return { - 'item_id': item_id, - 'title': title, - 'price': price, - 'seller_name': seller_name, - 'item_url': item_url, - 'publish_time': publish_time, - 'tags': tag_names, - 'main_image': main_image, - 'raw_data': item_data # 保留原始数据以备后用 - } - - except Exception as e: - logger.warning(f"解析商品数据失败: {str(e)}") - return None - - # 搜索器工具函数 async def search_xianyu_items(keyword: str, page: int = 1, page_size: int = 20) -> Dict[str, Any]: @@ -1130,50 +996,3 @@ async def search_multiple_pages_xianyu(keyword: str, total_pages: int = 1) -> Di - -async def get_item_detail_from_api(item_id: str) -> Optional[str]: - """ - 从外部API获取商品详情 - - Args: - item_id: 商品ID - - Returns: - 商品详情文本,获取失败返回None - """ - try: - # 使用默认的API配置 - api_base_url = 'https://selfapi.zhinianboke.com/api/getItemDetail' - timeout_seconds = 10 - - api_url = f"{api_base_url}/{item_id}" - - logger.info(f"正在从外部API获取商品详情: {item_id}") - - # 使用简单的HTTP请求 - import aiohttp - timeout = aiohttp.ClientTimeout(total=timeout_seconds) - - async with aiohttp.ClientSession(timeout=timeout) as session: - async with session.get(api_url) as response: - if response.status == 200: - result = await response.json() - - # 检查返回状态 - if result.get('status') == '200' and result.get('data'): - item_detail = result['data'] - logger.info(f"成功获取商品详情: {item_id}, 长度: {len(item_detail)}") - return item_detail - else: - logger.warning(f"API返回状态异常: {result.get('status')}, message: {result.get('message')}") - return None - else: - logger.warning(f"API请求失败: HTTP {response.status}") - return None - - except asyncio.TimeoutError: - logger.warning(f"获取商品详情超时: {item_id}") - return None - except Exception as e: - logger.error(f"获取商品详情异常: {item_id}, 错误: {str(e)}") - return None