109 lines
4.4 KiB
Python
109 lines
4.4 KiB
Python
"""商机产线数据能力:从数据爬取平台拉取招标数据(只读)。
|
||
|
||
所有函数签名统一 (sor, **params),返回 (ok, payload|错误信息)。
|
||
薄封装:查询条件透传给爬虫平台,本层不做二次加工(热点排序由爬虫平台算)。
|
||
"""
|
||
|
||
from .opp_common import crawler_get
|
||
|
||
|
||
async def search_tenders(sor, keyword="", days=7, source="", only_it=True, limit=50):
|
||
"""关键词检索招标信息。"""
|
||
params = {"days": days, "limit": limit}
|
||
if keyword:
|
||
params["keyword"] = keyword
|
||
if source:
|
||
params["source"] = source
|
||
params["only_it"] = "1" if only_it else "0"
|
||
return await crawler_get(sor, "/api/tenders", params)
|
||
|
||
|
||
async def tender_detail(sor, tender_id):
|
||
"""单条招标详情(含公告全文、来源 url)。"""
|
||
return await crawler_get(sor, "/api/tenders/%s" % tender_id)
|
||
|
||
|
||
async def daily_ai_tenders(sor, target_date=""):
|
||
"""每日 AI/Agent 软件类招标展示数据。"""
|
||
params = {}
|
||
if target_date:
|
||
params["date"] = target_date
|
||
return await crawler_get(sor, "/api/ai_tenders", params)
|
||
|
||
|
||
async def hot_software(sor, days=30, top=10):
|
||
"""热点软件主题排名(数量+预算+热点地区+样例)。"""
|
||
return await crawler_get(sor, "/api/hot_software",
|
||
{"days": days, "top": top})
|
||
|
||
|
||
async def category_references(sor, category, days=30, limit=500, record_type="tender"):
|
||
"""某软件主题的全部分项(references 可查证)。
|
||
|
||
每条带公告原文/详情页 url + 采集来源 source_url,供界面逐条查证。
|
||
record_type: tender=招标(默认) / demand=众包需求发布(猪八戒/一品威客)。
|
||
"""
|
||
return await crawler_get(sor, "/api/category_references",
|
||
{"category": category, "days": days, "limit": limit,
|
||
"record_type": record_type})
|
||
|
||
|
||
async def crawler_stats(sor):
|
||
"""爬虫平台采集健康度。"""
|
||
return await crawler_get(sor, "/api/stats")
|
||
|
||
|
||
async def demands(sor, keyword="", days=30, source="", limit=50):
|
||
"""众包平台软件需求发布列表(国内:猪八戒/一品威客;海外:Freelancer/PeoplePerHour)。
|
||
|
||
区别于招标:这些是甲方在众包平台直接发布的开发需求,
|
||
反映市场真实需求热度与预算分布。每条带详情页 url(可查证)。
|
||
"""
|
||
params = {"days": days, "limit": limit}
|
||
if keyword:
|
||
params["keyword"] = keyword
|
||
if source:
|
||
params["source"] = source
|
||
return await crawler_get(sor, "/api/demands", params)
|
||
|
||
|
||
async def hot_demands(sor, days=30, top=10):
|
||
"""众包需求热点主题排名(需求侧热度)。"""
|
||
return await crawler_get(sor, "/api/hot_demands",
|
||
{"days": days, "top": top})
|
||
|
||
|
||
async def hot_overseas(sor, days=30, top=10):
|
||
"""海外众包软件需求热点主题排名(Freelancer/PeoplePerHour,英文主题)。"""
|
||
return await crawler_get(sor, "/api/hot_overseas",
|
||
{"days": days, "top": top})
|
||
|
||
|
||
async def overseas_references(sor, category, days=30, limit=500):
|
||
"""某海外需求主题的全部分项(references 可查证)。
|
||
|
||
每条带海外平台详情页 url,供界面逐条查证。
|
||
"""
|
||
return await crawler_get(sor, "/api/overseas_references",
|
||
{"category": category, "days": days, "limit": limit})
|
||
|
||
|
||
async def query_tenders(sor, keyword="", region="", buyer="", notice_type="",
|
||
source="", min_budget="", max_budget="", min_ai="",
|
||
days=90, group_by="", limit=50, only_it=True):
|
||
"""条件检索 + 汇总(用户口述条件 → LLM 映射为参数)。
|
||
|
||
过滤:keyword(标题多词AND)/region/buyer 模糊,notice_type/source 精确,
|
||
min_budget/max_budget(万元)区间,min_ai 评分下限,days 回溯窗口,only_it。
|
||
汇总:group_by=region|notice_type|category|source|month → 分组统计+样例。
|
||
"""
|
||
params: dict = {"days": days, "limit": limit}
|
||
for k, v in (("keyword", keyword), ("region", region), ("buyer", buyer),
|
||
("notice_type", notice_type), ("source", source),
|
||
("min_budget", min_budget), ("max_budget", max_budget),
|
||
("min_ai", min_ai), ("group_by", group_by)):
|
||
if v not in (None, ""):
|
||
params[k] = v
|
||
params["only_it"] = "1" if only_it else "0"
|
||
return await crawler_get(sor, "/api/tenders_query", params)
|