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

实习项目中如何解析Coursera动态加载的法语筛选课程页面?

解决动态内容解析问题:获取Coursera筛选后的法语课程

你的问题核心在于**file_get_html和simple_html_dom只能处理静态HTML内容**,而Coursera的筛选逻辑与课程列表加载是通过前端JavaScript完成的——当你用file_get_html请求URL时,它只会拿到服务器返回的初始页面源码,完全不会执行任何JS代码,所以哪怕你加sleep(10)也没用,因为没有浏览器环境来渲染动态加载的内容。

下面给你两种可行的解决方案,按推荐程度排序:


方案1:直接调用Coursera的API(高效推荐)

Coursera的课程数据是通过AJAX接口加载的,你可以跳过页面渲染环节,直接请求数据接口,这种方式既高效又稳定。步骤如下:

  1. 定位API接口:
    打开浏览器开发者工具(F12),切换到「Network」标签,筛选「XHR/fetch」类型的请求。然后在Coursera页面上选择法语筛选条件,观察新出现的请求——你会看到一个类似https://www.coursera.org/api/search/index的接口,它的响应是JSON格式的结构化课程数据。

  2. 用PHP请求API并解析:
    复制这个API的完整请求URL,同时带上必要的请求头(比如User-Agent、Accept等,避免被服务器拦截),然后用PHP的curl或者file_get_contents发起请求,最后解析返回的JSON即可。

示例代码:

<?php
// 替换为你找到的真实API URL
$apiUrl = 'https://www.coursera.org/api/search/index?params=...';

// 设置请求头,模拟真实浏览器请求
$opts = [
    'http' => [
        'method' => 'GET',
        'header' => 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' . "\r\n" .
                    'Accept: application/json' . "\r\n"
    ]
];
$context = stream_context_create($opts);

// 发起API请求
$response = file_get_contents($apiUrl, false, $context);
if ($response === false) {
    die('API请求失败,请检查URL和请求头');
}

// 解析JSON数据
$courses = json_decode($response, true);

// 遍历并输出课程信息(具体字段需根据API响应结构调整)
foreach ($courses['results'] as $course) {
    echo "<div class='card-info'>";
    echo "<h3>" . htmlspecialchars($course['name']) . "</h3>";
    echo "<p>机构:" . htmlspecialchars($course['partnerName']) . "</p>";
    echo "</div><br>";
}
?>

方案2:使用无头浏览器模拟页面渲染

如果API接口结构复杂或容易变化,可以用支持JavaScript渲染的无头浏览器工具,比如Symfony Panther(基于ChromeDriver),它能模拟真实浏览器加载页面、执行JS,等待动态内容加载完成后再获取完整HTML。

  1. 安装Symfony Panther:
    通过Composer安装依赖:

    composer require symfony/panther
    
  2. 编写渲染与解析代码:
    下面的代码会模拟浏览器打开目标页面,等待筛选后的课程卡片加载完成,再提取HTML内容进行解析:

<?php
require __DIR__.'/vendor/autoload.php';

use Symfony\Component\Panther\PantherTestCase;

// 启动无头浏览器
$client = PantherTestCase::createPantherClient();

// 访问目标页面
$targetUrl = 'https://www.coursera.org/courses?query=indices%5Bprod_all_products_custom_ranking_revenuelast28d%5D%5BrefinementList%5D%5Blanguage%5D%5B0%5D=French&indices%5Bprod_all_products_custom_ranking_revenuelast28d%5D%5Bpage%5D=1&indices%5Bprod_all_products_custom_ranking_revenuelast28d%5D%5Bconfigure%5D%5BclickAnalytics%5D=true&indices%5Bprod_all_products_custom_ranking_revenuelast28d%5D%5Bconfigure%5D%5BhitsPerPage%5D=10&configure%5BclickAnalytics%5D=true&page=1';
$client->request('GET', $targetUrl);

// 等待课程卡片元素加载完成(确保动态内容渲染完毕)
$client->waitFor('.card-info');

// 获取渲染后的完整HTML
$html = $client->getCrawler()->html();

// 用simple_html_dom解析HTML(也可直接用Panther的Crawler处理)
require_once('simple_html_dom.php');
$dom = str_get_html($html);
foreach($dom->find('div.card-info') as $e) {
    echo $e->outertext . '<br>';
}

// 关闭浏览器实例
$client->quit();
?>

补充:为什么sleep(10)无效?

再明确一下:file_get_html是直接从服务器拉取静态HTML文件,整个过程没有浏览器参与,不会执行页面中的任何JavaScript代码。页面上的筛选逻辑、动态内容加载都是JS在浏览器环境中完成的,所以sleep只是让PHP脚本暂停执行,对已经拿到的静态HTML没有任何影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:32:25