Real-time sentiment analysis of global AI news headlines
A fully automated, zero-cost web application that scrapes global news headlines about Artificial Intelligence, analyzes their sentiment using machine learning, and displays the results in a sophisticated interactive "scroll-telling" interface.
- Automated Data Pipeline: GitHub Actions runs every 6 hours to scrape fresh news
- ML-Powered Analysis: Uses Hugging Face's DistilBERT model for sentiment classification
- Interactive Visualizations: D3.js-powered charts with hover interactions
- Scroll-telling Experience: Reuters/NYT-style narrative data journalism interface
- Zero Cost: Runs entirely on GitHub Actions + GitHub Pages
- Mobile-First Design: Responsive layout that works across all devices
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β GitHub Actions β
β ββββββββββββ ββββββββββββββββ βββββββββββββββββββββββ β
β β CRON βββββΆβ Python βββββΆβ Commit data.json β β
β β (6 hrs) β β Scraper β β to Repository β β
β ββββββββββββ ββββββββββββββββ βββββββββββββββββββββββ β
β β β β
β βΌ βΌ β
β ββββββββββββββββββββ βββββββββββββββββββββββ β
β β Hugging Face β β Build & Deploy β β
β β Sentiment Model β β to GitHub Pages β β
β ββββββββββββββββββββ βββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β GitHub Pages β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β React App with D3.js Visualizations β β
β β β’ Line Chart (Sentiment Over Time) β β
β β β’ Bubble Chart (Source Distribution) β β
β β β’ Live Headlines Feed β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Component | Technology |
|---|---|
| Backend Script | Python 3.11 |
| RSS Parsing | feedparser |
| Sentiment Analysis | Hugging Face Transformers (DistilBERT) |
| Frontend Framework | React 18 + Vite |
| Styling | Tailwind CSS v4 |
| Visualizations | D3.js |
| Automation | GitHub Actions |
| Hosting | GitHub Pages |
Sentiment-Analysis/
βββ .github/
β βββ workflows/
β βββ main.yml # Automated pipeline
βββ scripts/
β βββ scraper.py # Python scraper + sentiment analyzer
β βββ requirements.txt # Python dependencies
βββ frontend/
β βββ src/
β β βββ components/
β β β βββ LineChart.jsx # Sentiment trend chart
β β β βββ BubbleChart.jsx # Source distribution chart
β β β βββ LiveFeed.jsx # Headlines with scores
β β β βββ ScrollSection.jsx # Scroll-telling wrappers
β β βββ hooks/
β β β βββ useScrollProgress.js
β β β βββ useSentimentData.js
β β βββ App.jsx
β β βββ index.css
β β βββ main.jsx
β βββ public/
β β βββ data.json # Generated sentiment data
β βββ index.html
β βββ package.json
β βββ vite.config.js
βββ README.md
- Node.js 18+
- Python 3.9+
- Git
-
Clone the repository
git clone https://github.com/YOUR_USERNAME/Sentiment-Analysis.git cd Sentiment-Analysis -
Set up Python environment (optional, for running scraper locally)
cd scripts pip install -r requirements.txt python scraper.py cd ..
-
Install frontend dependencies
cd frontend npm install -
Start development server
npm run dev
-
Open browser to
http://localhost:5173
cd frontend
npm run buildThe production build will be in frontend/dist/.
The workflow runs automatically, but you need to enable GitHub Pages:
- Go to Settings β Pages
- Under "Build and deployment", select GitHub Actions
- The workflow will deploy on next push or scheduled run
You can manually trigger data updates:
- Go to Actions β Update AI Sentiment Data & Deploy
- Click Run workflow
The data.json file contains:
{
"last_updated": "2024-12-25T12:00:00Z",
"total_articles": 85,
"overall_sentiment": 0.142,
"overall_label": "Neutral",
"daily_stats": [
{
"date": "2024-12-25",
"avg_sentiment": 0.185,
"article_count": 12,
"moving_avg": 0.143
}
],
"source_stats": [
{
"source": "TechCrunch",
"avg_sentiment": 0.378,
"article_count": 12
}
],
"articles": [
{
"headline": "OpenAI Announces Breakthrough...",
"source": "TechCrunch",
"sentiment_score": 0.756,
"sentiment_label": "Positive"
}
]
}| Element | Value |
|---|---|
| Headline Font | Source Serif 4 |
| UI Font | Inter |
| Background | #FAFAFA |
| Text | #222222 |
| Accent | #DC3545 (Reuters Red) |
| Positive | #28A745 |
| Negative | #DC3545 |
| Neutral | #6C757D |
Uses distilbert-base-uncased-finetuned-sst-2-english:
- Fine-tuned on Stanford Sentiment Treebank
- Binary classification (Positive/Negative)
- Scores normalized to -1 to +1 range
- Neutral: -0.2 to +0.2
Edit .github/workflows/main.yml:
schedule:
- cron: '0 */6 * * *' # Every 6 hours
# Change to:
- cron: '0 */12 * * *' # Every 12 hoursEdit scripts/scraper.py:
RSS_FEEDS = [
("Google News AI", "https://news.google.com/rss/search?q=..."),
# Add more feeds here
]MIT License - see LICENSE for details.
- Hugging Face for the sentiment model
- D3.js for visualization capabilities
- Reuters Graphics & NYT Upshot for design inspiration