×

58 同城 item_search - 获取搜索数据接口对接全攻略:从入门到精通

万邦科技Lex 万邦科技Lex 发表于2026-01-19 15:35:32 浏览63 评论0

抢沙发发表评论


58 同城 item_search 接口(官方标准命名 58 同城.item.search)是按多维度条件筛选本地生活全品类信息列表的核心检索接口,覆盖房产、招聘、二手车、二手物品、家政服务等主流业务线。该接口采用 HTTPS+AppKey/Secret 签名认证,支持 JSON/XML 双格式返回,具备筛选维度丰富、多业务线适配、数据实时性强的特点,是联动 item_get 接口获取详情的前置依赖。本攻略从接口认知、权限准备、实操对接、调试排错到生产级优化,提供全链路标准化指导。


一、接口核心认知:功能与适配场景

1. 接口定位与核心价值

  • 核心功能:输入城市编码、业务线分类、关键词、价格区间等筛选条件,返回分页信息列表;支持按发布时间、价格、热度等维度排序,单页最大返回 50 条数据;可联动 city_list 接口获取标准城市编码,实现精准地域筛选。

  • 58 同城数据特性

    • 多业务线统一适配:一套接口支持所有本地生活品类检索,无需为不同业务线单独对接接口,降低集成成本;

    • 筛选维度贴合用户需求:针对不同品类提供专属筛选条件(如房产支持户型 / 朝向筛选、二手车支持品牌 / 里程筛选);

    • 数据实时性强:信息上架、下架、价格调整等动态数据1 分钟内同步,保障列表数据时效性;

    • 权限分级管控:基础列表数据对所有权限开放,敏感筛选条件(如个人房源、急售信息)需企业资质授权。

  • 典型应用场景

    1. 本地生活服务平台:构建多品类信息检索页面,支持用户按城市、品类、价格等条件筛选;

    2. 垂直领域获客工具:针对房产 / 招聘 / 二手车等单一品类,批量获取信息列表,生成目标客户清单;

    3. 市场行情分析系统:定时检索指定品类信息,统计价格走势、供需变化等市场数据;

    4. 个性化推荐工具:基于用户历史筛选行为,推送相似条件的信息列表。

2. 核心参数与返回字段

(1)请求参数(GET/POST 提交,需签名认证)

参数类型 参数名称 类型 是否必填 说明 应用示例
公共参数 app_key string 应用密钥(开放平台获取) 58_appkey_2026_abc123

secret string 应用秘钥(开放平台获取) 58_secret_2026_def456

api_name string 接口名称,固定为item_search 58同城.item.search

format string 响应格式,默认 JSON json/xml

v string 接口版本,固定为1.0 1.0

timestamp string 秒级时间戳,与服务器时差≤10 分钟 1735689600
业务参数 city_id string 城市编码(从city_list接口获取) 1(北京)/2(上海)

cate_id string 业务线分类 ID 1(房产)/2(招聘)/3(二手车)

q string 搜索关键词,需 URL 编码 两室一厅 地铁房/二手车 大众

price_min float 最低价格(单位随品类变化) 房产(万元)/ 招聘(元 / 月)/ 二手车(万元)

price_max float 最高价格 同上

sort_type string 排序方式 pub_time_desc(最新发布)/price_asc(低价优先)/hot_desc(热度优先)

page_num int 页码,默认 1 2

page_size int 单页条数,默认 20,最大 50 50

filter string 品类专属筛选条件(JSON 格式) 房产:{"house_style":"2室1厅","orientation":"南向"}

注意事项

  1. city_idcate_id 为必填业务参数,需分别从 city_list 接口和开放平台品类文档获取标准值;

  2. timestamp 参数为秒级时间戳,与服务器时间误差超过 10 分钟会直接导致签名验证失败;

  3. filter 参数需为标准 JSON 字符串,不同品类的筛选字段不同,需参考官方文档传入;

  4. 签名生成需包含所有非空参数,按参数名 ASCII 升序排序后拼接secret进行 MD5 加密,参数缺失会导致认证失败。

(2)返回核心字段(按业务线分类)

字段分类 核心字段 说明
公共字段 item_id、title、cate_name、price、publish_time、update_time、status、view_count、support_tags status:有效 / 已下架 / 审核中;support_tags:配套标签列表
房产类 house_style、area_build、orientation、floor、metro_tag metro_tag:是否地铁房(是 / 否)
招聘类 company_name、salary、work_address、job_type salary:薪资范围(如 “5000-8000 元 / 月”)
二手车类 brand、model、year、mileage、displacement year:上牌年份;mileage:万公里数
二手物品类 new_degree、address new_degree:新旧程度(如 “9 成新”)
分页信息 total、page_num、page_size、has_next total:搜索结果总条数;has_next:是否有下一页

提示:item_search 接口仅返回信息基础属性,联系人、详细地址、媒体资源等深度信息需调用 item_get 接口获取。

3. 接口限制与注意事项

权限类型 日调用上限 调用频率 适用场景
个人测试权限 200 次 / 天 2 次 / 秒 功能调试、个人信息查询
企业基础权限 2000 次 / 天 5 次 / 秒 中小型本地服务平台、中介系统
企业高级权限 20000 次 / 天 15 次 / 秒 大型数据服务商、全国性本地生活平台
  • 数据缓存规则:列表数据缓存10 分钟,短时间内重复调用相同筛选条件的接口会直接返回缓存数据;

  • 调用频率限制:超出频率上限会触发临时封禁 15 分钟,多次超限会导致账号权限降级;

  • 地域限制:部分城市的房产、招聘信息受本地监管政策限制,仅对本地备案企业开放;

  • 合规要求:数据仅可用于自有平台展示或合法商业分析,严禁转售、篡改或用于骚扰式营销。


二、对接前准备:权限与环境搭建

1. 获取接口权限(官方唯一合规路径)

58 同城 item_search 接口的权限需通过58 同城开放平台申请,步骤如下:

  1. 登录 58 同城开放平台,注册企业 / 个人开发者账号;

  2. 提交资质审核:

    • 企业用户:上传营业执照、法人身份证、业务范围说明(如 “本地生活信息平台开发”);

    • 个人用户:上传身份证,填写应用用途(如 “个人租房信息检索工具”);

  3. 创建应用,填写应用名称、服务器 IP 白名单、数据用途说明,提交审核;

  4. 审核通过后,在 “应用管理 - 密钥管理” 中获取 app_keysecret(接口调用核心凭证);

  5. 申请 58同城.item.search 接口权限,基础权限审核周期为 1-3 个工作日,高级权限需额外提交《数据合规使用承诺书》。

风险提示:严禁通过非官方爬虫抓取 58 同城列表数据,违反协议会导致账号封禁并承担法律责任。

2. 技术环境准备

(1)支持语言与协议

  • 协议:HTTPS(强制),HTTP 请求会被直接拦截并返回 403 错误;

  • 开发语言:Python、Java、PHP、Go 等主流语言均可,推荐 Python(代码简洁,适配异步并发与多品类数据解析)。

(2)必备工具与依赖

工具类型 推荐工具 用途
调试工具 58 同城开放平台调试工具 在线填写参数、生成签名、测试接口响应

Postman 模拟 GET/POST 请求,保存不同品类的筛选测试用例
开发依赖(Python) requests 发送 HTTPS 请求

hashlib 生成 MD5 签名

jsonpath-ng 快速解析 JSON 格式的列表数据

pandas 整理多品类信息列表并导出 Excel
辅助工具 Redis 缓存搜索结果,减少重复调用

logging 记录接口调用日志,便于问题排查与审计

三、实操步骤:接口对接全流程(Python 示例)

步骤 1:理解签名认证规则(核心,必掌握)

58 同城所有接口采用统一的 app_key+secret+timestamp 签名认证 机制,item_search 接口的签名生成步骤如下:

  1. 收集所有非空请求参数(含公共参数app_key/api_name/timestamp等 + 业务参数city_id/cate_id等);

  2. 按参数名ASCII 升序排序(如api_name排在app_key之前);

  3. 拼接参数为 key1value1key2value2... 的字符串格式(无分隔符,参数值需与传入一致);

  4. secret 拼接在参数串末尾,生成签名原串;

  5. 对原串进行 MD5 加密,转为大写字符串,即为签名 sign

  6. sign 添加到请求参数中,发送 HTTPS GET 请求。

步骤 2:完整代码实现(含签名生成 + 多品类适配 + 数据标准化)

(1)依赖安装

pip install requests hashlib jsonpath-ng pandas

(2)Python 代码实现

import requests
import hashlib
import time
import json
import logging
import pandas as pd
from urllib.parse import quote
from typing import Optional, Dict, List
# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
# 日志配置:记录调用日志,便于问题排查与审计
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s",
    handlers=[logging.FileHandler("58_item_search.log"), logging.StreamHandler()]
)

# 配置信息(替换为你的开放平台app_key/secret)
CONFIG = {
    "app_key": "你的app_key",
    "secret": "你的secret",
    "api_url": "https://openapi.58.com/item_search",
    "format": "json",
    "version": "1.0"
}

# 业务线分类映射(参考58开放平台文档)
CATE_MAP = {
    "1": "房产",
    "2": "招聘",
    "3": "二手车",
    "4": "二手物品"
}

def generate_sign(params: Dict[str, str], secret: str) -> str:
    """生成58同城接口签名(MD5加密,大写)"""
    # 1. 按参数名ASCII升序排序
    sorted_params = sorted(params.items(), key=lambda x: x[0])
    # 2. 拼接参数为 key1value1key2value2 格式
    param_str = "".join([f"{k}{v}" for k, v in sorted_params])
    # 3. 拼接secret并MD5加密,转大写
    sign_str = param_str + secret
    sign = hashlib.md5(sign_str.encode("utf-8")).hexdigest().upper()
    return sign

def standardize_item_data(raw_item: Dict, cate_id: str) -> Dict:
    """标准化信息列表数据,适配不同业务线"""
    # 公共字段标准化
    standard_data = {
        "信息ID": raw_item.get("item_id", ""),
        "标题": raw_item.get("title", ""),
        "业务线": CATE_MAP.get(cate_id, "未知"),
        "分类名称": raw_item.get("cate_name", ""),
        "发布时间": raw_item.get("publish_time", ""),
        "更新时间": raw_item.get("update_time", ""),
        "信息状态": raw_item.get("status", ""),
        "浏览量": raw_item.get("view_count", 0),
        "配套标签": ",".join(raw_item.get("support_tags", [])),
        "数据请求时间": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    }

    # 价格字段适配(不同业务线单位不同)
    price = raw_item.get("price", 0.0)
    if cate_id == "1":  # 房产
        price_unit = "万元" if raw_item.get("cate_name") in ["新房", "二手房"] else "元/月"
    elif cate_id == "2":  # 招聘
        price_unit = "元/月"
        price = raw_item.get("salary", "面议")
    elif cate_id == "3":  # 二手车
        price_unit = "万元"
    else:  # 二手物品
        price_unit = "元"
    standard_data["价格"] = f"{price}{price_unit}" if isinstance(price, (int, float)) else price

    # 品类专属字段适配
    if cate_id == "1":  # 房产
        standard_data.update({
            "户型": raw_item.get("house_style", ""),
            "建筑面积(㎡)": raw_item.get("area_build", 0.0),
            "朝向": raw_item.get("orientation", ""),
            "楼层": raw_item.get("floor", ""),
            "是否地铁房": raw_item.get("metro_tag", "否")
        })
    elif cate_id == "2":  # 招聘
        standard_data.update({
            "公司名称": raw_item.get("company_name", ""),
            "工作地址": raw_item.get("work_address", ""),
            "职位类型": raw_item.get("job_type", "")
        })
    elif cate_id == "3":  # 二手车
        standard_data.update({
            "品牌型号": f"{raw_item.get('brand', '')} {raw_item.get('model', '')}",
            "上牌年份": raw_item.get("year", ""),
            "里程数(万公里)": raw_item.get("mileage", 0.0)
        })
    elif cate_id == "4":  # 二手物品
        standard_data.update({
            "新旧程度": raw_item.get("new_degree", ""),
            "物品地址": raw_item.get("address", "")
        })

    return standard_data

def item_search_58(
    city_id: str,
    cate_id: str,
    q: Optional[str] = None,
    price_min: Optional[float] = None,
    price_max: Optional[float] = None,
    sort_type: str = "pub_time_desc",
    page_num: int = 1,
    page_size: int = 20,
    filter_json: Optional[Dict] = None
) -> Dict:
    """调用58同城item_search接口获取信息列表"""
    # 1. 校验必填参数
    if not (city_id and cate_id):
        return {"success": False, "error_msg": "city_id和cate_id为必填参数", "data": [], "pagination": {}}

    # 2. 构建公共参数
    params = {
        "app_key": CONFIG["app_key"],
        "api_name": "item_search",
        "format": CONFIG["format"],
        "v": CONFIG["version"],
        "timestamp": str(int(time.time())),  # 秒级时间戳
        "city_id": city_id,
        "cate_id": cate_id,
        "sort_type": sort_type,
        "page_num": str(page_num),
        "page_size": str(min(page_size, 50))  # 限制最大条数为50
    }

    # 3. 添加工业务参数
    if q:
        params["q"] = quote(q, encoding="utf-8")
    if price_min is not None:
        params["price_min"] = str(price_min)
    if price_max is not None:
        params["price_max"] = str(price_max)
    if filter_json:
        params["filter"] = json.dumps(filter_json, ensure_ascii=False)

    # 4. 生成签名
    sign = generate_sign(params, CONFIG["secret"])
    params["sign"] = sign

    try:
        # 5. 发送HTTPS请求
        response = requests.get(
            url=CONFIG["api_url"],
            params=params,
            timeout=15,
            verify=True  # 生产环境必须开启证书验证
        )
        response.raise_for_status()  # 抛出HTTP状态码异常
        result = response.json()

        # 6. 解析响应结果
        if result.get("status") != "success":
            error_msg = f"[{result.get('error_code', '未知错误')}] {result.get('error_msg', '无错误信息')}"
            logging.error(f"搜索失败(城市:{city_id},品类:{cate_id}):{error_msg}")
            return {"success": False, "error_msg": error_msg, "data": [], "pagination": {}}

        raw_items = result.get("data", {}).get("item_list", [])
        pagination = {
            "total": result.get("data", {}).get("total", 0),
            "page_num": page_num,
            "page_size": page_size,
            "has_next": result.get("data", {}).get("has_next", False)
        }

        if not raw_items:
            logging.warning(f"无匹配信息(城市:{city_id},品类:{cate_id})")
            return {"success": True, "error_msg": "", "data": [], "pagination": pagination}

        # 7. 标准化数据
        standard_items = [standardize_item_data(item, cate_id) for item in raw_items]
        return {
            "success": True,
            "error_msg": "",
            "data": standard_items,
            "pagination": pagination
        }

    except requests.exceptions.RequestException as e:
        logging.error(f"网络请求异常(城市:{city_id},品类:{cate_id}):{str(e)}")
        return {"success": False, "error_msg": f"网络异常:{str(e)}", "data": [], "pagination": {}}
    except Exception as e:
        logging.error(f"数据解析异常(城市:{city_id},品类:{cate_id}):{str(e)}")
        return {"success": False, "error_msg": f"解析异常:{str(e)}", "data": [], "pagination": {}}
# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
# 调用示例
if __name__ == "__main__":
    # 示例1:搜索北京市房产类信息(city_id=1,cate_id=1)
    # 筛选条件:两室一厅 地铁房 价格50-80万元
    city_id = "1"  # 北京
    cate_id = "1"  # 房产
    keyword = "两室一厅 地铁房"
    price_min = 50.0
    price_max = 80.0
    # 品类专属筛选条件
    filter_json = {
        "house_style": "2室1厅",
        "orientation": "南向"
    }

    result = item_search_58(
        city_id=city_id,
        cate_id=cate_id,
        q=keyword,
        price_min=price_min,
        price_max=price_max,
        sort_type="pub_time_desc",
        page_num=1,
        page_size=20,
        filter_json=filter_json
    )

    if result["success"]:
        print(f"搜索成功!共找到 {result['pagination']['total']} 条信息")
        print("=== 前5条信息 ===")
        for item in result["data"][:5]:
            print(f"{item['信息ID']} | {item['标题']} | {item['价格']} | {item['是否地铁房']}")
        # 保存为Excel
        df = pd.DataFrame(result["data"])
        df.to_excel(f"58同城{CATE_MAP[cate_id]}搜索结果_{keyword}.xlsx", index=False)
        # 翻页示例
        if result["pagination"]["has_next"]:
            next_page_result = item_search_58(
                city_id=city_id,
                cate_id=cate_id,
                q=keyword,
                price_min=price_min,
                price_max=price_max,
                page_num=2,
                page_size=20,
                filter_json=filter_json
            )
            print(f"下一页获取到 {len(next_page_result['data'])} 条信息")
    else:
        print(f"获取失败:{result['error_msg']}")

四、调试与问题排查:快速解决对接异常

1. 优先用官方工具调试(排除签名与参数问题)

  1. 登录 58 同城开放平台调试工具,选择 item_search 接口;

  2. 输入city_idcate_idq等参数,点击 “生成签名” 并发送请求;

  3. 若官方工具调用成功 → 问题出在代码的签名生成逻辑或参数拼接错误(如关键词未 URL 编码、filter 参数未转 JSON 字符串);

  4. 若官方工具调用失败 → 问题出在权限配置或参数有效性(如城市编码错误、IP 未加入白名单)。

2. 高频问题排查表

问题现象常见原因解决方案
签名验证失败(401)1. app_key/secret 错误或过期;2. 参数未按 ASCII 升序排序;3. timestamp 非秒级或与服务器时差 > 10 分钟;4. filter 参数非标准 JSON 字符串1. 核对开放平台的 app_key/secret,过期则重新申请;2. 严格按参数名 ASCII 升序排序所有非空参数;3. 确保 timestamp 为秒级时间戳,同步服务器时间;4. 将 filter 字典转为标准 JSON 字符串,避免特殊字符
权限不足(403)1. 未申请item_search接口权限;2. 服务器 IP 不在白名单;3. 调用频率超限;4. 使用敏感筛选条件但无高级权限1. 在开放平台 “权限管理” 中申请对应接口;2. 添加服务器公网 IP 到应用白名单;3. 降低调用频率,控制并发数≤权限上限;4. 移除敏感筛选条件或升级企业高级权限
参数错误(400)1. city_id/cate_id 为空或非法;2. price_min > price_max;3. filter 参数字段与 cate_id 不匹配1. 从city_list接口获取标准城市编码,参考文档确认 cate_id;2. 校验价格区间合法性,确保 price_min ≤ price_max;3. 仅传入当前品类支持的筛选字段,参考官方文档
无数据返回(200 但 data 为空)1. 筛选条件过严(如价格区间过小);2. city_id 正确但无对应品类信息;3. 信息受地域监管限制1. 放宽筛选条件(如扩大价格区间、移除部分 filter 字段);2. 更换 city_id 或 cate_id 测试;3. 联系开放平台客服确认地域权限
响应超时(504)1. 网络波动或服务器负载高;2. page_size 设置过大(如 50)且筛选结果多;3. 高峰期调用(工作日 9:00-12:00/14:00-18:00)1. 添加重试机制,设置超时时间为 15 秒;2. 减小 page_size(如改为 20),分批次获取数据;3. 避开高峰期调用,调度到凌晨低峰期

五、进阶优化:生产级稳定性提升

1. 性能与配额优化

  • 批量翻页优化:通过 pagination.has_next 字段判断是否继续翻页,采用 异步并发框架(如 Python 的aiohttp)批量获取多页数据,并发数严格控制在权限允许的频率上限内(如企业基础权限 5 次 / 秒);避免同步循环翻页导致的效率低下。

  • 智能缓存策略:用 Redis 缓存搜索结果,缓存 key 设计为 58_search_城市ID_品类ID_关键词_价格区间,缓存时间区分场景:

    • 热门城市 / 高频关键词:缓存 10 分钟;

    • 冷门城市 / 低频关键词:缓存 30 分钟;

      缓存失效触发条件:当接口返回的total数据量变化超过 10% 时,主动更新缓存。

  • 筛选条件预处理:前端筛选组件做参数合法性校验,例如:

    • 限制price_minprice_max

    • 仅展示当前品类支持的筛选字段;

    • 对关键词做长度和敏感词过滤;

      减少无效的接口调用。

2. 数据质量优化

  • 数据清洗与标准化

    1. item_id去重,避免同一信息重复出现在不同页码或不同筛选条件的结果中;

    2. 过滤异常值(如价格≤0、面积≤0 的房产信息);

    3. 统一字段格式(如薪资范围统一为 “X-Y 元 / 月”,新旧程度统一为 “X 成新”);

    4. 缺失值填充(如无朝向信息的房产填充为 “未知朝向”)。

  • 多品类适配优化:根据cate_id动态解析和展示字段,避免非目标品类字段干扰(如查询二手车时隐藏房产相关字段)。

3. 合规与安全优化

  • 密钥安全管理:生产环境禁止硬编码 app_key/secret,推荐两种存储方式:

    1. 配置中心存储:将密钥存入 Nacos、Apollo 等配置中心,应用启动时动态拉取;

    2. 环境变量存储:通过os.environ.get("58_APP_KEY")读取,避免代码泄露风险;

      定期轮换密钥(建议每 3 个月一次)。

  • 重试与熔断机制

    1. 临时性错误(403 频率超限、504 超时),采用指数退避重试策略(首次间隔 1 秒,之后翻倍,最多重试 3 次);

    2. 永久性错误(401 签名错误、400 参数错误),直接抛出异常,不重试;

    3. 引入熔断机制(如pybreaker库),当接口连续失败次数≥5 次时,暂停调用 5 分钟,避免雪崩效应。

  • 日志审计:记录每次调用的城市 ID、品类 ID、筛选条件、响应状态、耗时、返回数据量等信息,日志保留至少 30 天,满足合规审计要求。


六、扩展场景:接口联动与功能升级

  1. 全链路数据采集:联动 city_list 获取城市编码 → item_search 按城市 / 品类筛选信息列表 → item_get 批量获取详情,实现 “城市→列表→详情” 的完整数据链路;

  2. 本地生活服务平台搭建:整合多品类搜索结果,搭建一站式本地生活检索平台,支持用户按城市、品类、价格等条件筛选和比价;

  3. 信息监控预警系统:定时调用 item_search 接口,监控指定品类的信息发布、价格变化,当出现符合条件的信息(如低价二手房、高薪职位)时,通过邮件 / 短信推送预警;

  4. 商家获客智能助手:针对二手物品、家政服务等品类,批量获取信息列表,筛选高意向客户(如价格低于市场价的卖家),辅助商家精准跟进。


群贤毕至

访客