Python 动态网页抓取之提取视频源

最近遇到一个需求:根据优酷ios客户端分享来的链接,提取出视频源,并在ios系统播放器播放。在踩了一些坑之后,笔者对视频网站的提取也有了一些经验,在此做个总结,为以后遇到这个问题的同学提供一些经验和方向。

1. 简介

提取网站视频链接分三种情况:

  1. 电脑版网页链接,在查看这类网页源代码时会发现视频源为flash文件,无法获取有效的视频地址,需要使用第三方库You-Get
  2. 遗憾的是You-Get并非支持所有的视频网站,对于不能支持的视频网站,需要设置User-Agent模拟iPhone用户进行提取,或者破解其加密方式
  3. iPhone Safair中的视频源,这个是本文的重点

2. 使用You-Get抓取视频地址

You-Get 实际上是一个视频下载器,用 Python3 编写,运行在命令行环境而不是GUI。它支持很多视频网站,具体可以看Github项目的介绍,并且持续更新中。

安装You-Get

You-Get 运行在 Python3 环境下,不支持Python2.x。所以在开始之前,系统中至少有一个Python3.x版本。

虽然项目介绍中说明可以直接编译源码安装,但是如果没有特殊要求,使用 pip 是最简单的安装方式。
pip 的安装可以查看这篇文章pip installation

使用pip安装You-get

$ [sudo] pip3 install you-get   

检查是否安装成功

$ you-get -V

使用You-Get下载视频

$ you-get http://youtu.be/sGwy8DsUJ4M

显示视频信息

$ you-get -u http://youtu.be/sGwy8DsUJ4M

使用you-get -u $link返回视频信息,然后用正则表达式将视频链接提取出来即可。

一些问题

  1. ios系统播放器只支持mp4和mov等少数几种视频格式。但是在下载的视频中很多是flv格式,无法在系统播放器中播放。
  2. 手机中分享来的视频网址无法使用You-Get提取视频。
  3. You-Get并非支持所有视频网站。

3. 提取手机Safari的视频链接

虽然ios系统不支持flv等视频格式,但是优酷等网站在safari中仍可以播放。所以笔者猜测在手机端视频并非以falsh文件方式播放。通过设置User-Agent Mozilla/5.0 (iPhone; CPU iPhone OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B410 Safari/600.1.4模拟手机浏览器访问视频网站,在源代码中可以得到视频链接。

视频链接 http://v.youku.com/v_show/id_XMTMzMzkxNzgwOA==_ev_1.html?x

image

以及网页源代码

image

图中src就是我们需要的内容。

知道了源码中含有视频链接就好办多了,只要我们获取到源码,然后利用正则表达式提取出视频链接即可。但是,尝试后发现,视频标签部分是动态获取的,破解js比较麻烦,而且并不通用,所以这里采用一种简单粗暴的方案:

在服务器端运行一个虚拟窗口,通过调用浏览器加载网页,并对最终代码做正则提取出视频地址。

运行环境

CentOs系统,使用python3.4版本,1M带宽,FireFox浏览器

使用Splinter调用浏览器

Splinter是一款Python自动化测试工具,可以模拟浏览器的行为。可以运行js,支持鼠标操作等。

安装稳定版

$ [sudo] pip install splinter

或者源码安装

$ git clone git://github.com/cobrateam/splinter.git
$ cd splinter
$ [sudo] python setup.py install

代码示例

browser = Browser()
browser.visit(url)
html = browser.html

browser.quit()

运行虚拟桌面

centos服务器是没有桌面的。为了能在服务器中调用浏览器进行渲染,笔者在centos命令行界面运行一个虚拟的桌面。Xvfb新建一个虚拟的X窗口,配合python的pyvirtualdisplay进行操作。

安装

# 安装Xvfb和pyvirtualdisplay
yum install xorg-x11-server-Xvfb
pip install pyvirtualdisplay

安装firefoxselenium

yum install firefox
pip install selenium

代码

from pyvirtualdisplay import Display
from selenium import webdriver

display = Display(visible=0, size=(800, 600))
display.start()

browser = webdriver.Firefox()
browser.get('http://www.baidu.com')
print browser.title
browser.quit()

display.stop()

Talk is cheap, Show me the fucking code


from splinter import Browser
from selenium.webdriver import PhantomJS, DesiredCapabilities
from splinter.driver.webdriver import (BaseWebDriver, WebDriverElement as BaseWebDriverElement)

from pyvirtualdisplay import Display
from selenium import webdriver

import re
import json


def fetch_info(url):
    html = download_html(url)
    videoUrl = parse_html(url, html)

    resultDic = {'ret' : 0, 'srcUrl' : url, 'title' : url, 'abstract' : url, 'qsvideo' : videoUrl}
    print(json.dumps(resultDic))

    pass

def download_html(url):
    display = Display(visible=0, size=(800, 600))
    display.start()

    browser = Browser(user_agent="Mozilla/5.0 (iPhone; CPU iPhone OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B410 Safari/600.1.4")
    browser.visit(url)
    html = browser.html

    browser.quit()
    display.stop()
    return html
    pass

def parse_html(url, html):
    matchObj = re.search(r'<div class="tvp_video"><video(.*)src="(.*)"></video>', html)
    if matchObj:
        videoUrl = matchObj.group(2)
        return videoUrl

    return ""
    pass

if __name__ == '__main__':
    url = "http://v.youku.com/v_show/id_XMTMyOTU4NTc4OA==.html"
    fetch_info(url)

4. 第二种情况

对于第二种情况,You-Get不能支持的视频网站,需要设置User-Agent伪装为iPhone用户进行提取,或者破解其加密方式。

5. 小结

总的来说,这是一种可行的抓取方案。但是,因为需要浏览器启动加载网页,对于条件比较苛刻的环境中效率相对较低。就笔者而言,在1M的带宽中抓取一个视频链接需要几十秒的时间,这几乎是不能忍受的。因此如何在低带宽中提高速度仍需要挖掘。目前猜测耗时可能是因为加载网页时下载图片导致,具体原因还需要详细调查验证。

参考资料:
you-get github
pip
Splinter
linux无界面(headless)使用selenium抓取数据

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,093评论 4 62
  • 用到的组件 1、通过CocoaPods安装 2、第三方类库安装 3、第三方服务 友盟社会化分享组件 友盟用户反馈 ...
    SunnyLeong阅读 14,613评论 1 180
  • 好久没出差了,3月17日突然接到通知,告知20日要到上电技培中心参加培训师学习,当时心里一紧、感觉好突然,连忙探...
    上海电力王青元阅读 261评论 0 0
  • 项目简介: 我们做什么? 我们做以小区为定位的小区拼团平台,辐射周边1公理 我们什么做? 分2步走: 1:做”京东...
    c99a0e805927阅读 2,452评论 0 0
  • 与书共寝,安详自在。下班回家,累了坐在床上,随意拿本书来读,读累了放下书,安寝!第二天到自然醒,继续昨天的书看!偶...
    霸王东渡阅读 246评论 0 4