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

PHP爬取URL中href属性问题:一级深度爬取无结果求助

嘿,我来帮你排查下为什么你的findAndCompare函数没返回任何结果。从你描述的需求和给出的代码片段来看,大概率是踩了几个PHP网页爬取的常见坑,咱们一步步拆解问题:

可能的问题排查点及修复建议

1. 输入URL的协议补全与格式验证

首先,用户输入的URL很可能没带http://或https://(比如只输入example.com),这时候你的爬取逻辑会把它当成相对路径,直接导致请求失败。

建议在获取website1的输入值后,先做协议补全和格式校验:

$inputUrl = $_POST['website1'] ?? '';
// 补全缺失的HTTP/HTTPS协议
if (!preg_match("~^(?:f|ht)tps?://~i", $inputUrl)) {
    $inputUrl = "https://" . $inputUrl;
}
// 验证URL格式是否合法
if (!filter_var($inputUrl, FILTER_VALIDATE_URL)) {
    die("请输入有效的网站URL(比如:https://example.com)");
}

2. findAndCompare函数的HTML解析逻辑缺陷

如果你用正则表达式匹配<a>标签的href,很容易因为HTML结构的不规范(比如标签内有空格、单引号包裹href、特殊字符)导致匹配失效。强烈建议用DOMDocument替代正则,这是处理HTML最可靠的方式。

示例解析逻辑(可以整合到你的函数里):

function extractHrefs($targetUrl) {
    $hrefList = [];
    $dom = new DOMDocument();
    // 屏蔽HTML解析时的警告(很多网站的HTML并不完全符合标准)
    libxml_use_internal_errors(true);
    
    // 用更稳定的cURL获取页面内容(替代file_get_contents)
    $htmlContent = getPageContent($targetUrl);
    if (!$htmlContent) return $hrefList;

    $dom->loadHTML($htmlContent);
    libxml_clear_errors();

    // 遍历所有<a>标签提取href
    $links = $dom->getElementsByTagName('a');
    foreach ($links as $link) {
        $rawHref = $link->getAttribute('href');
        if (empty($rawHref)) continue;

        // 把相对路径转换为绝对路径
        $absoluteHref = convertToAbsoluteUrl($targetUrl, $rawHref);
        $hrefList[] = $absoluteHref;
    }

    // 去重避免重复链接
    return array_unique($hrefList);
}

// 辅助函数:转换相对路径为绝对路径
function convertToAbsoluteUrl($baseUrl, $relativeUrl) {
    $parsedBase = parse_url($baseUrl);
    if (strpos($relativeUrl, 'http') === 0) {
        return $relativeUrl; // 已经是绝对路径
    } elseif (strpos($relativeUrl, '/') === 0) {
        return $parsedBase['scheme'] . '://' . $parsedBase['host'] . $relativeUrl;
    } else {
        $basePath = dirname($parsedBase['path'] ?? '/');
        return $parsedBase['scheme'] . '://' . $parsedBase['host'] . $basePath . '/' . $relativeUrl;
    }
}

// 辅助函数:用cURL获取页面内容(避免被反爬)
function getPageContent($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 跟随重定向
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/114.0.0.0 Safari/537.36'); // 模拟浏览器UA
    curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 设置超时时间
    $content = curl_exec($ch);
    curl_close($ch);
    return $content;
}

3. 一级深度爬取的流程漏洞

一级深度爬取需要先爬取首页的所有链接,再逐个爬取这些链接对应的页面并提取href。如果你的findAndCompare函数没实现这个递进逻辑,或者在爬取子页面时遇到请求失败(比如反爬、404),也会返回空结果。

建议的完整流程:

  • 第一步:提取首页的所有绝对路径href
  • 第二步:遍历首页的href列表,逐个调用extractHrefs函数提取子页面的href
  • 第三步:汇总首页和子页面的href结果(可以分开存储区分层级)

4. 表单提交的潜在问题

你代码里用<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>作为表单action,虽然做了转义,但如果脚本文件名包含特殊字符,可能导致提交异常。可以替换成更稳定的写法:

<form action="<?php echo htmlspecialchars($_SERVER['SCRIPT_NAME']);?>" method="post">

或者直接写action="",浏览器会自动提交到当前页面。

最后建议你先做单步测试:比如固定一个已知可用的URL(比如https://example.com),调用extractHrefs函数看是否能返回正常结果,确认解析逻辑没问题后,再整合表单提交和一级爬取的完整流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:03:26