You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用PHP Selenium WebDriver抓取并保存流媒体MP4文件

解决方案

注意你原有代码中的XPath写法不规范,需要调整为可匹配到video元素的正确XPath表达式,否则会无法获取到src属性

失败原因排查

直接使用fopen/file_get_contents无法获取视频流,通常是以下几个原因:

  • 视频服务端做了请求校验,需要携带浏览器当前会话的Cookie、Referer、User-Agent等请求头,裸请求会被服务器拦截
  • 获取到的src是blob:开头的浏览器本地对象地址,对应资源存在于浏览器内存中,服务端PHP无法直接访问
  • 视频是分片加载的HLS流(地址为.m3u8后缀),单个src不是完整MP4文件地址

对应实现方案

场景1:src为http/https开头的真实远程MP4地址

复用Selenium当前浏览器的会话信息发起请求即可,推荐用CURL实现,示例代码如下:

// 接你原有代码
$vid = $driver->findElement(WebDriverBy::xpath('//video[@id="videojs_html5"]'))->getAttribute("src");

// 1. 获取浏览器当前会话的Cookie、User-Agent、当前页面地址(用作Referer)
$cookies = $driver->manage()->getCookies();
$cookieStr = '';
foreach ($cookies as $cookie) {
    $cookieStr .= $cookie->getName() . '=' . $cookie->getValue() . '; ';
}
$userAgent = $driver->executeScript("return navigator.userAgent;");
$referer = $driver->getCurrentURL();

// 2. 用CURL携带头信息请求视频流,分片写入避免大视频占满内存
$savePath = __DIR__ . '/save_video.mp4';
$ch = curl_init($vid);
$fp = fopen($savePath, 'w+');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "User-Agent: $userAgent",
    "Referer: $referer",
    "Cookie: $cookieStr"
]);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_exec($ch);

// 错误检查
if(curl_errno($ch)) {
    unlink($savePath);
    throw new Exception('视频下载失败:' . curl_error($ch));
}

curl_close($ch);
fclose($fp);

场景2:src为blob:开头的本地对象地址

此时需要在浏览器端执行JS触发下载,提前配置Chrome的默认下载路径即可,示例代码如下:

use Facebook\Webdriver;
use Facebook\WebDriver\WebDriverBy;
use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;

require_once __DIR__ . '/vendor/autoload.php';

$host = 'http://localhost:4444/wd/hub';

// 配置Chrome下载路径,避免下载到默认位置找不到
$chromeOptions = new ChromeOptions();
$downloadPath = __DIR__; // 自定义本地保存路径,确保有写入权限
$chromeOptions->setExperimentalOption('prefs', [
    'download.default_directory' => $downloadPath,
    'download.prompt_for_download' => false,
    'download.directory_upgrade' => true,
    'safebrowsing.enabled' => false
]);
$capabilities = DesiredCapabilities::chrome();
$capabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions);
$driver = RemoteWebDriver::create($host, $capabilities);

$driver->get("http://example.com");
$vid = $driver->findElement(WebDriverBy::xpath('//video[@id="videojs_html5"]'))->getAttribute("src");

// 执行JS触发浏览器下载
$driver->executeScript("
    const a = document.createElement('a');
    a.href = arguments[0];
    a.download = 'save_video.mp4';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
", [$vid]);

// 等待下载完成,可优化为检测目标文件大小不再变化的逻辑
sleep(15);
$driver->quit();

场景3:src为.m3u8后缀的HLS分片流

需要借助ffmpeg工具完成分片下载和合并,确保本地已经安装ffmpeg后,执行如下代码即可:

// 提前获取到带会话参数的m3u8地址$vid
$savePath = __DIR__ . '/save_video.mp4';
$cmd = "ffmpeg -i \"$vid\" -c copy -bsf:a aac_adtstoasc \"$savePath\"";
exec($cmd, $output, $returnVar);
if($returnVar !== 0) {
    throw new Exception('视频合并失败:' . implode("\n", $output));
}

内容的提问来源于stack exchange,提问作者wnets webmaster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 19:45:06