Skip to content

Instantly share code, notes, and snippets.

@irsl
Last active December 4, 2024 15:38
Show Gist options
  • Save irsl/c78b948c905314302557a109df97c1e8 to your computer and use it in GitHub Desktop.
Save irsl/c78b948c905314302557a109df97c1e8 to your computer and use it in GitHub Desktop.
Download a private facebook video
#!/usr/bin/env python3
import json
import re
import requests
import sys
def slurp(p):
with open(p, "r") as f:
return f.read()
def download_file(url, local_filename):
# NOTE the stream=True parameter below
with requests.get(url, stream=True) as r:
r.raise_for_status()
with open(local_filename, 'wb') as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
def do_the_job(html_source_file):
html_source = slurp(html_source_file)
scripts = re.findall(r'<script type="application/json" data-content-len="\d+" data-sjs>(.+)</script>', html_source)
for script in scripts:
if "video\/mp4" not in script:
continue
parsed_script = json.loads(script)
video_versions = parsed_script['require'][0][3][0]['__bbox']['require'][3][3][1]['__bbox']['result']['data']['video']['videoDeliveryResponseFragment']['videoDeliveryResponseResult']['progressive_urls']
if ".mp4?" not in json.dumps(video_versions):
raise Exception("no more")
candidates = {}
for video_version in video_versions:
candidates[video_version['metadata']['quality']] = video_version['progressive_url']
for quality in ["HD", "SD"]:
url = candidates.get(quality)
if not url:
continue
local_filename = html_source_file + ".mp4"
print("Downloading", url, "to", local_filename)
download_file(url, local_filename)
break
break
if __name__ == "__main__":
do_the_job(*sys.argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment