analyzing-twitter-sentiment-for-topic
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAnalyzing Twitter Sentiment for a Topic
分析某话题的Twitter情绪
Collects a sample of tweets about any topic or keyword and performs sentiment analysis across the dataset. Identifies dominant emotional tone, key themes driving positive/negative sentiment, and volume patterns over time.
收集任意话题或关键词的推文样本,并对数据集进行情绪分析。识别主导情感基调、驱动正面/负面情绪的关键主题,以及推文数量随时间变化的模式。
Prerequisites
前提条件
- environment variable set
APIFY_TOKEN - Optional: Apify MCP server installed
- 已设置环境变量
APIFY_TOKEN - 可选:已安装Apify MCP服务器
Inputs
输入参数
| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
| array | ✅ | | Twitter advanced search queries (e.g. |
| string | Optional | | Sort order: |
| string | Optional | — | ISO 639-1 language code (e.g. |
| number | Optional | Unlimited | Maximum tweets to return |
| boolean | Optional | | Only tweets from verified users |
| boolean | Optional | | Only Twitter Blue subscribers |
| boolean | Optional | | Only tweets with images |
| boolean | Optional | | Only tweets with videos |
| boolean | Optional | | Only quote tweets |
| string | Optional | — | Filter to a specific author handle |
| string | Optional | — | Tweets replying to a specific handle |
| string | Optional | — | Tweets mentioning a specific handle |
| string | Optional | — | Tweets near a location |
| string | Optional | — | Radius around geotaggedNear |
| string | Optional | — | Lat/lng + radius string |
| string | Optional | — | Tweets tagged with a place |
| number | Optional | — | Minimum retweet count |
| number | Optional | — | Minimum like count |
| number | Optional | — | Minimum reply count |
| string | Optional | — | Tweets after this date (YYYY-MM-DD) |
| string | Optional | — | Tweets before this date (YYYY-MM-DD) |
| boolean | Optional | | Add the matched search term to each tweet |
| string | Optional | — | JavaScript function to transform each output object |
| 参数 | 类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| 数组 | ✅ | | Twitter高级搜索查询(例如: |
| 字符串 | 可选 | | 排序方式: |
| 字符串 | 可选 | — | ISO 639-1语言代码(例如: |
| 数字 | 可选 | 无限制 | 返回的最大推文数量 |
| 布尔值 | 可选 | | 仅返回认证用户的推文 |
| 布尔值 | 可选 | | 仅返回Twitter Blue订阅用户的推文 |
| 布尔值 | 可选 | | 仅返回带图片的推文 |
| 布尔值 | 可选 | | 仅返回带视频的推文 |
| 布尔值 | 可选 | | 仅返回引用推文 |
| 字符串 | 可选 | — | 筛选特定作者的推文(需提供账号 handle) |
| 字符串 | 可选 | — | 回复特定账号的推文 |
| 字符串 | 可选 | — | 提及特定账号的推文 |
| 字符串 | 可选 | — | 特定地点附近的推文 |
| 字符串 | 可选 | — | |
| 字符串 | 可选 | — | 纬度/经度 + 半径的字符串 |
| 字符串 | 可选 | — | 标记了特定地点的推文 |
| 数字 | 可选 | — | 最小转发量 |
| 数字 | 可选 | — | 最小点赞量 |
| 数字 | 可选 | — | 最小回复量 |
| 字符串 | 可选 | — | 此日期之后的推文(格式:YYYY-MM-DD) |
| 字符串 | 可选 | — | 此日期之前的推文(格式:YYYY-MM-DD) |
| 布尔值 | 可选 | | 为每条推文添加匹配的搜索词 |
| 字符串 | 可选 | — | 用于转换每个输出对象的JavaScript函数 |
Workflow
工作流程
Progress:
- [ ] Step 1: Define topic and sentiment scope
- [ ] Step 2: Collect tweets via search
- [ ] Step 3: Classify sentiment per tweet
- [ ] Step 4: Identify themes per sentiment bucket
- [ ] Step 5: Deliver sentiment report进度:
- [ ] 步骤1:定义话题和情绪分析范围
- [ ] 步骤2:通过搜索收集推文
- [ ] 步骤3:对每条推文进行情绪分类
- [ ] 步骤4:按情绪类别识别主题
- [ ] 步骤5:交付情绪分析报告Step 1: Clarify Parameters
步骤1:明确参数
Ask the user for:
- Topic, keyword, or brand to analyze
- Date range (default: last 7 days — Twitter sentiment data decays fast)
- Language (default: English)
- Sample size (default: 500 tweets — sufficient for reliable distribution)
- Exclude retweets? (default: yes — reduces duplicated opinion signals)
- Comparison topic (optional — for side-by-side sentiment comparison)
向用户确认以下信息:
- 要分析的话题、关键词或品牌
- 日期范围(默认:过去7天——Twitter情绪数据时效性强)
- 语言(默认:英语)
- 样本量(默认:500条推文——足以保证结果的可靠性)
- 是否排除转发?(默认:是——减少重复的意见信号)
- 对比话题(可选——用于情绪的对比分析)
Step 2: Collect Tweets
步骤2:收集推文
Recommended — run_actor.js (handles waiting, output, and file saving automatically):
bash
undefined推荐方式 — 使用run_actor.js(自动处理等待、输出和文件保存):
bash
undefinedQuick answer (prints table to chat)
快速输出(在聊天中打印表格)
node scripts/run_actor.js
--actor "apidojo~tweet-scraper"
--input '{"param": "value"}'
--actor "apidojo~tweet-scraper"
--input '{"param": "value"}'
node scripts/run_actor.js
--actor "apidojo~tweet-scraper"
--input '{"param": "value"}'
--actor "apidojo~tweet-scraper"
--input '{"param": "value"}'
Save as CSV
保存为CSV文件
node scripts/run_actor.js
--actor "apidojo~tweet-scraper"
--input '{"param": "value"}'
--output YYYY-MM-DD_results.csv --format csv
--actor "apidojo~tweet-scraper"
--input '{"param": "value"}'
--output YYYY-MM-DD_results.csv --format csv
node scripts/run_actor.js
--actor "apidojo~tweet-scraper"
--input '{"param": "value"}'
--output YYYY-MM-DD_results.csv --format csv
--actor "apidojo~tweet-scraper"
--input '{"param": "value"}'
--output YYYY-MM-DD_results.csv --format csv
Save as JSON
保存为JSON文件
node scripts/run_actor.js
--actor "apidojo~tweet-scraper"
--input '{"param": "value"}'
--output YYYY-MM-DD_results.json --format json
--actor "apidojo~tweet-scraper"
--input '{"param": "value"}'
--output YYYY-MM-DD_results.json --format json
> `APIFY_TOKEN` must be set in environment or `.env` file.
**If Apify MCP is available:**Tool: apify:run-actor
Actor: "apidojo~tweet-scraper"
Input:
{
"searchTerms": ["[TOPIC_KEYWORD]"],
"maxItems": 500,
"tweetLanguage": "en",
"since": "[YYYY-MM-DD]",
"until": "[YYYY-MM-DD]"
}
**REST API fallback:**
```bash
curl -X POST \
"https://api.apify.com/v2/acts/apidojo~tweet-scraper/runs?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"searchTerms": ["[TOPIC_KEYWORD]"],
"maxItems": 500,
"tweetLanguage": "en",
"since": "[YYYY-MM-DD]"
}'node scripts/run_actor.js
--actor "apidojo~tweet-scraper"
--input '{"param": "value"}'
--output YYYY-MM-DD_results.json --format json
--actor "apidojo~tweet-scraper"
--input '{"param": "value"}'
--output YYYY-MM-DD_results.json --format json
> 必须在环境变量或`.env`文件中设置`APIFY_TOKEN`。
**如果Apify MCP可用:**工具: apify:run-actor
Actor: "apidojo~tweet-scraper"
输入:
{
"searchTerms": ["[TOPIC_KEYWORD]"],
"maxItems": 500,
"tweetLanguage": "en",
"since": "[YYYY-MM-DD]",
"until": "[YYYY-MM-DD]"
}
**REST API备选方案:**
```bash
curl -X POST \
"https://api.apify.com/v2/acts/apidojo~tweet-scraper/runs?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"searchTerms": ["[TOPIC_KEYWORD]"],
"maxItems": 500,
"tweetLanguage": "en",
"since": "[YYYY-MM-DD]"
}'Step 3: Classify Sentiment
步骤3:情绪分类
For each tweet's , classify as Positive, Negative, or Neutral using lexical signals:
textPositive indicators: love, great, amazing, perfect, best, win, excited, congrats, excellent, recommend, beautiful, proud, happy, thank, awesome, incredible
Negative indicators: hate, awful, worst, terrible, broken, scam, disappointed, angry, frustrated, disgusted, avoid, never again, shame, sad, fail, wrong, bad
Strong negative amplifiers: "can't believe", "what a joke", "are you serious", "wtf", "this is ridiculous"
Neutral default: Everything else
For ambiguous cases, use emoji signals:
- 😍🥰❤️🙌👏✨🔥 → lean Positive
- 😡🤬😤💀🗑️🤢👎 → lean Negative
- 🤔😐🤷 → lean Neutral
Weight tweets by engagement: a tweet with 1,000 likes carries more signal than one with 0.
针对每条推文的内容,通过词汇信号将其分类为正面、负面或中性:
text正面指标: love、great、amazing、perfect、best、win、excited、congrats、excellent、recommend、beautiful、proud、happy、thank、awesome、incredible
负面指标: hate、awful、worst、terrible、broken、scam、disappointed、angry、frustrated、disgusted、avoid、never again、shame、sad、fail、wrong、bad
强负面强化词: "can't believe"、"what a joke"、"are you serious"、"wtf"、"this is ridiculous"
默认中性: 其他所有内容
对于模糊的情况,使用表情符号信号:
- 😍🥰❤️🙌👏✨🔥 → 倾向于正面
- 😡🤬😤💀🗑️🤢👎 → 倾向于负面
- 🤔😐🤷 → 倾向于中性
按互动量为推文加权:一条获得1000个点赞的推文比0点赞的推文更具信号价值。
Step 4: Theme Extraction
步骤4:主题提取
For Negative tweets: identify the top 3-5 recurring nouns/themes. What are people upset about specifically?
For Positive tweets: identify the top 3-5 recurring praise themes.
Look for proper nouns (people, places, products), specific events, or feature names that appear repeatedly.
对于负面推文:识别出现次数最多的3-5个名词/主题。人们具体在不满什么?
对于正面推文:识别出现次数最多的3-5个获赞主题。
寻找重复出现的专有名词(人物、地点、产品)、特定事件或功能名称。
Step 5: Format Report
步骤5:格式化报告
Output Format
输出格式
undefinedundefinedTwitter Sentiment Analysis: "[TOPIC]"
Twitter情绪分析:"[TOPIC]"
Period: [DATE_RANGE] | Tweets analyzed: [N] | Date: [DATE]
时间段:[DATE_RANGE] | 分析推文数量:[N] | 日期:[DATE]
Overall Sentiment
整体情绪
████████████░░░░░░░░ Positive: [X%] ([N] tweets)
████░░░░░░░░░░░░░░░░ Negative: [X%] ([N] tweets)
██████████░░░░░░░░░░ Neutral: [X%] ([N] tweets)Weighted by engagement:
- Positive sentiment accounts for [X%] of total likes/RTs
- Negative sentiment accounts for [X%] of total likes/RTs
Overall verdict: [Mostly Positive / Mixed / Mostly Negative / Polarized]
████████████░░░░░░░░ 正面:[X%]([N]条推文)
████░░░░░░░░░░░░░░░░ 负面:[X%]([N]条推文)
██████████░░░░░░░░░░ 中性:[X%]([N]条推文)按互动量加权:
- 正面情绪占总点赞/转发量的[X%]
- 负面情绪占总点赞/转发量的[X%]
整体结论: [以正面为主 / 混合 / 以负面为主 / 两极分化]
Top Negative Themes
热门负面主题
- "[Theme]" — [N] tweets, [N] total likes Example: "@[handle]: [tweet excerpt]"
- "[Theme]" — [N] tweets
- "[Theme]" — [N] tweets
- "[主题]" — [N]条推文,总点赞量[N] 示例:"@[handle]: [推文节选]"
- "[主题]" — [N]条推文
- "[主题]" — [N]条推文
Top Positive Themes
热门正面主题
- "[Theme]" — [N] tweets, [N] total likes Example: "@[handle]: [tweet excerpt]"
- "[Theme]" — [N] tweets
- "[主题]" — [N]条推文,总点赞量[N] 示例:"@[handle]: [推文节选]"
- "[主题]" — [N]条推文
Most Engaged Tweets
互动量最高的推文
🔴 Most-liked negative: @[handle] ([N] likes): "[excerpt]"
🟢 Most-liked positive: @[handle] ([N] likes): "[excerpt]"
🔴 点赞最多的负面推文:@[handle]([N]个点赞):"[节选]"
🟢 点赞最多的正面推文:@[handle]([N]个点赞):"[节选]"
Volume Over Time
推文数量随时间变化
[Day 1]: [N] tweets | [Day 2]: [N] tweets | [Day 3]: [N] tweets
[第1天]:[N]条推文 | [第2天]:[N]条推文 | [第3天]:[N]条推文
Notable Spikes
显著峰值
[Date with highest volume] — [N] tweets | Likely cause: [describe if detectable from tweet context]
undefined[推文数量最高的日期] — [N]条推文 | 可能原因:[根据推文上下文描述(如果可检测)]
undefinedTroubleshooting
故障排除
Sentiment feels inaccurate: Lexical analysis misses sarcasm. For high-stakes decisions, manually review the top 20 tweets per bucket.
Topic too broad: Narrow the search term. "Apple" returns tech and food — use "Apple iPhone" instead.
Very low tweet volume: Topic may not be actively discussed on Twitter right now. Expand date range.
情绪分析结果不准确: 词汇分析无法识别讽刺。对于高风险决策,请手动查看每个类别中排名前20的推文。
话题范围过广: 缩小搜索词范围。例如“Apple”会返回科技和食品相关内容——改用“Apple iPhone”。
推文数量极少: 该话题目前可能未在Twitter上被广泛讨论。扩大日期范围。