我把一个人的 X/Twitter 喂给 AI,它居然看懂了这个人
公开的X/Twitter账号主页信息量庞大,人工浏览几百上千条混合多语种的推文效率低下且难以回溯。本文介绍的开源工具xcrawler,旨在将这种主观判断转化为有证据支撑的结构化用户画像报告。
你是否曾遇到这样的困扰:想快速了解一个公开的X/Twitter账号,于是打开其主页,一条条地往下翻看。你试图了解他最近在聊什么,长期关注哪些话题,何时最为活跃,内容偏技术还是偏生活,情绪状态有无变化,以及他经常提及哪些人和标签。如果只是几十条内容,人工浏览尚可应付。但一旦样本量增加到几百条、几千条,内部又混杂着中文、英文、日文、韩文、缩写、网络梗、Hashtag和各类专有名词,这项工作便会迅速变得低效。更重要的是,人工浏览后得出的结论往往是:“这个人好像挺关注AI”“这个账号应该偏技术内容”“他晚上比较活跃”“最近情绪好像有点负面”。这些判断未必错误,但真正的问题是:证据在哪里?这些结论源于哪些具体推文?能否进行回溯?能否持续更新?能否将主观感受转化为结构化结果?这正是我开发xcrawler的原因。
并非又一个爬虫,而是可追溯的分析工具
xcrawler是一个面向公开X/Twitter时间线的开源用户画像分析工具。它能抓取公开账号的时间线内容,并对其进行清洗、翻译、分析,最终生成一份相对结构化、可复盘、可追溯的用户画像报告。它不是单纯的“抓数据”工具,也不是简单地将推文丢给大模型,让AI总结一句“这个人喜欢什么”。我更希望做到的是:将公开的X/Twitter时间线,转化为有证据支撑的用户画像、兴趣地图和行为洞察。目前它已支持以下功能:公开推文抓取、新推文与历史推文的增量同步、多语言检测与翻译、兴趣画像分析、时间行为分析、情感趋势分析、生活事件信号检测、Hashtag或Mention网络分析、图表与HTML报告生成、CSV数据导出、evidence tweet证据追溯、本地缓存与多用户数据隔离。因此,我更愿意将其定义为一款公开社交内容洞察工具。
为何这件事具有价值?
公开社交内容中蕴含着大量信号。一个人长期转发的内容、反复讨论的话题、经常使用的词汇、发布内容的时间、以及其与各种话题或账号产生的连接,都在某种程度上反映了他们的内容偏好、表达方式和社交参与路径。然而,这些信号通常是碎片化的。单条推文意义有限,真正具有价值的是长期样本中呈现的重复模式。例如:一个账号是否长期关注AI?其关注的是大模型应用,还是底层模型、Agent或工程化?其内容更偏向研究、产品、投资,还是个人表达?它在什么时间段最为活跃?最近的内容方向是否发生了变化?它经常提及哪些标签和账号?其内容的情绪是稳定的,还是存在明显波动?这些问题依靠人工浏览也能做出判断,但人工判断的问题在于速度慢、结果不稳定、难以复盘。xcrawler希望解决的问题,正是将这种“感觉”尽量转化为结构化结果,并保留证据。
它可应用于哪些场景?
最初开发这个项目,是为了更系统地理解公开账号长期输出的内容特征。随着功能的完善,我发现它有着广泛的适用场景。例如:1. 公开账号研究:快速理解一个公开账号长期关注什么、表达什么、活跃节奏如何。2. 创作者画像:分析创作者的内容方向、兴趣标签、表达风格和潜在受众信号。3. 内容策略分析:观察某个领域内高频出现的话题、标签、情绪和发布时间节奏。4. 品牌与竞品观察:分析品牌账号、竞品账号或行业意见领袖的公开内容变化。5. 受众洞察:对一组公开账号进行分析,理解他们公开表达出来的兴趣、话题和行为信号。6. 营销投放前的人群理解:在内容策划、投放或合作前,先了解目标人群公开呈现出的兴趣结构。7. 多语言内容整理:对日语、英语、韩语、法语等多种语言的推文进行统一翻译,再进行后续分析。8. 长期变化追踪:通过增量抓取和运行记录,观察账号内容随时间发生的变化。当然,这里有一个至关重要的前提:xcrawler仅适用于公开内容分析。它不应被用于骚扰、跟踪、人肉搜索、隐私挖掘、敏感身份判断,也不应被用于违反平台规则或当地法律的行为。工具越接近对人的分析,其行为边界就越发重要。
xcrawler具体能分析什么?
目前,xcrawler主要包含以下几类核心能力。
1. 抓取公开推文,并支持增量同步
该工具支持抓取指定公开账号的原创推文,并排除转发和回复。除了首次抓取,它还支持增量同步功能:抓取比现有数据更新的推文,补全更早的历史推文,根据目标日期停止历史抓取,合并数据时自动去重,以及在API限流时尽量等待和恢复。这种能力对于长期观察一个账号至关重要。在实际使用中,我们很少希望每天进行全量重跑。更常见的需求是:今天补充一点新内容,明天补上一点历史缺口,后天再更新一次分析报告。因此,增量抓取并非锦上添花,而是长期使用的基础能力。
2. 自动处理多语言内容
X/Twitter上的内容经常是多语言混合的。一个账号可能今天发布英文内容,明天发布日文,后天又发布中文,中间还夹杂着缩写、梗图、链接、标签和专有名词。如果直接分析原文,后续的聚类、画像和情感判断会变得非常混乱。因此,xcrawler会先进行文本清洗和语言检测,然后将非中文内容翻译成中文,以便于后续统一分析。在此过程中,我特别做了几点设计:中文内容直接跳过翻译;已翻译的文本写入缓存;后续运行不会重复翻译;多条推文进行批量翻译,以降低LLM调用次数;翻译失败时会记录失败列表,方便重试。这些措施对于成本控制非常关键。因为只要涉及LLM,工程上就必须考虑三个问题:慢任务、失败恢复和成本可控。
3. 生成兴趣画像,但尽量避免过度推断
兴趣画像是这个项目最核心的能力之一。
xcrawler会尝试从长期内容中提取稳定的兴趣点,而不是根据单条推文做出夸大推断。它会关注以下方面:反复出现的话题、长期出现的关键词、内容领域的分布、核心兴趣与边缘兴趣、置信度,以及支撑结论的tweet_id。在prompt和输出结构里,我刻意加入了较为克制的原则:不根据单条内容推断长期兴趣;不做人格、心理或价值观方面的推断;在证据不足时降低置信度;输出结构化的JSON数据;evidence_tweet_ids必须来自输入数据。这意味着它并非让AI“自由发挥”,更像是要求AI在明确的边界内进行归纳:你可以总结,但要告诉我证据的来源;你可以做出判断,但不要把不确定性包装成确定的结论;你可以分析公开内容,但不要跨越隐私和伦理的边界。我认为这正是它区别于普通AI总结工具的地方。
4. 分析时间行为和活跃节奏
一个账号的活跃时间,本身就是一种很有价值的行为信号。
xcrawler会分析:24小时内的发推分布、工作日与周末的活跃度、最活跃的时段、最活跃的星期、不同时间段的内容密度,以及作息和发布节奏的特征。这些信息能帮助我们理解一个账号的内容发布习惯。例如:他(她)是白天更活跃,还是晚上更活跃?其更像工作日输出,还是周末输出?其发布节奏是稳定的,还是阶段性的?在什么时间窗口观察或互动最为合适?这些分析不一定能直接得出强有力的结论,但可以作为内容研究和账号观察的重要辅助信号。
5. 做情感趋势分析,但失败不伪装成成功
该工具也支持对翻译后的推文进行情感分类,类别包括:positive、neutral、negative和unknown。这里有一个我认为很重要的细节:如果某个LLM批次失败,结果不会被默认归为neutral,而是会被标记为unknown。原因在于,失败并不等同于中性。如果把失败数据默默算作neutral,最终的报告看起来会显得平稳,但实际上已经被污染。这类细节很容易被忽略,但它直接影响分析的可信度。在数据分析和AI工程中,有时真正危险的不是失败,而是失败后看起来却像成功。
6. 检测生活事件,但默认保持克制
xcrawler也可以从公开推文中识别一些明确提及的生活事件,例如:生日、感情状态变化、学业变化、职业变化、健康事件、旅行或搬家、重大购物,以及其他明确事件。但在这一部分,我做得比较谨慎。因为生活事件分析天然更接近隐私边界。即使内容是公开发布的,也不意味着工具可以无限放大、聚合和推断。因此,项目默认对敏感的生活事件进行隐藏处理,HTML报告中的证据原文也支持脱敏。这并非形式主义,而是我认为此类工具必须具备的底线设计。
7. 分析Hashtag / Mention网络
除了文本内容,社交信号同样重要。xcrawler会进行以下统计:高频Hashtag、高频Mention、Hashtag与Mention的共现关系、Hashtag柱状图、Mention柱状图,以及网络分析结果JSON。这些信息有助于我们理解:这个账号经常参与哪些话题?它经常提及哪些账号?其内容更靠近哪个社交圈层?某些话题和某些账号是否经常同时出现?与单纯的文本总结相比,Hashtag和Mention更像是账号的“外部连接图谱”,能够补充兴趣画像中不易看到的社交关系信号。
8. 生成可视化报告和数据导出
最终,xcrawler可以生成图表和HTML报告,其中包括:24小时发推分布图、星期分布图、语言分布图、兴趣标签图、情感趋势图、情感分布图、Hashtag或Mention图表、HTML汇总报告,以及CSV导出文件。更重要的是,报告中会尽量保留evidence tweet。也就是说,当报告指出“这个账号关注AI”时,你可以回溯并查看到这个判断源于哪些具体的推文。这也是我在开发这个项目时始终坚持的原则:AI分析不应仅提供结论,还应尽可能保留证据链。
为何将其从脚本改造成开源工具?
在最早期,xcrawler只是几个简单的脚本。它们能运行,但并不适合开源。因为一个真正供他人使用的开源项目,不能仅仅满足于“作者自己知道如何运行”。后来,我开始逐步对其进行工程化封装。
统一CLI:让新用户无需理解一堆脚本
现在,该项目推荐使用统一的命令入口:xcrawler fetch;xcrawler fetch-more;xcrawler translate;xcrawler analyze interest;xcrawler analyze behavior;xcrawler analyze sentiment;xcrawler analyze network;xcrawler report;xcrawler export csv。这样,新用户无需先理解每个Python脚本之间的调用关系。他们只需要知道:我需要抓取、需要翻译、需要分析兴趣、需要生成报告、需要导出数据。CLI的设计应围绕用户的任务来组织,而不是围绕作者的脚本习惯。
配置管理:让项目更易于复用
项目通过.env文件管理配置,例如:X_BEARER_TOKEN=your_x_bearer_token;DEEPSEEK_API_KEY=your_deepseek_api_key;TARGET_USERNAME=MiracleHe;TIMEZONE_OFFSET=8。同时,它也支持通过CLI参数覆盖.env中的设置,例如:xcrawler fetch -u some_user --pages 3。这种设计既适合固定分析一个账号,也便于临时切换目标用户。
多用户缓存隔离:避免数据相互覆盖
不同用户的数据会按用户名分别保存,例如:cache/{username}_raw_tweets.json;cache/{username}_translated.json;cache/{username}_interest_profile.json;cache/{username}_behavior.json;cache/{username}_sentiment.json;cache/{username}_network.json。这样,多个账号可以并行分析,而不会发生数据覆盖。这看似只是文件命名的问题,但对于真正的长期使用来说,它非常关键。因为只要涉及多账号、多次运行、多版本结果,数据隔离就是不可或缺的基础设施。
执行计划和参数校验:让慢任务更可控
这类项目天然会遇到慢任务,因为它涉及X API抓取、多语言翻译、embedding模型、KMeans聚类、LLM分析、图表生成以及HTML报告生成等多个环节。因此,我加入了参数校验和执行计划。例如,参数要求:pages必须大于等于1;batch-size必须大于等于1;top必须大于等于1;温度参数必须在0到2之间。一些任务在启动前也会显示执行计划,例如预计抓取页数、最多推文数、翻译批次数、是否会调用LLM等。这能避免一种糟糕的体验:用户执行命令后,完全不知道接下来会发生什么,也不清楚是否会消耗大量token。慢任务并不可怕,可怕的是慢任务不透明。
运行记录:让每次分析都能复盘
项目会记录分析运行的元数据,包括:用户名、分析类型、使用的模型、参数、输入范围、开始与结束时间、运行状态、耗时、LLM调用次数、token用量,以及失败批次。这些记录会被写入analysis_runs.json文件中。这样一来,你可以随时回溯:这次分析使用了什么模型?分析了多少内容?有无失败?花费了多少token?结果是部分成功还是全部成功?下次是否需要缩小输入规模?对于个人项目而言,这或许不是第一眼最酷的功能,但对于长期使用来说,它非常重要。因为只有可复盘,才能持续优化。
测试和CI:避免项目只在作者电脑上能跑
项目目前包含94个单元测试,覆盖了许多关键路径:文本清洗、语言检测、翻译缓存、批量翻译响应解析、X API mock、CLI参数解析与校验、evidence校验、隐私保护、LLM Provider、analysis run、情感分析失败处理、JSON Store、CSV导出、HTML报告证据区,以及敏感证据隐藏。同时,项目也接入了GitHub Actions进行持续集成。这并不意味着项目已经完美无缺,但至少它已不再是“只能在我电脑上跑”的状态。我希望它能逐步演进为一个真正可维护、可复用、可协作的开源项目。
慢任务和成本是如何处理的?
这个项目会遇到两个现实问题:第一是速度慢,第二是成本高。因此,我做了几类优化。
1. 增量抓取,避免每天全量重跑
通过命令“xcrawler fetch-more --pages 3”,只补充新增内容和历史缺口,而非每次都从头开始。
2. 翻译缓存,避免重复调用LLM
已经翻译过的内容会写入缓存。下次再运行时,不会重复翻译同一条文本。
3. 批量翻译,减少API调用次数
多条推文可以合并为一次LLM调用。相较于逐条翻译,这种方式更适合批处理场景。
4. 控制抓取规模
使用命令“xcrawler fetch --pages 3”,先以小规模验证配置,再决定是否扩大抓取范围。
5. 控制分析输入规模
通过命令“xcrawler analyze interest --limit 300”,为专业兴趣分析设置输入上限,避免一次性将过多内容发送给模型。
6. 失败不伪装成功
例如,在情感分析失败时,结果会被标记为unknown,而不是默认写成neutral。这件事虽小,但对结果的可信度至关重要。
隐私和边界:这类工具必须首先明确界限
我一直认为,这类工具最容易遭到误解,因为它分析的是用户发布的公开内容。公开,不代表可以无限使用;可抓取,不代表可以滥用;能分析,不代表应该推断一切。因此,xcrawler的定位非常明确:它适用于公开账号研究、创作者分析、内容策略、品牌观察、受众洞察、学习和研究,以及LLM应用工程化实践。它不应被用于骚扰、跟踪、人肉搜索、非公开信息推断、敏感身份判断、歧视性画像,以及任何违反平台规则或当地法律的行为。项目默认将数据保存在本地,敏感生活事件默认隐藏,HTML报告中的证据原文支持脱敏,README中也明确说明了responsible use的边界。工具本身不能替使用者做出伦理判断,但一个负责任的工具,至少应在设计上保持克制。
快速使用
安装:git clone https://github.com/yuanrengu/xcrawler.git;cd xcrawler;python3 -m venv .venv;source .venv/bin/activate;python3 -m pip install -e ".[all]";cp .env.example .env。编辑.env文件,填入:X_BEARER_TOKEN=your_x_bearer_token;DEEPSEEK_API_KEY=your_deepseek_api_key;TARGET_USERNAME=MiracleHe。然后运行:xcrawler fetch -u MiracleHe --pages 3;xcrawler analyze interest -u MiracleHe;xcrawler analyze behavior -u MiracleHe;xcrawler analyze sentiment -u MiracleHe;xcrawler analyze network -u MiracleHe;xcrawler report -u MiracleHe。生成的数据、图表和报告会保存在本地cache目录下。
当前限制
我不想把它包装成一个“完美产品”。它现在已经可以使用,但仍存在一些限制。1. 依赖X API权限和额度:不同账号的API权限会影响可抓取的数据量。2. 首次运行可能需要下载embedding模型,这会消耗一些时间和磁盘空间。3. LLM分析会产生token成本,特别是在大量推文翻译、情感分析和兴趣画像分析时。4. 兴趣分析还可以继续升级:目前已有输入上限保护,但更理想的形态是分片提取、候选归并、置信度重排和证据校验。5. 长期多用户分析需要更强的存储层:当前默认使用JSON文件,适合个人、小规模、低频分析,后续可加入SQLite Store,便于查询运行历史、模型参数和结果版本。6. 项目命名未来可能调整:xcrawler这个名字偏技术脚本,未来若产品化,可能会换成更有品牌感的名字。
后续计划
接下来我希望继续推进几项工作:开发SQLite Store、建立LLM成本看板、实施更完整的分片分析和归并策略、优化HTML报告模板、提供更多开箱即用的分析preset、准备示例数据和demo、推动更清晰的项目品牌化,以及完善文档和贡献指南。我希望它不仅仅是一个“能跑的脚本”,而是一个可以被复用、可以被审计、可以持续演进的开源工具。
最后
公开社交内容中包含着大量信号,但真正有价值的并非“抓到数据”,而是将数据整理成可复盘、可追溯的洞察。xcrawler所做的,正是将公开的X/Twitter时间线转化为用户画像、兴趣地图和行为洞察。如果你对公开账号研究、创作者分析、受众洞察、内容策略或LLM应用工程化感兴趣,欢迎试用并提出issue或PR。