GPTs趋势追踪:Python爬虫与数据分析实战指南
1. 项目概述:GPTs趋势追踪的价值与挑战
如果你和我一样,每天都会花些时间在ChatGPT的GPTs商店里“寻宝”,那你肯定也遇到过类似的困扰:商店里的GPTs数量每天都在爆炸式增长,但官方推荐和排行榜的更新似乎总慢半拍,而且分类方式也未必完全符合你的实际需求。你可能会想,有没有一个更实时、更透明、甚至能按自己口味定制的“风向标”呢?这正是我今天想和你深入聊聊的“gpts-trending”项目。简单来说,它是一个致力于自动抓取、记录和分析ChatGPT GPTs商店每日热门榜单的开源项目。它不只是一个简单的爬虫,更像是一个为开发者和重度用户打造的“数据雷达”,帮助我们穿透官方商店的迷雾,看清哪些GPTs正在真正流行,以及它们背后的趋势。
这个项目的核心价值,在于它解决了信息获取的“时效性”和“颗粒度”问题。官方榜单可能一天一更,但一个爆款GPT的崛起有时就在几小时之间。通过自动化脚本, gpts-trending 可以更高频地(比如每小时)捕获数据,让我们能捕捉到那些转瞬即逝的“趋势苗头”。更重要的是,它把数据“扒”下来后,进行了结构化的整理和归档。这意味着你可以回溯查看历史上任何一天的热门GPTs,分析某个垂直领域(比如编程、写作、设计)的长期趋势变化,甚至对比不同时间点的榜单差异,看看哪些是昙花一现,哪些是常青树。
对于开发者而言,这个项目的意义更为重大。它提供了一个绝佳的“市场调研”工具。通过观察趋势榜单,你可以快速了解当前用户最需要什么类型的功能(比如最近是不是AI绘画提示词生成器特别火?),哪些描述话术或功能组合更吸引人,从而为自己的GPTs开发提供灵感方向和竞争分析。它也是一个学习案例库,你可以直接研究那些成功上榜的GPTs,看它们的命名、描述、开场白和指令(Prompt)设计有何高明之处。
接下来,我将为你拆解这个项目的实现思路、技术细节、实操方法,并分享我在部署和使用过程中踩过的坑和总结的经验。无论你是想自己搭建一个类似的监控系统,还是单纯想更好地利用这个项目提供的数据,相信下面的内容都会对你有所帮助。
2. 核心思路与技术选型解析
要构建一个稳定、可持续的GPTs趋势追踪系统,不能只靠手动刷新网页。我们需要一套自动化的方案,其核心工作流可以概括为: 定时触发 -> 模拟访问 -> 数据抓取 -> 清洗解析 -> 结构化存储 -> 可视化展示 。 gpts-trending 项目正是围绕这个流程进行技术选型和设计的。
2.1 为什么选择Python作为主力语言?
项目主要使用Python,这是一个非常务实的选择。首先,在数据抓取(爬虫)和数据处理领域,Python拥有无与伦比的生态优势。像 requests 、 httpx 、 aiohttp 这样的库让HTTP请求变得极其简单,而 BeautifulSoup 、 lxml 、 parsel 则是HTML/XML解析的利器。对于可能遇到的反爬机制, selenium 或 playwright 可以模拟真实浏览器行为。其次,数据处理和归档方面, pandas 能轻松进行数据清洗和分析, sqlite3 或 SQLAlchemy 便于轻量级数据存储, json 和 csv 模块用于标准化输出。最后,Python脚本易于部署到各种云服务器或函数计算平台,实现7x24小时无人值守运行。选择Python,意味着开发者可以将主要精力集中在业务逻辑(如何定位和解析榜单数据)上,而不是与底层网络或语法搏斗。
2.2 数据抓取策略:直面动态渲染的挑战
ChatGPT的GPTs商店页面是典型的现代单页应用(SPA),其内容大量依赖JavaScript动态渲染。这意味着你不能简单地用 requests 库获取HTML然后解析,因为初始返回的HTML可能只是一个空壳,关键的榜单数据是通过后续的API请求异步加载的。项目需要应对这个挑战。
方案一:无头浏览器模拟。 这是最直接但资源消耗较大的方法。使用 playwright 或 selenium 启动一个无头Chrome或Firefox浏览器,完全模拟用户操作打开GPTs商店页面,等待页面完全加载、所有动态内容渲染完毕,再从完整的DOM树中提取数据。这种方法的优点是能100%还原用户所见,不易被简单的反爬策略阻挡。缺点是运行速度慢,占用内存和CPU资源多,不适合在高频定时任务中密集使用。
方案二:逆向工程API接口。 这是更高效、更优雅的方案。通过浏览器的开发者工具(F12),切换到Network(网络)选项卡,刷新GPTs商店页面,观察加载过程中发起了哪些XHR或Fetch请求。通常,你会发现一个返回榜单数据的API接口,其响应是结构化的JSON格式。直接模拟请求这个API,可以绕过页面渲染,直接拿到最纯净的数据。这种方法速度快、消耗低,是爬虫项目的首选。难点在于需要解析请求的Headers(尤其是认证相关的 Authorization 头或 Cookie )以及可能的查询参数,并处理接口可能发生的变更。
实操心得 :在实际操作中,我推荐采用“ API优先,浏览器降级 ”的策略。首先花时间逆向分析官方接口。如果接口稳定且易于模拟,就作为主要数据源。同时,将无头浏览器方案作为备用方案写在代码里,当API接口失效或结构大变时,可以自动切换或发出警报,保证系统的鲁棒性。
2.3 数据存储与版本管理设计
抓取到的数据需要持久化保存,以便进行历史追溯和趋势分析。这里涉及到两个层面的设计:
1. 原始数据快照存储: 每次抓取,建议将原始的API响应JSON或解析前的完整HTML保存下来。可以按日期和时间建立目录结构,例如 ./data/raw/2025/02/2025-02-20_12-00-00.json 。这样做的好处是,即使后续解析规则升级,你仍然拥有最原始的数据,可以重新处理。存储格式首选压缩后的JSON文件,平衡了可读性和存储空间。
2. 结构化数据存储: 将解析后的核心信息(如GPT名称、开发者、描述、分类、上榜时间、排名等)存入结构化的数据库。对于个人或小规模使用,SQLite是完美选择,它无需安装单独的数据库服务,单个文件易于备份和迁移。可以设计一张 gpts_trending 表,包含上述字段。如果数据量增长迅猛,可以考虑迁移到PostgreSQL或MySQL。
3. 版本管理与更新判断: 榜单数据是随时间变化的。简单的做法是每次抓取都全量存储。更精细的做法是,只存储发生变化的部分。例如,对比本次解析出的GPTs列表与数据库中最近一次记录,只将新上榜、排名变化或下榜的GPTs记录为一条新版本,并打上时间戳。这可以显著减少冗余数据,但逻辑更复杂。 gpts-trending 项目采用按天归档的方式,每天生成一个Markdown文件来记录当日的分类榜单,这是一种轻量且对人类友好的方式,非常适合通过Git进行版本管理和在GitHub Pages上直接展示。
3. 关键实现步骤与代码拆解
让我们深入到代码层面,看看如何一步步实现这个系统。我将以一个基于API逆向和SQLite存储的简化版为例进行说明。
3.1 环境准备与依赖安装
首先,创建一个干净的Python虚拟环境并安装核心依赖。这能避免包版本冲突。
# 创建项目目录并进入
mkdir gpts-trending-analyzer && cd gpts-trending-analyzer
# 创建虚拟环境(以venv为例)
python -m venv venv
# 激活虚拟环境
# Windows: venv\Scripts\activate
# Linux/Mac: source venv/bin/activate
# 安装核心库
pip install requests httpx beautifulsoup4 pandas sqlite-utils schedule
# 如果需要备用浏览器方案,安装playwright
pip install playwright
playwright install chromium
3.2 逆向分析GPTs商店API
这是最关键也是最需要耐心的一步。打开Chrome浏览器,访问GPTs商店页面,按F12打开开发者工具。
- 清除Network日志,然后刷新页面。
- 在Network选项卡中,过滤
Fetch/XHR请求。 - 仔细查看每个请求的Preview(预览)或Response(响应),寻找包含
gpts、list、ranking、featured等关键词且返回数据是GPTs列表的请求。 - 找到目标请求后,查看其Headers(请求头),重点关注:
Authorization: 可能包含Bearer Token,这是模拟请求的关键。Cookie: 会话信息。User-Agent: 需要设置为常见的浏览器UA。Content-Type: 通常是application/json。
- 查看请求的Payload(负载)或Query String Parameters(查询参数),了解分页、分类筛选等参数。
假设我们找到了一个疑似接口: https://api.openai.com/v1/gpts/collections/trending ,请求方法为GET。
3.3 构建数据抓取脚本
基于上面的发现,我们编写核心抓取脚本 crawler.py 。
import requests
import json
import sqlite3
from datetime import datetime
import os
from typing import List, Dict, Any
# 配置部分
API_URL = "https://api.openai.com/v1/gpts/collections/trending"
# !!! 重要:这里的HEADERS需要你根据实际逆向结果填充,特别是Authorization。
# 直接从浏览器复制完整的请求头字符串可能更可靠。
HEADERS = {
"Accept": "application/json",
"Authorization": "Bearer YOUR_ACTUAL_TOKEN_HERE", # 需要替换
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Referer": "https://chat.openai.com/gpts",
}
DB_PATH = "./data/trending.db"
RAW_DATA_DIR = "./data/raw"
def ensure_dirs():
"""确保数据目录存在"""
os.makedirs(RAW_DATA_DIR, exist_ok=True)
os.makedirs(os.path.dirname(DB_PATH), exist_ok=True)
def fetch_trending_gpts() -> Dict[str, Any]:
"""从API抓取趋势数据"""
try:
response = requests.get(API_URL, headers=HEADERS, timeout=30)
response.raise_for_status() # 检查HTTP错误
data = response.json()
return data
except requests.exceptions.RequestException as e:
print(f"请求API失败: {e}")
# 这里可以触发降级策略,调用备用浏览器抓取函数
return None
except json.JSONDecodeError as e:
print(f"解析JSON响应失败: {e}")
return None
def save_raw_data(data: Dict[str, Any]):
"""保存原始API响应为JSON文件,用于备份和调试"""
if not data:
return
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"trending_{timestamp}.json"
filepath = os.path.join(RAW_DATA_DIR, filename)
with open(filepath, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
print(f"原始数据已保存至: {filepath}")
def parse_gpts_list(api_data: Dict[str, Any]) -> List[Dict[str, Any]]:
"""解析API数据,提取GPTs列表信息"""
gpts_list = []
# 注意:这里的解析路径需要根据实际的API响应结构进行调整
# 假设数据结构为:{ "collections": [ { "name": "Featured", "gpts": [...] }, ... ] }
collections = api_data.get("collections", [])
for collection in collections:
category = collection.get("name", "Unknown")
gpts_items = collection.get("gpts", [])
for idx, item in enumerate(gpts_items, start=1):
gpt_info = {
"gpt_id": item.get("id"),
"name": item.get("name"),
"author": item.get("author", {}).get("name"),
"description": item.get("description"),
"category": category,
"rank_in_category": idx, # 在当前分类下的排名
"created_at": item.get("created_at"),
"updated_at": item.get("updated_at"),
"snapshot_time": datetime.now().isoformat(), # 抓取时间
}
gpts_list.append(gpt_info)
return gpts_list
def init_database():
"""初始化SQLite数据库和表"""
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS trending_gpts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
gpt_id TEXT NOT NULL,
name TEXT NOT NULL,
author TEXT,
description TEXT,
category TEXT,
rank_in_category INTEGER,
created_at TEXT,
updated_at TEXT,
snapshot_time TEXT NOT NULL,
UNIQUE(gpt_id, snapshot_time, category) -- 防止同一时刻同一分类下重复记录
)
''')
# 创建索引以加速查询
cursor.execute('CREATE INDEX IF NOT EXISTS idx_snapshot_time ON trending_gpts (snapshot_time)')
cursor.execute('CREATE INDEX IF NOT EXISTS idx_category ON trending_gpts (category)')
cursor.execute('CREATE INDEX IF NOT EXISTS idx_gpt_id ON trending_gpts (gpt_id)')
conn.commit()
conn.close()
def save_to_database(gpts_list: List[Dict[str, Any]]):
"""将解析后的数据存入数据库"""
if not gpts_list:
return
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
for gpt in gpts_list:
cursor.execute('''
INSERT OR IGNORE INTO trending_gpts
(gpt_id, name, author, description, category, rank_in_category, created_at, updated_at, snapshot_time)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
''', (
gpt['gpt_id'], gpt['name'], gpt['author'], gpt['description'],
gpt['category'], gpt['rank_in_category'], gpt['created_at'],
gpt['updated_at'], gpt['snapshot_time']
))
conn.commit()
conn.close()
print(f"成功插入 {len(gpts_list)} 条GPTs记录到数据库。")
def main():
"""主抓取流程"""
print(f"开始抓取GPTs趋势数据... {datetime.now()}")
ensure_dirs()
init_database()
raw_data = fetch_trending_gpts()
if not raw_data:
print("抓取失败,退出。")
return
save_raw_data(raw_data)
gpts_list = parse_gpts_list(raw_data)
if gpts_list:
save_to_database(gpts_list)
print(f"本次共处理 {len(gpts_list)} 个GPTs。")
else:
print("警告:解析出的GPTs列表为空,请检查API数据结构或解析逻辑。")
if __name__ == "__main__":
main()
3.4 实现定时任务与自动化
单次抓取意义有限,我们需要让它定时自动运行。可以使用Python内置的 schedule 库,或者更专业的 APScheduler 。这里以 schedule 为例,创建一个 scheduler.py 。
import schedule
import time
from crawler import main as crawl_job
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def job():
logging.info("定时抓取任务开始执行")
try:
crawl_job()
except Exception as e:
logging.error(f"抓取任务执行失败: {e}")
logging.info("定时抓取任务执行完毕")
if __name__ == "__main__":
# 每6小时执行一次
schedule.every(6).hours.do(job)
# 也可以每天固定时间执行,如 schedule.every().day.at("10:30").do(job)
logging.info("定时任务调度器已启动,每6小时运行一次抓取。按 Ctrl+C 退出。")
# 立即运行一次
job()
while True:
schedule.run_pending()
time.sleep(60) # 每分钟检查一次
4. 数据展示与进阶分析
数据抓取和存储只是第一步,让数据产生价值的关键在于分析和展示。 gpts-trending 项目通过生成Markdown文件提供了一种简洁直观的每日视图。我们可以在此基础上进行扩展。
4.1 生成每日趋势报告
我们可以编写一个脚本,从数据库中读取最新一次抓取的数据,按分类生成格式优美的Markdown报告,类似于项目示例中的样式。
# generate_report.py
import sqlite3
from datetime import datetime, timedelta
import pandas as pd
def generate_daily_report():
conn = sqlite3.connect('./data/trending.db')
# 获取最近一次抓取的时间戳
cursor = conn.cursor()
cursor.execute('SELECT MAX(snapshot_time) FROM trending_gpts')
latest_snapshot = cursor.fetchone()[0]
if not latest_snapshot:
print("数据库中没有数据。")
return
# 查询最近一次抓取的所有记录
query = '''
SELECT category, rank_in_category, name, author, description
FROM trending_gpts
WHERE snapshot_time = ?
ORDER BY
CASE category
WHEN 'Featured' THEN 1
WHEN 'Top Picks' THEN 2
... -- 其他分类排序
ELSE 999
END,
rank_in_category
'''
df = pd.read_sql_query(query, conn, params=(latest_snapshot,))
conn.close()
# 生成Markdown
snapshot_date = datetime.fromisoformat(latest_snapshot).strftime('%Y-%m-%d')
report_content = f"# GPTs Trending Report - {snapshot_date}\n\n"
current_category = None
for _, row in df.iterrows():
if row['category'] != current_category:
current_category = row['category']
report_content += f"## {current_category}\n\n"
report_content += f"**{row['rank_in_category']}. {row['name']}**"
if row['author']:
report_content += f" *by {row['author']}*"
report_content += f"\n\n{row['description']}\n\n---\n\n"
# 保存报告
report_filename = f"./reports/daily_report_{snapshot_date}.md"
with open(report_filename, 'w', encoding='utf-8') as f:
f.write(report_content)
print(f"每日报告已生成: {report_filename}")
if __name__ == "__main__":
generate_daily_report()
4.2 趋势分析与洞察挖掘
有了历史数据,我们就可以进行一些简单的趋势分析了。使用 pandas 可以轻松实现。
# analyze_trends.py
import sqlite3
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
def analyze_category_trends(days_back=7):
"""分析过去N天内各分类上榜GPTs的数量变化"""
conn = sqlite3.connect('./data/trending.db')
end_date = datetime.now()
start_date = end_date - timedelta(days=days_back)
# 查询指定时间段内,每天每个分类的GPTs数量
query = '''
SELECT
DATE(snapshot_time) as date,
category,
COUNT(DISTINCT gpt_id) as gpt_count
FROM trending_gpts
WHERE DATE(snapshot_time) BETWEEN ? AND ?
GROUP BY DATE(snapshot_time), category
ORDER BY date, category
'''
df = pd.read_sql_query(query, conn, params=(start_date.date(), end_date.date()))
conn.close()
# 数据透视,便于绘图
pivot_df = df.pivot(index='date', columns='category', values='gpt_count').fillna(0)
# 绘制堆叠面积图或折线图
plt.figure(figsize=(14, 8))
pivot_df.plot(kind='area', stacked=True, alpha=0.7, colormap='tab20c')
plt.title(f'GPTs Store Category Trends (Last {days_back} Days)')
plt.xlabel('Date')
plt.ylabel('Number of GPTs in Top Lists')
plt.legend(title='Category', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.savefig('./reports/category_trends.png', dpi=300, bbox_inches='tight')
plt.show()
# 找出“常青树”GPTs(连续N天上榜)
continuity_query = '''
WITH ranked AS (
SELECT
gpt_id,
name,
DATE(snapshot_time) as date,
LAG(DATE(snapshot_time)) OVER (PARTITION BY gpt_id ORDER BY snapshot_time) as prev_date
FROM trending_gpts
WHERE DATE(snapshot_time) BETWEEN ? AND ?
),
grouped AS (
SELECT
gpt_id,
name,
date,
SUM(CASE WHEN julianday(date) - julianday(prev_date) > 1 THEN 1 ELSE 0 END)
OVER (PARTITION BY gpt_id ORDER BY date) as group_id
FROM ranked
)
SELECT
gpt_id,
name,
MIN(date) as start_date,
MAX(date) as end_date,
COUNT(*) as consecutive_days
FROM grouped
GROUP BY gpt_id, name, group_id
HAVING consecutive_days >= ?
ORDER BY consecutive_days DESC
LIMIT 10
'''
continuity_df = pd.read_sql_query(continuity_query, conn, params=(start_date.date(), end_date.date(), 3)) # 至少连续3天
print("\n--- 连续上榜GPTs(常青树) ---")
print(continuity_df.to_string(index=False))
if __name__ == "__main__":
analyze_category_trends(14)
5. 部署、运维与避坑指南
将脚本部署到服务器上长期运行,并确保其稳定,是项目从“玩具”变为“工具”的关键。
5.1 服务器部署方案选择
- 云服务器(VPS) :如AWS EC2、DigitalOcean Droplet、腾讯云CVM等。这是最灵活的方案,你有完整的控制权。可以使用
systemd或supervisor来管理你的Python脚本进程,确保崩溃后自动重启。成本相对较高,需要一定的运维知识。 - Serverless函数计算 :如AWS Lambda、Vercel Serverless Functions、腾讯云SCF等。非常适合定时触发任务。你只需上传代码,配置好定时触发器(Cron表达式),平台会自动运行和扩缩容。按实际调用次数和资源消耗计费,在低频任务下成本极低,甚至免费。缺点是运行环境有时间和内存限制,且调试相对复杂。
- GitHub Actions :如果你将代码托管在GitHub,这是一个绝佳的免费自动化方案。你可以编写一个工作流文件(.github/workflows/crawl.yml),设定每天或每小时运行一次,执行你的抓取脚本,并将生成的数据或报告提交回仓库或发布到GitHub Pages。这是
gpts-trending项目很可能采用的方案,因为它完美契合开源项目的协作和展示需求。
5.2 常见问题与排查技巧
在运行过程中,你几乎一定会遇到下面这些问题。
问题1:API请求返回403/401错误,或数据为空。
- 原因 :最可能的原因是请求头中的
AuthorizationToken过期或失效。OpenAI的接口认证可能较为严格。 - 排查 :
- 检查Token是否有效。有时需要登录态的Cookie配合。
- 使用
curl或Postman直接复制浏览器中的完整请求头和URL进行测试,确认接口本身是否可用。 - 在代码中添加更详细的日志,打印出请求的URL和Headers(注意隐藏敏感信息)。
- 应对策略 :
- 实现Token刷新机制 :如果Token有刷新接口,在代码中集成刷新逻辑。
- 降级到浏览器模拟 :当API方式持续失败时,自动切换到
playwright进行抓取。 - 设置警报 :当连续多次抓取失败时,通过邮件、Telegram Bot或Server酱发送警报通知你。
问题2:解析数据时出现 KeyError ,程序崩溃。
- 原因 :API返回的数据结构发生了变化。这是爬虫项目最常见的问题。
- 排查 :查看保存的原始JSON文件,对比新旧文件的结构差异。
- 应对策略 :
- 增强解析代码的健壮性 :多用
.get('key', default)方法,避免直接使用['key']。 - 添加结构验证 :在解析前,先检查响应中是否包含预期的关键字段。
- 版本化解析器 :如果数据结构变化很大,可以编写不同版本的解析函数,并根据响应中的某个特征(如版本号)自动选择。
- 增强解析代码的健壮性 :多用
问题3:抓取频率过高导致IP或账号被临时限制。
- 原因 :过于频繁的请求触发了反爬机制。
- 应对策略 :
- 降低频率 :将抓取间隔从每小时调整为每3小时或每天。对于趋势分析,一天2-4次抓取通常足够。
- 添加随机延迟 :在请求间增加
time.sleep(random.uniform(1, 5)),模拟人类操作。 - 使用代理IP池 (如果必要且合规):对于大规模抓取,可以考虑使用轮换代理。但对于个人趋势追踪,控制频率是更简单有效的方法。
问题4:数据库文件越来越大,查询变慢。
- 原因 :历史数据不断累积。
- 应对策略 :
- 定期归档 :每月或每季度将旧数据导出为压缩的JSON或Parquet文件,然后从主数据库中删除。
- 分区表 :如果迁移到PostgreSQL/MySQL,可以使用分区表按时间分区。
- 建立更有效的索引 :确保在经常查询的字段(如
snapshot_time,gpt_id,category)上建立了索引。
5.3 我的实操心得与建议
- 从“只读”开始,尊重平台规则 :这个项目的初衷是学习和分析,而非恶意爬取。务必遵守
robots.txt(如果有),并将抓取频率控制在合理、友好的范围内。避免对目标服务器造成压力。 - 数据备份是生命线 :原始JSON快照一定要保存好。我吃过亏,一次解析逻辑写错,把几个月的历史数据都处理坏了,幸好有原始文件可以重跑。
- 日志是救命的稻草 :给脚本加上详细的日志记录(用
logging模块),记录每次抓取的时间、是否成功、抓取数量、遇到的错误等。当问题发生时,日志是唯一能告诉你“发生了什么”的东西。 - 容器化部署是终极简化 :使用Docker将你的Python环境、依赖和脚本打包成一个镜像。这样,无论是在本地、云服务器还是Serverless平台上,都能保证环境一致性,部署就是一行
docker run的事。 - 关注数据背后的故事 :不要只满足于把数据存下来。定期看看分析报告,思考为什么某个GPTs能火?它的描述有什么特点?最近哪个类别在崛起?这些洞察比数据本身更有价值。
这个项目是一个很好的起点,你可以根据自己的需求扩展它,比如增加情感分析(分析描述文本的积极性)、关联搜索热度、甚至是构建一个带搜索和筛选功能的简单网站。希望这份详细的拆解能帮助你理解 gpts-trending 这类项目的精髓,并成功搭建起属于自己的趋势洞察工具。
更多推荐



所有评论(0)