如何使用PHP与Curl实现需确认退出的网站登出?
解决Curl处理两步式网站登出的问题
我来帮你搞定这个需要确认的登出流程!这类网站的登出分两步:第一步触发登出请求后返回确认页面,第二步需要提交确认操作才能完成登出。下面是具体的实现步骤和代码示例:
第一步:获取登出确认页面并提取必要参数
首先你需要用Curl请求登出触发后的确认页面,同时要保持会话Cookie,还要从页面里提取表单的关键信息(比如表单提交地址、隐藏的CSRF令牌或者确认参数)。
修正你的请求头(格式问题)
你原来的User-Agent格式有错误(缺少空格),Connection也没写完,修正后的PHP请求头应该是这样:
$headers = array( "GET $geturl HTTP/1.1", "Host: $ip", "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Referer: $referer", "Cookie: JSESSIONID=$session_id", "Connection: keep-alive" );
获取页面并解析表单参数
用Curl获取页面后,我们需要解析HTML找到确认表单的action地址和隐藏字段。这里推荐用DOMDocument来解析(比正则更可靠):
// 初始化Curl $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $geturl); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 保存Cookie到文件,后续请求复用 curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt'); curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt'); // 执行请求,获取确认页面内容 $confirmPage = curl_exec($ch); curl_close($ch); // 解析页面找表单信息 $dom = new DOMDocument(); @$dom->loadHTML($confirmPage); // @忽略HTML解析警告 $xpath = new DOMXPath($dom); // 找到确认表单(假设表单包含登出相关的action路径) $form = $xpath->query('//form[contains(@action, "logout")]')->item(0); if (!$form) { die("找不到登出确认表单"); } // 获取表单提交地址,相对路径要补全为完整URL $formAction = $form->getAttribute('action'); if (strpos($formAction, 'http') === false) { $formAction = "http://$ip" . $formAction; } // 提取表单里的隐藏字段(比如csrf_token等) $postData = array(); $inputs = $xpath->query('//form//input[@type="hidden"]'); foreach ($inputs as $input) { $postData[$input->getAttribute('name')] = $input->getAttribute('value'); } // 加上确认按钮的参数(要和页面里按钮的name/value完全一致) $postData['confirm'] = '确定'; // 示例值,需根据页面源码调整
第二步:提交确认登出请求
拿到表单参数后,就可以构造POST请求提交确认操作了:
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $formAction); // 设置为POST请求 curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData)); // 复用之前的Cookie维持会话 curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt'); curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt'); // 设置请求头,Referer设为之前的确认页面URL $postHeaders = array( "Host: $ip", "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Referer: $geturl", "Content-Type: application/x-www-form-urlencoded", "Connection: keep-alive" ); curl_setopt($ch, CURLOPT_HTTPHEADER, $postHeaders); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 执行确认请求 $result = curl_exec($ch); // 检查是否登出成功(根据返回页面的特征文字判断) if (strpos($result, "已登出") !== false) { echo "登出成功!"; } else { echo "登出失败,返回内容:$result"; } curl_close($ch);
关键注意事项
- Cookie保持:一定要用
CURLOPT_COOKIEJAR和CURLOPT_COOKIEFILE维持会话,否则JSESSIONID会失效导致请求失败。 - 表单参数准确性:要确保提取的隐藏字段和按钮参数和页面源码完全一致,比如按钮的
name可能是submit而非confirm,需要查看页面确认。 - 请求头模拟:尽量模拟真实浏览器的请求头,避免被网站识别为爬虫拦截。
内容的提问来源于stack exchange,提问作者Shubham Vyas
相关产品推荐
相关产品推荐

