Skip to content

Instantly share code, notes, and snippets.

@novitae
Last active March 18, 2022 19:21
Show Gist options
  • Save novitae/cadb21f9ac662b9a1ce3819813026f63 to your computer and use it in GitHub Desktop.
Save novitae/cadb21f9ac662b9a1ce3819813026f63 to your computer and use it in GitHub Desktop.
from argparse import ArgumentParser
from re import match
import requests
from os import path
from tqdm import tqdm
class UrlNotMatchingError(Exception): pass
class APIFetchingError(Exception): pass
def _getApiResp(url) -> dict:
resp = requests.get(url, headers={
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15"
}, allow_redirects=False)
if resp.status_code == 302:
loc = resp.headers.get("Location")
vid = loc.split("/")[-2]
api = requests.get(f"https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids={vid}", headers={
"Host": "www.iesdouyin.com",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive",
"Accept": "*/*",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15",
"Referer": loc,
"Accept-Language": "fr-FR,fr;q=0.9",
"X-Requested-With": "XMLHttpRequest"
})
return api.json()
raise APIFetchingError(f"{url} responded {resp.status_code}.")
def _checkUrlFormat(url) -> str:
if match(r"https:\/\/v\.douyin\.com\/[A-Za-z0-9]{6,8}\/", url):
return url
raise UrlNotMatchingError(f"""{url} doesn't match r"https:\/\/v\.douyin\.com\/[A-Za-z0-9]{{6,8}}\/\"""")
def _parseResp(j) -> list:
retour = []
uid = j["item_list"][0]["author"]["unique_id"]
for x, imgnfo in enumerate(j["item_list"][0]["images"]):
retour.append({f"{uid}_{x}.webp":imgnfo["url_list"][0]})
return retour
def _getPicBinary(url) -> bytes:
host = url.split("//")[-1].split("/")[0]
image = requests.get(url, headers = {
"Accept": "image/webp,image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5",
"Accept-Encoding": "gzip, deflate, br",
"Host": host,
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15",
"Accept-Language": "fr-FR,fr;q=0.9",
"Referer": "https://www.iesdouyin.com/",
"Connection": "keep-alive"
})
return image.content
def main() -> None:
p = ArgumentParser()
p.add_argument("url", help="The url of the video to download")
p.add_argument("-p","--path", help="Path to export the images")
a = p.parse_args()
url = _checkUrlFormat(url=a.url)
pth = a.path if a.path else path.dirname(__file__)
j = _getApiResp(url=url)
pics = _parseResp(j=j)
for name, picurl in tqdm([tuple(p.items())[0] for p in pics]):
open(path.join(pth, name),"wb").write(_getPicBinary(picurl))
if __name__ == "__main__":
main()

This program downloads Douyin Diaporamas in full size no-watermark.
Copy this file somewhere on your computer.

# to install requirements
pip install tqdm requests argparse

# to print help
python DouyinDiaporamaDownloader.py -h

# to download pics from a douyin diapo url
python DouyinDiaporamaDownloader.py https://v.douyin.com/NA4uke8/

# to download pics from a douyin diapo url with a specified path
python DouyinDiaporamaDownloader.py https://v.douyin.com/NA4uke8/ --path /Desktop/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment