1
\$\begingroup\$

As I'm located in China, using YouTube is a headache for me. I know about youtube-dl, but I just started learning and decided to build something myself. With a bunch of things TBD, it basically does the job.

Can I check results of downloading in a more efficient way? E.g. can I get file size from Chrome before the download starts?

import requests
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import os
import time


def getHTMLPage(playlist):
    """Extracts playlist html source from youtube"""
    try:
        r = requests.get(playlist, timeout=30)
        r.enconding = 'utf8'
        r.raise_for_status()
        return r.text
    except:
        return ''


def getPlaylistLinks(playlist_page):
    """Gets links of all videos in the playlist"""
    soup = BeautifulSoup(playlist_page, 'html.parser')
    clip_links = []
    a = soup.find_all('a', {'class': 'pl-video-title-link yt-uix-tile-link yt-uix-sessionlink spf-link '})
    for entry in a:
        try:
            href = 'https://www.youtube.com/'+entry.attrs['href'][:20]
            name = entry.string.strip()
            clip_links.append([name, href])
        except:
            continue
    h1 = soup.find('h1', {'class': 'pl-header-title'})
    playlist_name = h1.string.strip()
    return clip_links, playlist_name


def downloadFromSavemedia(url, driver, clip_link, number):
    """Helper function for getDownloads, initiates download from
    savemedia.com"""
    driver.get(url)
    try:
        start_time = time.time()
        input_bar = driver.find_element_by_id("video-url")
        input_bar.send_keys(clip_link, Keys.ENTER)
        submit_button = driver.find_element_by_id('download-submit')
        submit_button.click()
        driver.implicitly_wait(6)
        download_button = driver.find_element_by_id("get_video")
        wrapper_link = download_button.get_attribute('data-href')
        print('Got the link, ' + wrapper_link)
        if wrapper_link is None:
            raise Exception('Did not get the link')
        driver.get(url+wrapper_link)
        if time.time() - start_time > 120:
            raise Exception('Overtime')  # try to handle vpn connection quality issues
        return True
    except:
        print('smth went wrong for file #{}'.format(number))
        return False


def checkFileStatus(file_name):
    """Helper function for getDownloads, waits file to be downloaded"""
    print('Ok, writing exactly ' + file_name)
    checkFlag = False
    while not checkFlag:
        if os.path.exists(file_name):
            print(file_name + " exists")
            check_one = os.path.getsize(file_name)
            time.sleep(5)
            check_two = os.path.getsize(file_name)
            if check_two == check_one:
                checkFlag = True
                print(file_name + ' has been saved')
                return
        else:
            time.sleep(5)


def getDownloads(clip_links, home_dir):
    """Manages the whole downloading process
    - opens webdrive with Chrome
    - saves and renames files from valid links
    -  quits webdrive"""
    chromeOptions = webdriver.ChromeOptions()
    prefs = {"download.default_directory": home_dir}
    chromeOptions.add_experimental_option("prefs", prefs)
    chromedriver = 'C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe'
    savemediaurl = 'http://savemedia.com/'
    for index, entry in enumerate(clip_links):
        driver = webdriver.Chrome(executable_path=chromedriver, chrome_options=chromeOptions)
        saved_file = downloadFromSavemedia(savemediaurl, driver, entry[1], index+1)
        if saved_file:
            old_name = entry[0] + '.mp4'
            checkFileStatus(old_name)
            new_name = str(index+1).zfill(2) + '. ' + entry[0] + '.mp4'
            os.rename(old_name, new_name)
        driver.quit()
    return


def main():
    """Implements the logics of this script"""
    playlist = 'linktext'
    html = getHTMLPage(playlist)
    clip_links, playlist_name = getPlaylistLinks(html)
    if not os.path.exists(("C:\\Users\Mikhail Belousov\\Downloads\\" + playlist_name)):
        os.makedirs("C:\\Users\Mikhail Belousov\\Downloads\\" + playlist_name)
    os.chdir("C:\\Users\Mikhail Belousov\\Downloads\\" + playlist_name)
    home_dir = os.getcwd()
    getDownloads(clip_links, home_dir)

if __name__ == '__main__':
    main()
\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to StackExchange Code Review! Please review How do I ask a good Question? Specifically, Be sure to embed the code you want reviewed in the question itself; you can leave supporting, but non-essential, code in links to other sites. \$\endgroup\$ – Stephen Rauch Mar 19 '17 at 15:20
  • \$\begingroup\$ Don't worry about the length, 136 lines is nothing :) Just paste the code here (and make sure to mark it as code by selecting the whole code and pressing CTRL-K). \$\endgroup\$ – Graipher Mar 19 '17 at 16:44
  • \$\begingroup\$ @Jamal, why can't I ask three questions? Do I violate the rules in this way? \$\endgroup\$ – Mikhail Belousov Mar 19 '17 at 20:26
  • \$\begingroup\$ The first two were off-topic because they were asking about implementing new code. We only work with existing code. \$\endgroup\$ – Jamal Mar 19 '17 at 20:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.