Costruire il tuo Digest RSS Alimentato da IA
In un’era di sovraccarico informativo, rimanere aggiornati con le ultime notizie preferite può essere impegnativo. Inoltre, internet è pieno di contenuti clickbait che ci distraggono dalle informazioni davvero importanti. I feed RSS offrono una soluzione, ma chi ha tempo di leggere decine di articoli ogni giorno? Questo tutorial ti mostra come costruire un digest intelligente RSS che riassume automaticamente i contenuti usando l’IA.
Analizzeremo tre passaggi chiave: analizzare i feed RSS, estrarre il contenuto completo degli articoli e generare riassunti alimentati dall’IA usando l’API di OpenAI.
Prerequisiti
Prima di iniziare, avrai bisogno di:
- Python 3.7+
- Una chiave API OpenAI
- Familiarità di base con Python
Installa i pacchetti richiesti:
1pip install feedparser requests beautifulsoup4 openai
Passaggio 1: Analizzare i Feed RSS con Python
I feed RSS (Really Simple Syndication) sono file XML che i siti web usano per pubblicare i loro contenuti più recenti. La libreria feedparser di Python rende facile lavorare con questi feed.
1import feedparser
2import requests
3from datetime import datetime, timezone
4
5def parse_rss_feed(feed_url):
6 """Parse a single RSS feed and extract articles"""
7
8 # Fetch the RSS feed
9 response = requests.get(feed_url, timeout=30)
10 response.raise_for_status()
11
12 # Parse the XML content
13 feed = feedparser.parse(response.content)
14
15 articles = []
16 for entry in feed.entries:
17 # Extract publication date
18 pub_date = None
19 if hasattr(entry, 'published_parsed') and entry.published_parsed:
20 pub_date = datetime(*entry.published_parsed[:6], tzinfo=timezone.utc)
21
22 # Get article content (summary from RSS)
23 content = getattr(entry, 'summary', '')
24
25 article = {
26 'title': entry.get('title', 'No Title'),
27 'url': entry.get('link', ''),
28 'content': content,
29 'published': pub_date,
30 'author': entry.get('author', 'Unknown')
31 }
32 articles.append(article)
33
34 return articles
35
36# Example usage
37feed_url = "https://feeds.bbci.co.uk/news/rss.xml"
38articles = parse_rss_feed(feed_url)
39print(f"Found {len(articles)} articles")
La libreria feedparser gestisce la complessità dell’analisi XML e fornisce un’interfaccia pulita per accedere ai metadati degli articoli come titoli, URL, date di pubblicazione e contenuto riassuntivo.
Passaggio 2: Estrarre il Contenuto Completo con Beautiful Soup
I feed RSS tipicamente includono solo riassunti degli articoli. Per ottenere il contenuto completo per una migliore analisi IA, dobbiamo recuperare e analizzare le pagine web reali.
1from bs4 import BeautifulSoup
2import re
3
4def extract_article_content(url):
5 """Fetch and extract main content from a web page"""
6
7 headers = {
8 'User-Agent': 'Mozilla/5.0 (compatible; RSS Reader/1.0)'
9 }
10
11 try:
12 response = requests.get(url, headers=headers, timeout=30)
13 response.raise_for_status()
14
15 # Parse HTML with Beautiful Soup
16 soup = BeautifulSoup(response.text, 'html.parser')
17
18 # Remove unwanted elements
19 for element in soup(['script', 'style', 'nav', 'footer', 'header', 'aside']):
20 element.decompose()
21
22 # Extract text content
23 content = soup.get_text(separator=' ', strip=True)
24
25 # Clean up whitespace
26 content = ' '.join(content.split())
27
28 # Limit content length for LLM processing
29 max_chars = 8000 # Roughly 2000 tokens
30 if len(content) > max_chars:
31 content = content[:max_chars] + "..."
32
33 return content if len(content) > 100 else None
34
35 except Exception as e:
36 print(f"Error extracting content from {url}: {e}")
37 return None
38
39# Enhance articles with full content
40def enhance_articles(articles):
41 """Add full content to articles"""
42
43 for article in articles:
44 if article['url']:
45 full_content = extract_article_content(article['url'])
46 if full_content and len(full_content) > len(article['content']):
47 article['content'] = full_content
48 print(f"Enhanced: {article['title']}")
49
50 return articles
Beautiful Soup eccelle nell’analisi HTML e nell’estrazione di contenuto testuale pulito. Rimuoviamo elementi di navigazione, script e altre parti non-contenuto per concentrarci sul testo dell’articolo.
Passaggio 3: Generare Riassunti IA con OpenAI
Ora arriva la magia: usare l’API di OpenAI per generare riassunti intelligenti dei nostri articoli raccolti.
1import openai
2
3class DigestGenerator:
4 def __init__(self, api_key):
5 self.client = openai.OpenAI(api_key=api_key)
6
7 def create_digest(self, articles):
8 """Generate an AI-powered digest of articles"""
9
10 # Prepare articles for the prompt
11 article_summaries = []
12 for i, article in enumerate(articles[:10], 1): # Limit to 10 articles
13 summary = {
14 'title': article['title'],
15 'content': article['content'][:1500], # Truncate for token limits
16 'url': article['url'],
17 'published': article['published'].strftime('%Y-%m-%d') if article['published'] else 'Unknown'
18 }
19 article_summaries.append(summary)
20
21 # Create the prompt
22 prompt = self._build_digest_prompt(article_summaries)
23
24 try:
25 response = self.client.chat.completions.create(
26 model="gpt-3.5-turbo",
27 messages=[{"role": "user", "content": prompt}],
28 temperature=0.3,
29 max_tokens=2000
30 )
31
32 return response.choices[0].message.content
33
34 except Exception as e:
35 print(f"Error generating digest: {e}")
36 return self._fallback_digest(article_summaries)
37
38 def _build_digest_prompt(self, articles):
39 """Build the prompt for AI digest generation"""
40
41 prompt = f"""Create a comprehensive daily digest from these {len(articles)} articles.
42
43Instructions:
44- Summarize the key themes and trends
45- Group related topics together
46- Highlight the most important developments
47- Keep it engaging and informative
48- Use markdown formatting
49
50Articles:
51
52"""
53
54 for i, article in enumerate(articles, 1):
55 prompt += f"""
56## Article {i}: {article['title']}
57**URL:** {article['url']}
58**Published:** {article['published']}
59
60{article['content']}
61
62---
63"""
64
65 return prompt
66
67 def _fallback_digest(self, articles):
68 """Simple fallback if AI fails"""
69 digest = f"# Daily Digest - {datetime.now().strftime('%Y-%m-%d')}\n\n"
70
71 for article in articles:
72 digest += f"## {article['title']}\n"
73 digest += f"**Published:** {article['published']}\n"
74 digest += f"**Link:** {article['url']}\n\n"
75 digest += f"{article['content'][:200]}...\n\n---\n\n"
76
77 return digest
La chiave per buoni riassunti IA è creare prompt efficaci. Diamo all’IA istruzioni chiare e forniamo dati dell’articolo strutturati per l’analisi.
Mettere Tutto Insieme
Ecco la funzione principale che mette insieme tutti e tre i componenti:
1import os
2
3def main():
4 RSS_FEEDS = [
5 "https://feeds.bbci.co.uk/news/rss.xml",
6 "http://rss.cnn.com/rss/cnn_latest.rss/"
7 ]
8
9 print("Fetching articles from RSS feeds...")
10 all_articles = []
11
12 # Step 1: Parse RSS feeds
13 for feed_url in RSS_FEEDS:
14 try:
15 articles = parse_rss_feed(feed_url)
16 all_articles.extend(articles)
17 print(f"Fetched {len(articles)} articles from {feed_url}")
18 except Exception as e:
19 print(f"Error processing {feed_url}: {e}")
20
21 if not all_articles:
22 print("No articles found!")
23 return
24
25 # Sort by publication date (newest first)
26 all_articles.sort(key=lambda x: x['published'] or datetime.min, reverse=True)
27
28 # Step 2: Enhance with full content
29 print("Extracting full article content...")
30 enhanced_articles = enhance_articles(all_articles[:15]) # Process top 15
31
32 # Step 3: Generate AI digest
33 print("Generating AI digest...")
34
35 openai_api_key = os.getenv("OPENAI_API_KEY")
36 generator = DigestGenerator(openai_api_key)
37 digest = generator.create_digest(enhanced_articles)
38
39 # Save and display results
40 timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
41 filename = f"digest_{timestamp}.md"
42
43 with open(filename, 'w', encoding='utf-8') as f:
44 f.write(digest)
45
46 print(f"\n✅ Digest saved to {filename}")
47 print("\n" + "="*60)
48 print(digest)
49 print("="*60)
50
51if __name__ == "__main__":
52 main()
Il programma completo è disponibile qui
Conclusioni
Con un paio di centinaia di righe di codice Python siamo riusciti a costruire un sistema di digest che raccoglie informazioni da diversi feed e li riassume usando un LLM. Spero che questo ti abbia ispirato a costruire il tuo feed personale. Se l’argomento ti interessa, dai un’occhiata a Colino, un sistema di digest open source configurabile.
In un'era di sovraccarico informativo, rimanere aggiornati con le ultime notizie preferite può essere impegnativo.
Inoltre, internet è pieno di contenuti clickbait che ci distraggono dalle informazioni davvero importanti.
I feed RSS offrono una soluzione, ma chi ha tempo di leggere decine di articoli ogni giorno? Questo tutorial ti mostra come costruire un digest intelligente RSS che riassume automaticamente i contenuti usando l'IA.
Analizzeremo tre passaggi chiave: analizzare i feed RSS, estrarre il contenuto completo degli articoli e generare riassunti alimentati dall'IA usando l'API di OpenAI.
## Prerequisiti
Prima di iniziare, avrai bisogno di:
- Python 3.7+
- Una chiave API OpenAI
- Familiarità di base con Python
Installa i pacchetti richiesti:
```bash
pip install feedparser requests beautifulsoup4 openai
```
## Passaggio 1: Analizzare i Feed RSS con Python
I feed RSS (Really Simple Syndication) sono file XML che i siti web usano per pubblicare i loro contenuti più recenti. La libreria `feedparser` di Python rende facile lavorare con questi feed.
```python
import feedparser
import requests
from datetime import datetime, timezone
def parse_rss_feed(feed_url):
"""Parse a single RSS feed and extract articles"""
# Fetch the RSS feed
response = requests.get(feed_url, timeout=30)
response.raise_for_status()
# Parse the XML content
feed = feedparser.parse(response.content)
articles = []
for entry in feed.entries:
# Extract publication date
pub_date = None
if hasattr(entry, 'published_parsed') and entry.published_parsed:
pub_date = datetime(*entry.published_parsed[:6], tzinfo=timezone.utc)
# Get article content (summary from RSS)
content = getattr(entry, 'summary', '')
article = {
'title': entry.get('title', 'No Title'),
'url': entry.get('link', ''),
'content': content,
'published': pub_date,
'author': entry.get('author', 'Unknown')
}
articles.append(article)
return articles
# Example usage
feed_url = "https://feeds.bbci.co.uk/news/rss.xml"
articles = parse_rss_feed(feed_url)
print(f"Found {len(articles)} articles")
```
La libreria `feedparser` gestisce la complessità dell'analisi XML e fornisce un'interfaccia pulita per accedere ai metadati degli articoli come titoli, URL, date di pubblicazione e contenuto riassuntivo.
## Passaggio 2: Estrarre il Contenuto Completo con Beautiful Soup
I feed RSS tipicamente includono solo riassunti degli articoli. Per ottenere il contenuto completo per una migliore analisi IA, dobbiamo recuperare e analizzare le pagine web reali.
```python
from bs4 import BeautifulSoup
import re
def extract_article_content(url):
"""Fetch and extract main content from a web page"""
headers = {
'User-Agent': 'Mozilla/5.0 (compatible; RSS Reader/1.0)'
}
try:
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
# Parse HTML with Beautiful Soup
soup = BeautifulSoup(response.text, 'html.parser')
# Remove unwanted elements
for element in soup(['script', 'style', 'nav', 'footer', 'header', 'aside']):
element.decompose()
# Extract text content
content = soup.get_text(separator=' ', strip=True)
# Clean up whitespace
content = ' '.join(content.split())
# Limit content length for LLM processing
max_chars = 8000 # Roughly 2000 tokens
if len(content) > max_chars:
content = content[:max_chars] + "..."
return content if len(content) > 100 else None
except Exception as e:
print(f"Error extracting content from {url}: {e}")
return None
# Enhance articles with full content
def enhance_articles(articles):
"""Add full content to articles"""
for article in articles:
if article['url']:
full_content = extract_article_content(article['url'])
if full_content and len(full_content) > len(article['content']):
article['content'] = full_content
print(f"Enhanced: {article['title']}")
return articles
```
Beautiful Soup eccelle nell'analisi HTML e nell'estrazione di contenuto testuale pulito. Rimuoviamo elementi di navigazione, script e altre parti non-contenuto per concentrarci sul testo dell'articolo.
## Passaggio 3: Generare Riassunti IA con OpenAI
Ora arriva la magia: usare l'API di OpenAI per generare riassunti intelligenti dei nostri articoli raccolti.
```python
import openai
class DigestGenerator:
def __init__(self, api_key):
self.client = openai.OpenAI(api_key=api_key)
def create_digest(self, articles):
"""Generate an AI-powered digest of articles"""
# Prepare articles for the prompt
article_summaries = []
for i, article in enumerate(articles[:10], 1): # Limit to 10 articles
summary = {
'title': article['title'],
'content': article['content'][:1500], # Truncate for token limits
'url': article['url'],
'published': article['published'].strftime('%Y-%m-%d') if article['published'] else 'Unknown'
}
article_summaries.append(summary)
# Create the prompt
prompt = self._build_digest_prompt(article_summaries)
try:
response = self.client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}],
temperature=0.3,
max_tokens=2000
)
return response.choices[0].message.content
except Exception as e:
print(f"Error generating digest: {e}")
return self._fallback_digest(article_summaries)
def _build_digest_prompt(self, articles):
"""Build the prompt for AI digest generation"""
prompt = f"""Create a comprehensive daily digest from these {len(articles)} articles.
Instructions:
- Summarize the key themes and trends
- Group related topics together
- Highlight the most important developments
- Keep it engaging and informative
- Use markdown formatting
Articles:
"""
for i, article in enumerate(articles, 1):
prompt += f"""
## Article {i}: {article['title']}
**URL:** {article['url']}
**Published:** {article['published']}
{article['content']}
---
"""
return prompt
def _fallback_digest(self, articles):
"""Simple fallback if AI fails"""
digest = f"# Daily Digest - {datetime.now().strftime('%Y-%m-%d')}\n\n"
for article in articles:
digest += f"## {article['title']}\n"
digest += f"**Published:** {article['published']}\n"
digest += f"**Link:** {article['url']}\n\n"
digest += f"{article['content'][:200]}...\n\n---\n\n"
return digest
```
La chiave per buoni riassunti IA è creare prompt efficaci. Diamo all'IA istruzioni chiare e forniamo dati dell'articolo strutturati per l'analisi.
## Mettere Tutto Insieme
Ecco la funzione principale che mette insieme tutti e tre i componenti:
```python
import os
def main():
RSS_FEEDS = [
"https://feeds.bbci.co.uk/news/rss.xml",
"http://rss.cnn.com/rss/cnn_latest.rss/"
]
print("Fetching articles from RSS feeds...")
all_articles = []
# Step 1: Parse RSS feeds
for feed_url in RSS_FEEDS:
try:
articles = parse_rss_feed(feed_url)
all_articles.extend(articles)
print(f"Fetched {len(articles)} articles from {feed_url}")
except Exception as e:
print(f"Error processing {feed_url}: {e}")
if not all_articles:
print("No articles found!")
return
# Sort by publication date (newest first)
all_articles.sort(key=lambda x: x['published'] or datetime.min, reverse=True)
# Step 2: Enhance with full content
print("Extracting full article content...")
enhanced_articles = enhance_articles(all_articles[:15]) # Process top 15
# Step 3: Generate AI digest
print("Generating AI digest...")
openai_api_key = os.getenv("OPENAI_API_KEY")
generator = DigestGenerator(openai_api_key)
digest = generator.create_digest(enhanced_articles)
# Save and display results
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
filename = f"digest_{timestamp}.md"
with open(filename, 'w', encoding='utf-8') as f:
f.write(digest)
print(f"\n✅ Digest saved to {filename}")
print("\n" + "="*60)
print(digest)
print("="*60)
if __name__ == "__main__":
main()
```
Il programma completo è disponibile [qui](https://gist.github.com/dovidio/a36ad141cfd6f33966a8bbfc2ffcb92f)
## Conclusioni
Con un paio di centinaia di righe di codice Python siamo riusciti a costruire un sistema di digest che raccoglie informazioni da diversi feed e li riassume usando un LLM.
Spero che questo ti abbia ispirato a costruire il tuo feed personale. Se l'argomento ti interessa, dai un'occhiata a [Colino](https://github.com/dovidio/colino), un sistema di digest open source configurabile.