美文网首页效率
9行代码实现YouTube视频批量下载

9行代码实现YouTube视频批量下载

作者: 林清猫耳 | 来源:发表于2018-11-05 11:50 被阅读741次

    先上源码:

    import re, os, requests
    
    url = r"https://www.youtube.com/playlist?list=PLXO45tsB95cK7G-raBeTVjAoZHtJpiKh3"    #youtube播放列表
    headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'}
    html = requests.get(url, headers=headers).text
    videoIds = re.findall('"videoId":"([A-Za-z0-9_-]{11})","thumbnail"', html)
    for videoId in videoIds:
        download_link = "https://youtu.be/" + videoId  # 构造下载地址
        os.chdir(r"C:\Users\Ph\Videos\RL")
        os.system("youtube-dl " + download_link)  # 用youtube-dl下载视频
    

    从YouTube批量下载视频只有两步:

    1. 拿到播放列表里每个视频的url
    2. 使用youtube-dl下载视频

    其中第一步拿到每个视频的url有两种方法,以上代码是第一种方法,简单粗暴。

    仔细分析视频url的结构可以发现,最重要的是一个11位的videoId (不一定全都是11位)。并且可以发现videoId是由字母A-Za-z数字0-9和符号-_组成的 (不排除还有其它特殊符号)。
    所以,要拿到每个视频的url只需要拿到每个视频的videoId即可。

    第一种方法是使用requests请求播放列表页面拿到网页源代码,然后直接用正则表达式匹配拿到该页12个视频的videoId。再拼接构造下载地址并使用youtube-dl下载视频。

    关于youtube-dl的安装和使用可以参考这篇博客

    当然,上面的代码有刻意写短的嫌疑。实际写爬虫代码在写requests请求时应该加上try...except...来捕获请求异常并作相应处理。


    下面介绍第二种方法,用webdriver模拟无头浏览器来拿到视频url。

    设置Chrome无头浏览器,拿到播放列表页面的网页源代码:

    from selenium import webdriver
    
    opt= webdriver.ChromeOptions()
    opt.add_argument('headless')
    driver= webdriver.Chrome(chrome_options=opt)
    driver.get(url)
    r = driver.page_source
    

    但这里拿到的page_source和上面第一种方法requests.get拿到的网页源代码是不一样的。这里拿到的是浏览器解析执行JavaScript代码后渲染出来的Elements。

    然后就是解析page_source来拿视频url啦。通过定位可以发现视频url藏在idthumbnaila标签中:

    a标签

    这一步可以用XPath:

    from lxml import etree
    
    html = etree.HTML(r)
    div = html.xpath('//a[@id="thumbnail"]')
    for a in div:
        link = a.get('href')
        videoId = re.findall(r'v=(.*?)&', link)[0]
        download_link = "https://youtu.be/" + videoId
    

    也可以用pyquery:

    from pyquery import PyQuery as pq
    
    doc = pq(r, parser="html") 
    links = doc('a#thumbnail').items()
    for a in links:
        link = a.attr['href'])
        videoId = re.findall(r'v=(.*?)&', link)[0]
        download_link = "https://youtu.be/" + videoId
    

    用pyquery这里有个小坑,观察page_source第一行可以发现有 xmlns="http://www.w3.org/1999/xhtml"。 而pyquery默认解析后的文档是xmlns格式,因此需要配置parse="html",否则使用a#thumbnail无法正常拿到a标签。参考自 https://segmentfault.com/a/1190000016575362

    拿到的link以及download_link如下:


    视频links

    下面是下载过程及结果:


    downloading videos

    相关文章

      网友评论

        本文标题:9行代码实现YouTube视频批量下载

        本文链接:https://www.haomeiwen.com/subject/kqwjxqtx.html