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

开发每日站点数据抓取函数:匹配时间后获取数据技术问询

节目数据抓取函数优化与时间匹配实现

看起来你正在搭建一个每日获取目标站点节目数据的函数,核心需求是先匹配到和指定日期对应的节点,再抓取对应内容对吧?我先帮你梳理下现有代码里的问题,再补充完整的时间匹配逻辑:

现有代码的几个小问题

  • 全局变量冲突:函数参数已经定义了$day,但你又用了global $day,这会直接覆盖传入的参数值,这是个典型的bug,得删掉这行。
  • CURL配置不完整:你设置了UA为空、超时,但没加CURLOPT_RETURNTRANSFER(让CURL返回内容而不是直接输出),也没处理请求失败的情况,而且空UA很容易被目标站点的反爬机制拦截。
  • 缺少时间匹配逻辑:代码只到CURL设置就截断了,还没实现HTML中时间节点的匹配和数据抓取部分。

修正+完整实现代码

下面是补全后的代码,我加入了时间节点匹配(用DOM解析更可靠)、请求错误处理、跳过已结束节目的逻辑:

function get_shows($channel_id, $day, $skip_finished = true) {
    // 移除global $day,避免覆盖传入的参数
    $url = 'http://example.com/api/GS?cid=' . $channel_id . '&offset=+00.00&day=' . $day;
    
    $curl = curl_init();
    curl_setopt_array($curl, array(
        // 设置合理的User-Agent,避免被拦截
        CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36',
        CURLOPT_TIMEOUT => 30,
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true, // 关键:让CURL返回响应内容
        CURLOPT_FOLLOWLOCATION => true, // 跟随3xx重定向
        CURLOPT_SSL_VERIFYPEER => false, // 如果目标站点是HTTPS且证书有问题,可临时关闭(生产环境建议开启)
        CURLOPT_SSL_VERIFYHOST => false
    ));
    
    // 执行请求并获取响应
    $response = curl_exec($curl);
    $http_status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    curl_close($curl);
    
    // 先判断请求是否成功
    if ($http_status !== 200 || empty($response)) {
        error_log("请求节目数据失败,状态码:$http_status");
        return [];
    }
    
    // 用DOM解析HTML,匹配时间节点(需根据目标站点实际HTML结构调整)
    $dom = new DOMDocument();
    @$dom->loadHTML($response); // @符号屏蔽HTML解析时的警告(比如不规范的标签)
    $xpath = new DOMXPath($dom);
    
    // 假设时间节点是带有show-date类的span标签,你需要替换成目标站点的实际节点路径
    $time_nodes = $xpath->query('//span[contains(@class, "show-date")]');
    $matched_data = [];
    
    foreach ($time_nodes as $node) {
        $show_date = trim($node->nodeValue);
        // 匹配传入的日期(假设$day格式为YYYY-MM-DD)
        if ($show_date !== $day) {
            continue;
        }
        
        // 抓取该时间节点对应的节目数据,这里的XPath路径要根据实际HTML结构调整
        $show_container = $node->parentNode; // 假设节目信息在时间节点的父容器里
        $title = $xpath->query('./h4[@class="show-title"]', $show_container)->item(0)?->nodeValue ?? '无标题';
        $start_time = $xpath->query('./span[@class="show-start"]', $show_container)->item(0)?->nodeValue ?? '';
        $end_time = $xpath->query('./span[@class="show-end"]', $show_container)->item(0)?->nodeValue ?? '';
        
        // 跳过已结束的节目(如果开启该选项)
        if ($skip_finished && !empty($end_time)) {
            $current_timestamp = strtotime(date('Y-m-d H:i:s'));
            $show_end_timestamp = strtotime("$day $end_time");
            if ($show_end_timestamp < $current_timestamp) {
                continue;
            }
        }
        
        $matched_data[] = [
            'title' => $title,
            'start_time' => $start_time,
            'end_time' => $end_time,
            'date' => $show_date
        ];
    }
    
    return $matched_data;
}

关键细节说明

  1. DOM解析替代正则:用DOMDocument和XPath解析HTML比正则表达式更稳定,哪怕目标站点的HTML结构有小变动,调整XPath路径即可,不会像正则那样容易失效。
  2. 请求容错处理:增加了HTTP状态码判断,请求失败时返回空数组并记录错误日志,方便排查问题。
  3. 跳过已结束节目:通过将节目结束时间转换成时间戳,和当前时间对比,实现跳过逻辑,这里假设$day和节目时间的格式是统一的,你可以根据实际情况调整时间格式转换逻辑。
  4. User-Agent设置:使用主流浏览器的UA标识,降低被目标站点拦截的概率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:12:19