mirror of
https://github.com/bellingcat/facebook-downloader.git
synced 2026-06-08 03:28:31 +03:00
Added downloader.py, geckodriver.exe, and updated LICENSE, README.md
Added/Updated: 1. downloader.py: the main file and contains all the code 2. geckodriver.exe: the binary that will be required to run selenium 3. LICENSE: license text has been updated 4. README.md: Updated readme
This commit is contained in:
6
LICENSE
6
LICENSE
@@ -631,8 +631,8 @@ to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
Facebook video downloader
|
||||
Copyright (C) 2022 Richard Mwewa
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
Facebook-Downloader Copyright (C) 2022 Richard Mwewa
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
62
README.md
62
README.md
@@ -1,2 +1,62 @@
|
||||
# Facebook-Downloader
|
||||
Facebook video downloader
|
||||
A program for downloading Facebook videos
|
||||
|
||||
# Installation
|
||||
**1. Clone the project**
|
||||
```
|
||||
git clone https://github.com/rly0nheart/Facebook-Downloader.git
|
||||
```
|
||||
|
||||
**2. Move to Facebook-Downloader directory**
|
||||
```
|
||||
cd Facebook-Downloader
|
||||
```
|
||||
|
||||
**3. Install dependencies**
|
||||
## Note
|
||||
> *This will install tqdm, selenium, and requests*
|
||||
> > *You will need to have Firefox installed to run the program*
|
||||
> > > *For user convenience, the program will come with a geckodriver.exe binary*
|
||||
```
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
# Usage
|
||||
```
|
||||
python downloader.py <facebook-url>
|
||||
```
|
||||
|
||||
> *Alternatively, you could grant execution permission to the downloader and run it as shown below*
|
||||
|
||||
**1. Grant execution permission**
|
||||
```
|
||||
chmod +x downloader.py
|
||||
```
|
||||
|
||||
**2. Run downloader**
|
||||
```
|
||||
./downloader.py <facebook-url>
|
||||
```
|
||||
|
||||
## Example
|
||||
```
|
||||
python downloader.py https://www.facebook.com/PageName/videos/VideoID
|
||||
```
|
||||
|
||||
## Note
|
||||
> Upon run, the downloader will first check for updates. If found, users will be prompted to download the updates
|
||||
|
||||
|
||||
# Optional Arguments
|
||||
| Flag | Description |
|
||||
|---------|:-----------:|
|
||||
| *-A/--audio* | download audio only (coming soon) |
|
||||
| *-o/--output* | output filename |
|
||||
| *-v/--version* | show program's version number and exit |
|
||||
|
||||
# Donations
|
||||
If you would like to donate, you could Buy A Coffee for the developer using the button below
|
||||
|
||||
<a href="https://www.buymeacoffee.com/189381184" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>
|
||||
|
||||
Your support will be much appreciated!
|
||||
|
||||
96
downloader.py
Normal file
96
downloader.py
Normal file
@@ -0,0 +1,96 @@
|
||||
import time
|
||||
import logging
|
||||
import argparse
|
||||
import requests
|
||||
from tqdm import tqdm
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
|
||||
|
||||
class FacebookDownloader:
|
||||
|
||||
def __init__(self, args):
|
||||
self.option = webdriver.FirefoxOptions()
|
||||
self.option.add_argument('--headless')
|
||||
self.driver = webdriver.Firefox(options=self.option)
|
||||
self.program_version_number = "2022.1.0.0"
|
||||
self.downloading_url = "https://getfvid.com"
|
||||
self.update_check_endpoint = "https://api.github.com/repos/rly0nheart/Facebook-Downloader/releases/latest"
|
||||
|
||||
|
||||
def notice(self):
|
||||
notice_msg = f"""
|
||||
Facebook-Downloader {self.program_version_number} Copyright (C) 2022 Richard Mwewa
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
"""
|
||||
return notice_msg
|
||||
|
||||
|
||||
def check_and_get_updates(self):
|
||||
print(self.notice())
|
||||
response = requests.get(self.update_check_endpoint).json()
|
||||
if response['tag_name'] == self.program_version_number:
|
||||
"""Ignore if the program is up to date"""
|
||||
pass
|
||||
else:
|
||||
update_prompt = input(f"[?] A new release is available ({response['tag_name']}). Would you like to install it? (y/n) ")
|
||||
if update_prompt.lower() == "y":
|
||||
files_to_update = ['downloader.py', 'geckodriver.exe', 'README.md', 'requirements.txt']
|
||||
for file in tqdm(files_to_update, desc=f'Updating'):
|
||||
data = requests.get(f'https://raw.githubusercontent.com/rly0nheart/Facebook-Downloader/master/{file}')
|
||||
with open(file, "wb") as f:
|
||||
f.write(data.content)
|
||||
f.close()
|
||||
exit(f"Updated: Re-run program.")
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
def download_video(self):
|
||||
self.check_and_get_updates()
|
||||
self.driver.get(self.downloading_url) # Opening getfvid.com, a website that downloads facebook videos
|
||||
url_entry_field = self.driver.find_element(By.NAME, "url") # Find the url entry field
|
||||
url_entry_field.send_keys(args.url) # write facebook url in the entry field
|
||||
url_entry_field.send_keys(Keys.ENTER) # press enter
|
||||
time.sleep(20) # Sleep for at least 20 seconds to wait for the next page to load
|
||||
self.driver.refresh
|
||||
|
||||
"""
|
||||
HD: "/html/body/div[2]/div/div/div[1]/div/div[2]/div/div[3]/p[1]/a"
|
||||
SD: "/html/body/div[2]/div/div/div[1]/div/div[2]/div/div[3]/p[2]/a"
|
||||
Audio: "/html/body/div[2]/div/div/div[1]/div/div[2]/div/div[3]/p[3]/a"
|
||||
"""
|
||||
|
||||
download_btn = self.driver.find_element(By.XPATH, '/html/body/div[2]/div/div/div[1]/div/div[2]/div/div[3]/p[1]/a') # Find the download button (this clicks the first button which returns a video in hd)
|
||||
download_url = download_btn.get_attribute('href')
|
||||
|
||||
with requests.get(download_url, stream=True) as response:
|
||||
response.raise_for_status()
|
||||
with open(f'downloads/{args.output}.mp4', 'wb') as file:
|
||||
for chunk in tqdm(response.iter_content(chunk_size=8192), desc=f'Downloading: {args.output}.mp4'):
|
||||
file.write(chunk)
|
||||
print(f'Downloaded: {file.name}')
|
||||
self.driver.close()
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description='Facebook-Downloader — by Richard Mwewa')
|
||||
parser.add_argument('url', help='facebook video url (eg. https://www.facebook.com/PageName/videos/VideoID')
|
||||
parser.add_argument('-A', '--audio', help=argparse.SUPPRESS, action='store_true')
|
||||
parser.add_argument('-o', '--output', help='output filename')
|
||||
args = parser.parse_args()
|
||||
logging.basicConfig(format='[%(asctime)s] %(levelname)s: %(message)s', datefmt='%I:%M:%S%p', level='NOTSET')
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
FacebookDownloader(args).download_video()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
logging.warning('Process interrupted with Ctrl+C.')
|
||||
|
||||
except Exception as e:
|
||||
logging.error(e)
|
||||
BIN
geckodriver.exe
Normal file
BIN
geckodriver.exe
Normal file
Binary file not shown.
Reference in New Issue
Block a user