开发每日站点数据抓取函数:匹配时间后获取数据技术问询
节目数据抓取函数优化与时间匹配实现
看起来你正在搭建一个每日获取目标站点节目数据的函数,核心需求是先匹配到和指定日期对应的节点,再抓取对应内容对吧?我先帮你梳理下现有代码里的问题,再补充完整的时间匹配逻辑:
现有代码的几个小问题
- 全局变量冲突:函数参数已经定义了
$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; }
关键细节说明
- DOM解析替代正则:用
DOMDocument和XPath解析HTML比正则表达式更稳定,哪怕目标站点的HTML结构有小变动,调整XPath路径即可,不会像正则那样容易失效。 - 请求容错处理:增加了HTTP状态码判断,请求失败时返回空数组并记录错误日志,方便排查问题。
- 跳过已结束节目:通过将节目结束时间转换成时间戳,和当前时间对比,实现跳过逻辑,这里假设
$day和节目时间的格式是统一的,你可以根据实际情况调整时间格式转换逻辑。 - User-Agent设置:使用主流浏览器的UA标识,降低被目标站点拦截的概率。
内容的提问来源于stack exchange,提问作者Robert Jones
相关产品推荐
相关产品推荐

