🎉
This commit is contained in:
@@ -0,0 +1,42 @@
|
|||||||
|
name: Update RSS Feed
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 6 * * *' # every day at 6:00 GMT (7CET/8CEST)
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-feed:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
env:
|
||||||
|
RUNNER_TOOL_CACHE: ${{ github.workspace }}/_work/_tool
|
||||||
|
AGENT_TOOLSDIRECTORY: ${{ github.workspace }}/_work/_tool
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: https://gitea.com/actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: https://gitea.com/actions/setup-python@7f4fc3e22c37d6ff65e88745f38bd3157c663f7c # v4.9.1
|
||||||
|
with:
|
||||||
|
python-version: '3.9.11'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
- name: Run Scrape Obec Žižkovo Pole
|
||||||
|
env:
|
||||||
|
FB_PAGE: "obec.zizkovopole"
|
||||||
|
run: |
|
||||||
|
python main.py "$FB_PAGE" --pages 2 --output "$FB_PAGE.xml"
|
||||||
|
|
||||||
|
- name: Commit and Push changes
|
||||||
|
run: |
|
||||||
|
git config --global user.name 'gitea-actions[bot]'
|
||||||
|
git config --global user.email 'gitea-actions[bot]@users.noreply.gitea.com'
|
||||||
|
git add *.xml
|
||||||
|
git commit -m "Update RSS feed(s)" || exit 0
|
||||||
|
git push
|
||||||
@@ -1,3 +1,56 @@
|
|||||||
# fb-rss-bridge
|
# Facebook to RSS Scraper
|
||||||
|
|
||||||
https://github.com/ManthsCode/fb-rss-bridge
|
This tool scrapes public posts from a Facebook page and converts them into an RSS feed (.xml). It can be run locally or automated using GitHub Actions.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Python 3.9+
|
||||||
|
- pip (Python package installer)
|
||||||
|
|
||||||
|
## Local Installation & Usage
|
||||||
|
|
||||||
|
1. **Clone the repository:**
|
||||||
|
```bash
|
||||||
|
git clone <repository-url>
|
||||||
|
cd fb-rss-bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Install dependencies:**
|
||||||
|
It is recommended to use a virtual environment.
|
||||||
|
```bash
|
||||||
|
python3 -m venv .venv
|
||||||
|
source .venv/bin/activate
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Run the scraper:**
|
||||||
|
```bash
|
||||||
|
python3 main.py <page_name>
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace `<page_name>` with the Facebook page ID or username.
|
||||||
|
|
||||||
|
**Options:**
|
||||||
|
- `--output`: Specify output file name (default: `feed.xml`)
|
||||||
|
- `--pages`: Number of pages to scrape (default: 1)
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
python3 main.py GitHub --pages 2 --output github_feed.xml
|
||||||
|
```
|
||||||
|
|
||||||
|
## GitHub/Gitea Actions Automated Feed (Free Cloud Solution)
|
||||||
|
|
||||||
|
This repository is configured to run automatically on GitHub's free tier for public repositories.
|
||||||
|
|
||||||
|
1. **How it works:**
|
||||||
|
- The `.gitea/workflows/update_feed.yml` file defines a "cron job" that runs every 6 hours.
|
||||||
|
- It spins up a temporary server (runner), installs Python, runs the script, and saves the `feed.xml` back to your code.
|
||||||
|
- This entire process is free for public repositories on GitHub.
|
||||||
|
|
||||||
|
2. **Configuration:**
|
||||||
|
The workflow is scheduled to run every 6 hours. You can customize the target Facebook page in `.gitea/workflows/update_feed.yml`:
|
||||||
|
```yaml
|
||||||
|
env:
|
||||||
|
FB_PAGE: "GitHub" # Change this to the desired page ID/username
|
||||||
|
```
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
from facebook_scraper import get_posts
|
||||||
|
from rfeed import Item, Feed, Guid
|
||||||
|
import datetime
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Configure logging
|
||||||
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||||
|
|
||||||
|
def scrape_facebook_page(page_name, pages_count=1):
|
||||||
|
"""
|
||||||
|
Scrapes the posts from a Facebook page.
|
||||||
|
"""
|
||||||
|
logging.info(f"Starting scrape for page: {page_name}")
|
||||||
|
posts_data = []
|
||||||
|
try:
|
||||||
|
# get_posts returns a generator
|
||||||
|
for post in get_posts(page_name, pages=pages_count):
|
||||||
|
posts_data.append(post)
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error scraping page {page_name}: {e}")
|
||||||
|
|
||||||
|
logging.info(f"Retrieved {len(posts_data)} posts.")
|
||||||
|
return posts_data
|
||||||
|
|
||||||
|
def generate_rss(posts, page_name, output_file="feed.xml"):
|
||||||
|
"""
|
||||||
|
Generates an RSS feed from the scraped posts.
|
||||||
|
"""
|
||||||
|
items = []
|
||||||
|
for post in posts:
|
||||||
|
# Extract relevant data
|
||||||
|
post_id = post.get('post_id')
|
||||||
|
text = post.get('text') or "No text content"
|
||||||
|
post_url = post.get('post_url')
|
||||||
|
time = post.get('time')
|
||||||
|
image = post.get('image')
|
||||||
|
|
||||||
|
# Create RSS item
|
||||||
|
item = Item(
|
||||||
|
title=text[:60] + "..." if len(text) > 60 else text,
|
||||||
|
link=post_url,
|
||||||
|
description=f"{text}<br/><br/>" + (f"<img src='{image}'/>" if image else ""),
|
||||||
|
author=page_name,
|
||||||
|
guid=Guid(post_id),
|
||||||
|
pubDate=time
|
||||||
|
)
|
||||||
|
items.append(item)
|
||||||
|
|
||||||
|
feed = Feed(
|
||||||
|
title=f"{page_name} Facebook Feed",
|
||||||
|
link=f"https://www.facebook.com/{page_name}",
|
||||||
|
description=f"RSS feed for {page_name} Facebook page",
|
||||||
|
language="en-US",
|
||||||
|
lastBuildDate=datetime.datetime.now(),
|
||||||
|
items=items
|
||||||
|
)
|
||||||
|
|
||||||
|
with open(output_file, "w", encoding='utf-8') as f:
|
||||||
|
f.write(feed.rss())
|
||||||
|
logging.info(f"RSS feed written to {output_file}")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="Facebook to RSS Scraper")
|
||||||
|
parser.add_argument("page_name", help="Name or ID of the Facebook page")
|
||||||
|
parser.add_argument("--output", default="feed.xml", help="Output RSS file name")
|
||||||
|
parser.add_argument("--pages", type=int, default=1, help="Number of pages to scrape")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
posts = scrape_facebook_page(args.page_name, args.pages)
|
||||||
|
if posts:
|
||||||
|
generate_rss(posts, args.page_name, args.output)
|
||||||
|
else:
|
||||||
|
logging.warning("No posts found or scraping failed.")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
facebook-scraper
|
||||||
|
rfeed
|
||||||
Reference in New Issue
Block a user