☰
用 Python 抓取百度热搜「Manus 引发科技圈震动」:TaoToken 统一 Key 配置与数据分析实战
2026/9/29 3:45:36 网站建设 项目流程

1. 从百度热搜抓「Manus 引发科技圈震动」到底难在哪

百度热搜榜是很多人做舆情分析、选题挖掘的第一站,但真要把「Manus 引发科技圈震动」这类词条抓下来做趋势分析,坑比想象中多。热搜榜本身是动态渲染的,直接requests.get拿到的 HTML 里往往只有骨架,词条数据藏在后续的接口请求里;就算拿到了数据,字段结构也经常变,今天叫word,明天可能叫query。更麻烦的是,当你把抓取、清洗、关键词提取、情感分析、可视化串成一条流水线时,中间任何一步要调用大模型做语义处理,都得单独配一套 Key 和请求逻辑,脚本里到处散落着api_key、base_url,改一次配置要翻五个文件。

这篇就围绕这个场景,把两件事合到一起讲:一是用 Python 把百度热搜里和 Manus 相关的词条抓下来,做热度趋势和关键词分析;二是用 TaoToken 的统一 Key 把整条链路里需要大模型介入的环节(关键词归一化、情感判断、摘要生成)收口到一份config.toml里。适合已经会一点 Python、想跑通「抓取到图表」完整流程的人,也适合手上有一堆零散 API Key、想统一管理的开发者。

我试过把抓取脚本和大模型调用混在一个文件里,结果每次换模型都要改代码,后来拆成配置驱动才清爽。下面按「先跑通抓取、再接统一 Key、最后出图」的顺序来。

2. TaoToken 统一 Key 的前置准备

TaoToken 在这里扮演的角色是「一个 Key 管多个模型」的入口。你不需要在脚本里为每个模型写不同的请求地址和鉴权头,只要在配置文件里声明好,代码里统一读配置就行。官网地址是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 入口是 https://taotoken.net/api ,注意 API 地址不带 UTM 参数,配置里填这个就行。

先做三件事:

第一,拿到 API Key。登录后进控制台,在 API Keys 页面创建一个新 Key,复制保存。这个页面地址是 https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite ,创建时建议按用途命名,比如baidu-hotsearch-analysis,方便后面区分。

第二,确认你要用的模型。做热搜文本分析,通常需要两类能力:一类是轻量的关键词抽取和分类,一类是情感倾向判断。你可以在模型对话页面先手动试几条 Manus 相关文本,看看哪个模型返回的中文结果更稳。模型对话入口是 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite 。

第三,如果你打算把这条分析链路做成长期跑的定时任务,或者后面接 Agent 自动出日报,可以了解下 Coding Plan,它更适合这种持续调用的场景:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite 。

接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,配置字段和请求格式以文档为准,下面给的骨架是通用结构。

3. 可复制的配置与抓取脚本

3.1 config.toml 配置骨架

把 Key 和模型信息从代码里抽出来,放到项目根目录的config.toml:

[taotoken] api_key = "sk-你的Key" base_url = "https://taotoken.net/api" timeout = 30 [taotoken.models] keyword = "你选的关键词抽取模型" sentiment = "你选的情感分析模型" summary = "你选的摘要模型" [spider] hotsearch_url = "https://top.baidu.com/board?tab=realtime" keyword_filter = "Manus" request_interval = 2.0 max_retries = 3 [output] data_dir = "./data" chart_dir = "./charts"

读取配置用标准库tomllib(Python 3.11+)或tomli:

import tomllib with open("config.toml", "rb") as f: cfg = tomllib.load(f) API_KEY = cfg["taotoken"]["api_key"] BASE_URL = cfg["taotoken"]["base_url"]

3.2 抓取百度热搜词条

百度热搜榜的实时数据通过接口返回,直接请求榜单页 HTML 拿不到结构化内容。下面这个脚本用requests请求榜单接口,过滤出含「Manus」的词条,并保存原始 JSON:

import requests import json import time import tomllib from pathlib import Path with open("config.toml", "rb") as f: cfg = tomllib.load(f) HEADERS = { "User-Agent": ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/122.0.0.0 Safari/537.36" ), "Referer": "https://top.baidu.com/", } def fetch_hotsearch(): url = cfg["spider"]["hotsearch_url"] for attempt in range(cfg["spider"]["max_retries"]): try: resp = requests.get(url, headers=HEADERS, timeout=15) resp.raise_for_status() return resp.text except requests.RequestException as e: print(f"第 {attempt+1} 次请求失败: {e}") time.sleep(cfg["spider"]["request_interval"]) return None def extract_manus_items(html): # 榜单页内嵌了 JSON 数据,用正则或字符串定位提取 import re pattern = re.compile(r'\{[^{}]*"word"[^{}]*\}') items = [] for m in pattern.finditer(html): try: obj = json.loads(m.group()) if cfg["spider"]["keyword_filter"].lower() in obj.get("word", "").lower(): items.append(obj) except json.JSONDecodeError: continue return items if __name__ == "__main__": html = fetch_hotsearch() if html: items = extract_manus_items(html) out = Path(cfg["output"]["data_dir"]) out.mkdir(exist_ok=True) with open(out / "manus_hotsearch.json", "w", encoding="utf-8") as f: json.dump(items, f, ensure_ascii=False, indent=2) print(f"抓到 {len(items)} 条相关词条")

这里的关键点是:榜单页的数据结构会变,正则只是示例,实际以你抓到的 HTML 为准。如果正则匹配不到,先把resp.text存下来,搜索"word"看真实字段名。请求间隔设成 2 秒,别把频率拉太高。

3.3 用统一 Key 做关键词归一化

抓下来的词条里,「Manus」「Manus AI」「Manus 智能体」可能指同一件事,需要归一化。这一步调 TaoToken:

import requests def call_taotoken(model, prompt): url = f"{BASE_URL}/v1/chat/completions" headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", } payload = { "model": model, "messages": [{"role": "user", "content": prompt}], "temperature": 0.2, } resp = requests.post(url, headers=headers, json=payload, timeout=30) resp.raise_for_status() return resp.json()["choices"][0]["message"]["content"] def normalize_keywords(words): prompt = ( "把下面这些热搜词条按语义归并成标准关键词," "输出 JSON 数组,每项包含 original 和 normalized 两个字段:\n" + "\n".join(words) ) return call_taotoken(cfg["taotoken"]["models"]["keyword"], prompt)

base_url和api_key都从配置读,换模型只改config.toml,代码不动。

4. 验证请求与成功结果

4.1 先验证 Key 通不通

在正式跑分析前,用一条最小请求确认配置正确:

def health_check(): result = call_taotoken( cfg["taotoken"]["models"]["summary"], "用一句话说明什么是 AI Agent。" ) print("连通性正常,返回:", result[:80]) health_check()

如果返回了中文句子,说明 Key、base_url、模型名三者都对。如果报 401,检查 Key 是否复制完整;报 404,检查 base_url 是否多了斜杠或路径写错。

4.2 跑通完整分析链路

把抓取、归一化、词频统计串起来:

import pandas as pd from collections import Counter import jieba def analyze(): with open("./data/manus_hotsearch.json", encoding="utf-8") as f: items = json.load(f) words = [it.get("word", "") for it in items] normalized = normalize_keywords(words) print("归一化结果:", normalized) # 词频统计 all_text = " ".join(words) tokens = [w for w in jieba.lcut(all_text) if len(w) > 1] counter = Counter(tokens) top20 = counter.most_common(20) df = pd.DataFrame(top20, columns=["word", "freq"]) df.to_csv("./data/top20_words.csv", index=False, encoding="utf-8-sig") print(df) analyze()

成功时你会看到控制台打印出归一化后的 JSON,以及一张前 20 高频词表,./data/top20_words.csv里是同样的内容。

4.3 出图验证

import matplotlib.pyplot as plt import seaborn as sns plt.rcParams["font.sans-serif"] = ["SimHei"] plt.rcParams["axes.unicode_minus"] = False df = pd.read_csv("./data/top20_words.csv") plt.figure(figsize=(10, 6)) sns.barplot(x="freq", y="word", data=df) plt.title("Manus 相关热搜高频词 Top20") plt.tight_layout() plt.savefig("./charts/top20_words.png", dpi=150) print("图表已保存到 ./charts/top20_words.png")

打开图片,如果能看到「Manus」「智能体」「AI」这类词排在前面,说明从抓取到出图的链路已经通了。

5. 本篇常见错排查

抓取返回空列表:最常见的原因是榜单页结构变了,正则没匹配到。解决办法是把resp.text写到文件里,手动搜"word"或"query",确认真实字段名后改正则。另一个原因是请求头里缺Referer,补上https://top.baidu.com/再试。

调用返回 401:Key 没读到或复制时带了空格。在代码里print(API_KEY[:8])确认前几位,和后台对比。注意config.toml里字符串要加引号。

返回 404:base_url写成了https://taotoken.net/api/带尾斜杠,或者路径拼成了/chat/completions少了/v1。以接入文档为准,文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。

中文乱码或词云方框:matplotlib 没设中文字体。加上plt.rcParams["font.sans-serif"] = ["SimHei"],Linux 上如果没有 SimHei,换成系统里有的中文字体名。

jieba 分词把「Manus」拆碎:把「Manus」「AI Agent」加进自定义词典:jieba.add_word("Manus"),再重新分词。

请求超时:把timeout从 30 调到 60,或者检查网络是否能正常访问https://taotoken.net/api。如果只是偶发,加重试逻辑。

6. 把 Key 管好,分析链路才跑得久

这条链路里,抓取部分是一次性投入,真正会反复改的是大模型调用那几段。把 Key 和模型名收进config.toml之后,你换模型、加新分析维度、接定时任务,都只动配置不动代码。如果你后面想把这条链路做成每天自动跑的舆情日报,或者接进 Agent 里做持续监控,Coding Plan 会比按次调用更省心:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite 。

新 Key 建议在 https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 单独建一个,别和别的项目混用,方便出问题时快速定位。配置字段有疑问就翻文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。先把health_check()跑通,再往下做分析,能省掉一大半排查时间。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询