Commit 6752015d authored by Benavides Ontiveros's avatar Benavides Ontiveros
Browse files

add mutiple subreddit fetch and error handling

parent 32c81dd5
import praw import praw
import json import json
import os import os
import logging
from dotenv import load_dotenv from dotenv import load_dotenv
from datetime import datetime, timezone from datetime import datetime, timezone
# --- Setup logging ---
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
handlers=[
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
# --- Load environment variables --- # --- Load environment variables ---
load_dotenv() load_dotenv()
# --- Validate environment variables ---
try:
subreddits_env = os.getenv("SUBREDDITS")
if not subreddits_env:
raise ValueError("Environment variable SUBREDDITS is missing.")
subreddit_list = [s.strip() for s in subreddits_env.split(",")]
POST_LIMIT = int(os.getenv("POST_LIMIT", 10))
COMMENT_LIMIT = int(os.getenv("COMMENT_LIMIT", 10))
if POST_LIMIT < 1 or COMMENT_LIMIT < 0:
raise ValueError("POST_LIMIT and COMMENT_LIMIT must be positive integers.")
OUTPUT_DIR = os.getenv("OUTPUT_DIR", ".")
os.makedirs(OUTPUT_DIR, exist_ok=True)
# Create .meta folder inside OUTPUT_DIR
META_DIR = os.path.join(OUTPUT_DIR, ".meta")
os.makedirs(META_DIR, exist_ok=True)
except Exception as e:
logger.error(f"Invalid configuration: {e}")
raise SystemExit(1)
# --- Reddit API credentials --- # --- Reddit API credentials ---
reddit = praw.Reddit( try:
client_id=os.getenv("REDDIT_CLIENT_ID"), reddit = praw.Reddit(
client_secret=os.getenv("REDDIT_CLIENT_SECRET"), client_id=os.getenv("REDDIT_CLIENT_ID"),
user_agent="MyRedditScraper/1.0" client_secret=os.getenv("REDDIT_CLIENT_SECRET"),
) user_agent="MyRedditScraper/1.0"
)
reddit.user.me() # Test authentication
except Exception as e:
logger.error(f"Failed to authenticate with Reddit API: {e}")
raise SystemExit(1)
# --- Choose subreddit and fetch posts --- # --- Process each subreddit ---
subreddit_name = "worldnews" for subreddit_name in subreddit_list:
subreddit = reddit.subreddit(subreddit_name) logger.info(f"Processing subreddit: {subreddit_name}")
data = []
data = [] try:
subreddit = reddit.subreddit(subreddit_name)
except Exception as e:
logger.error(f"Cannot access subreddit '{subreddit_name}': {e}")
continue
for post in subreddit.hot(limit=5): # get top 5 hot posts # Fetch posts
post.comments.replace_more(limit=0) # remove 'MoreComments' objects try:
posts = subreddit.hot(limit=POST_LIMIT)
except Exception as e:
logger.error(f"Failed to retrieve posts for r/{subreddit_name}: {e}")
continue
post_data = { # Process posts
"id": post.id, for post in posts:
"title": post.title, try:
"score": post.score, post.comments.replace_more(limit=0)
"url": post.url, except Exception as e:
"num_comments": post.num_comments, logger.warning(f"Comments for post {post.id} not fully loaded: {e}")
"created_utc": post.created_utc,
"comments": [] try:
} post_data = {
"id": post.id,
"title": post.title,
"score": post.score,
"url": post.url,
"num_comments": post.num_comments,
"created_utc": post.created_utc,
"comments": []
}
except Exception as e:
logger.error(f"Failed to read post data for {post.id}: {e}")
continue
# Fetch comments
try:
comments = post.comments.list()[:COMMENT_LIMIT]
except Exception as e:
logger.warning(f"Failed to load comments for post {post.id}: {e}")
comments = []
for comment in comments:
try:
post_data["comments"].append({
"id": comment.id,
"body": comment.body,
"score": comment.score,
"created_utc": comment.created_utc
})
except Exception as e:
logger.warning(f"Failed to parse a comment in post {post.id}: {e}")
# Collect top-level comments data.append(post_data)
for comment in post.comments.list()[:15]: # limit to first 15 comments
post_data["comments"].append({ # Wrap in top-level field
"id": comment.id, wrapped_output = {
"body": comment.body, "subreddit": subreddit_name,
"score": comment.score, "posts": data
"created_utc": comment.created_utc
})
data.append(post_data)
# --- Convert to JSON string ---
json_output = json.dumps(data, indent=4)
# --- Save Reddit data to .txt file ---
txt_filename = "reddit_data.txt"
with open(txt_filename, "w", encoding="utf-8") as f:
f.write(json_output)
print(f"Saved Reddit data to {txt_filename}")
# --- Create metadata JSON ---
metadata = {
"title": "Reddit " + subreddit_name,
"backlink": "C:\\Users\\USER\\Desktop\\Semester-1\\ST-SOP_Software-Project\\BigData4Biz\\ingest\\reddit_data.txt", # Replace for local ingest path
"language": "en",
"classifications": [subreddit_name],
"properties": {
"creation_date": int(datetime.now(timezone.utc).timestamp() * 1000)
} }
}
metadata_filename = "reddit_data.txt.json" # --- Generate Unix timestamp in milliseconds for unique file names ---
with open(metadata_filename, "w", encoding="utf-8") as f: timestamp_ms = int(datetime.now(timezone.utc).timestamp() * 1000)
json.dump(metadata, f, indent=4)
# Output data file
data_filename = os.path.join(OUTPUT_DIR, f"reddit_{subreddit_name}_{timestamp_ms}.txt")
try:
with open(data_filename, "w", encoding="utf-8") as f:
json.dump(wrapped_output, f, indent=4)
logger.info(f"Saved Reddit data → {data_filename}")
except Exception as e:
logger.error(f"Failed to save data file for r/{subreddit_name}: {e}")
continue
# Output metadata file in .meta folder
metadata_filename = os.path.join(META_DIR, f"reddit_{subreddit_name}_{timestamp_ms}.txt.json")
metadata = {
"title": f"Reddit {subreddit_name}",
"backlink": data_filename,
"language": "en",
"classifications": [subreddit_name],
"properties": {
"creation_date": timestamp_ms
}
}
print(f"Saved metadata to {metadata_filename}") try:
\ No newline at end of file with open(metadata_filename, "w", encoding="utf-8") as f:
json.dump(metadata, f, indent=4)
logger.info(f"Saved metadata → {metadata_filename}")
except Exception as e:
logger.error(f"Failed to save metadata for r/{subreddit_name}: {e}")
\ No newline at end of file
{ {
"title": "Reddit worldnews", "title": "Reddit worldnews",
"backlink": "C:\\Users\\USER\\Desktop\\Semester-1\\ST-SOP_Software-Project\\BigData4Biz\\ingest\\reddit_data.txt", "backlink": "C:\\Users\\USER\\Desktop\\Semester-1\\ST-SOP_Software-Project\\BigData4Biz\\ingest\\reddit_worldnews_1764111620240.txt",
"language": "en", "language": "en",
"classifications": [ "classifications": [
"worldnews" "worldnews"
], ],
"properties": { "properties": {
"creation_date": 1764001787548 "creation_date": 1764111620240
} }
} }
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment