如何从嵌入的外部页面DOM获取数据并存入PHP变量?
解决方案:绕过Embed限制,用PHP模拟请求获取结果
首先明确:用<embed>标签无法实现你的需求——浏览器的同源策略会完全阻止前端JS访问跨域页面的DOM,所以必须换思路,直接用PHP模拟用户的提交流程来和目标服务器交互。
核心思路
放弃Embed展示外部页面,改为:
- 用PHP请求目标站点的初始页面,提取必要的会话信息(Cookie、隐藏字段、验证码)
- 在本地页面展示表单,让用户输入密钥和验证码
- 用PHP将用户输入+会话信息一起提交给目标服务器
- 直接获取目标服务器返回的结果HTML,存入PHP变量
分步实现代码示例
1. 获取初始页面的会话信息(比如验证码、隐藏字段)
// 初始化CURL,维持会话Cookie $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://dfe-portal.svrs.rs.gov.br/Dfe/ConsultaPublicaDfe'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_COOKIEJAR, 'dfe_cookie.txt'); // 保存Cookie到文件 curl_setopt($ch, CURLOPT_COOKIEFILE, 'dfe_cookie.txt'); // 读取Cookie curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/118.0.0.0'); // 模拟浏览器 $initialHtml = curl_exec($ch); curl_close($ch); // 解析页面提取隐藏字段和验证码URL $dom = new DOMDocument(); @$dom->loadHTML($initialHtml); // @忽略HTML解析错误 $xpath = new DOMXPath($dom); // 收集所有隐藏表单字段(比如CSRF Token) $hiddenFields = []; foreach ($xpath->query('//input[@type="hidden"]') as $input) { $hiddenFields[$input->getAttribute('name')] = $input->getAttribute('value'); } // 提取验证码图片URL(根据实际页面结构调整XPath) $captchaImg = $xpath->query('//img[contains(@src, "captcha")]')->item(0); $captchaFullUrl = 'https://dfe-portal.svrs.rs.gov.br' . $captchaImg->getAttribute('src'); // 把验证码URL存到Session,供后续页面使用 session_start(); $_SESSION['captcha_url'] = $captchaFullUrl;
2. 本地展示用户输入表单
<form method="post" action="submit_query.php"> <div> <label>Chave de Acesso:</label> <input type="text" name="chave_acesso" required> </div> <div> <label>验证码:</label> <img src="get_captcha.php" alt="验证码"> <input type="text" name="captcha_code" required> </div> <!-- 传递隐藏字段 --> <?php foreach ($hiddenFields as $name => $val): ?> <input type="hidden" name="<?php echo htmlspecialchars($name); ?>" value="<?php echo htmlspecialchars($val); ?>"> <?php endforeach; ?> <button type="submit">Consultar</button> </form>
3. 输出验证码图片的辅助文件(get_captcha.php)
<?php session_start(); $captchaUrl = $_SESSION['captcha_url']; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $captchaUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_COOKIEFILE, 'dfe_cookie.txt'); // 复用之前的会话Cookie $captchaData = curl_exec($ch); curl_close($ch); // 输出图片 header('Content-Type: image/png'); // 根据实际验证码格式调整 echo $captchaData; ?>
4. 处理用户提交,获取结果DOM(submit_query.php)
<?php session_start(); // 获取用户输入和隐藏字段 $chaveAcesso = $_POST['chave_acesso']; $captchaCode = $_POST['captcha_code']; $hiddenFields = $_POST; unset($hiddenFields['chave_acesso'], $hiddenFields['captcha_code']); // 构造POST请求数据(注意字段名要和目标站点表单完全一致,需实际查看目标页面HTML) $postData = array_merge($hiddenFields, [ 'chaveAcessoDfe' => $chaveAcesso, // 目标站点的密钥输入name 'captcha' => $captchaCode // 目标站点的验证码输入name ]); // 发起POST请求 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://dfe-portal.svrs.rs.gov.br/Dfe/ConsultaPublicaDfe'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_COOKIEFILE, 'dfe_cookie.txt'); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 跟随跳转 curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/118.0.0.0'); // 这里的$responseHtml就是用户点击Consultar后的DOM内容,直接存入变量 $responseHtml = curl_exec($ch); curl_close($ch); // 示例:解析结果DOM提取需要的数据 $dom = new DOMDocument(); @$dom->loadHTML($responseHtml); $xpath = new DOMXPath($dom); $resultNode = $xpath->query('//div[@class="resultado-consulta"]')->item(0); if ($resultNode) { $resultText = $resultNode->nodeValue; // 后续处理逻辑... } ?>
关键注意事项
- 必须准确对应目标站点的表单字段名:打开目标页面的开发者工具,查看密钥输入、验证码输入的
name属性,以及所有隐藏字段的名称,确保POST数据的键名完全匹配。 - Cookie必须持续复用:目标站点的验证码和会话绑定,所以全程要使用同一个Cookie文件。
- 可能需要添加额外请求头:如果目标站点有反爬机制,可在CURL中添加
CURLOPT_REFERER、CURLOPT_ACCEPT等请求头模拟真实浏览器请求。
内容的提问来源于stack exchange,提问作者DRauber
相关产品推荐
相关产品推荐

