Python 获取网页视频

优采云 发布时间: 2022-06-04 00:28

  Python 获取网页视频

  前言

  最近在刷剧,想着把视频搞下来顺便学一下爬虫,网上看了一些资料,最后也成功了。以下是我获取视频的过程。

  创建IP池

  为了防止IP被ban先建立好IP池

  

  模拟登录

  在一些视频网站上看电影可能不需要登录直接可以观看,但是这里需要要登录,所以需要先进行模拟登录。

  这里可以采取selenium进行模拟登入,寻找相应元素并点击,不知道什么原因采取xpath路径寻找会找不到,所以采取css表达式进行寻找

  

  wd.find_element_by_css_selector('div[class="action mt_15"]').click()  # 点击登录按钮<br />wd.find_element_by_class_name("un-selected").click()  # 勾选服务<br />wd.find_elements_by_css_selector('span[class="type-icon"]')[0].click()  # 选择qq登录<br />

  之后选择qq的登录方式时,账号密码登录框架被嵌套两次,需要进行跳转到对应框架才能获取对应元素

  

  wd.switch_to.frame("_login_frame_quick_")  # 进入登录框架<br />wd.switch_to.frame("ptlogin_iframe")<br />wd.find_element_by_id('switcher_plogin').click() # 选择登录方式<br />account = wd.find_element_by_id('u')  # 账号<br />account.send_keys(account)<br />pd = wd.find_element_by_id('p')  # 密码<br />pd.send_keys(password)<br />wd.find_element_by_css_selector('a[class="login_button"]').click()  # 登录<br />

  获取m3u8

  常规播放方式是使用m3u8格式的ts流进行播放,只要能够截取到ts片段进行合成就可以获得整个视频,而ts链接存储在m3u8中,需要先获取m3u8文件

  腾讯视频的m3u8文件是隐藏的,通过开发者模式寻找比较费时。但是腾讯视频封装在window全局对象下边,可以通过js快速获取,避免大量寻找

  

  通过selenium执行js即可获得m3u8的下载地址从而获取m3u8

  

  def get_m3u8(txt):<br />    r = requests.get(txt,timeout=5,proxies=proxy)<br />    with open('movies.txt','wb') as f:<br />        f.write(r.content)<br /><br />wd.execute_script('alert(PLAYER._DownloadMonitor.context.dataset.currentVideoUrl);')<br />m3u8 = wd.switch_to.alert.text<br />get_m3u8(m3u8)<br />

  获取ts片段

  打开m3u8文件发现里面ts片段的地址是不全的,缺少前半部分,通过验证发现缺少的前半部分链接每次刷新视频后会更改,并不是固定的所以还是需要获取,经过验证发现缺少的链接包含在m3u8链接里面,所以ts片段完整链接=m3u8的部分链接+m3u8里面记载的ts链接

  def get_ts(n):<br />    with open("movies/" + str(n)+'.ts', 'wb') as f:<br />        try:<br />            r = requests.get(main_url+urls[n], timeout=5 ,proxies=proxy)<br />            r.raise_for_status()<br />            f.write(r.content)<br />            if flag == 1:<br />                failure_list.remove(n)<br />        except:<br />            if n not in failure_list:<br />                failure_list.append(n)<br /><br />main_url = '/'.join(m3u8.split('/')[0:-1])+'/'<br />urls = get_ts_url()  # 存储ts链接<br />for i in tqdm(ts_list, desc="正在获取片段:"):<br />    get_ts(i,proxies=proxy,timeout=5)<br />

  拼接

  检查每个ts片段是否异常,当所有片段是正常的后进行拼接,从而获取到视频

  # 合成ts片段<br />def get_video():<br />    files = [str(i)+'.ts' for i in range(len(os.listdir("movies/")))]<br />    if os.path.exists("movies.mp4"):<br />        os.remove("movies.mp4")<br />    for file in tqdm(files, desc="正在转换视频格式:"):<br />        if os.path.exists("movies/" + file):<br />            with open("movies/" + file, 'rb') as f1:<br />                with open("movies.mp4", 'ab') as f2:<br />                    f2.write(f1.read())<br />        else:<br />            print("失败")<br />            <br /># 检查是否片段是否完好<br />def check_ts():<br />    while failure_list:<br />        print("异常片段:")<br />        print(failure_list)<br />        for i in failure_list:<br />            get_ts(i)<br />    get_video()<br />

  补充

  selenium会在终端显示日志,导致进度条重复出现,这里关掉日志显示

  options = webdriver.ChromeOptions()<br />options.add_experimental_option('excludeSwitches', ['enable-logging'])<br />wd = webdriver.Chrome(chrome_options=options)<br />

  爬取完后发现,这样爬取的视频清晰度度是默认的,不是高清的。同时,切换清晰度的按钮是隐藏的,如果通过元素寻找直接点击会报错,但是将鼠标放在视频窗口上就可以显示清晰度按钮,进而点击切换清晰度

  # 切换清晰度<br />video = wd.find_element_by_css_selector('txpdiv[class="txp_shadow"]')<br />ActionChains(wd).move_to_element(video).perform()  # 控制鼠标移动到视频位置<br />wd.find_elements_by_css_selector('txpdiv[class="txp_label"]')[1].click()<br />wd.find_element_by_css_selector('txpdiv[data-role="txp-ui-control-definition-list"] txpdiv:nth-of-type(2)').click()  # 选择对应清晰度<br />

  

  总结

  获取ts片段时采用requests能够快速获取,而在模拟登录和获取m3u8上采取selenium比较浪费时间,效率不高,之后看看能不能采用requests代替selenium实现快速爬取。可能是反爬机制,尝试采取多线程直接拒绝访问了,所以只能采取单线程,后续看看能不能通过其他方式加快获取速度。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线