之前看到有博友给我留言说想看 “PHP 的 Curl 利用账号密码获取一个网站登录后的内容”,最近也不知道发啥文章了,那正好上代码吧!
今天我们拿 “堆糖,美图壁纸兴趣社区” 这个网站做案例吧。 网址:https://www.duitang.com/
先说一下这个不分语言,能发送请求就能实现,别问我为什么不用 java,PHP 简单(PHP 是最好的语言滑稽)

我们打开网站可以看到登录 or 注册的地方,直接点击

点击以后直接打开开发者控制台,preserve log 这个一定得勾选上,是持续记录日志的,网站登录成功以后会跳转那样我们就看不到请求数据了,所以要勾选上。
我这边是已经注册好了,那我就直接输入账号密码了。

我们点击登录按钮的时候可以看到有一条 url 是为:https://www.duitang.com/login/ 的请求, 那个就是登录请求,这个登录没有任何验证,这会让我们方便许多,我们再来看请求的参数,login_name 这个是登录的账号;pswd 这个我们看名字就知道是密码了,来 curl 模拟这个请求:
/**
* @param $url
* @param $data
* @return string
* 模拟登录
*/
function loginPost($url,$data){
$ch = curl_init();
$header=[
'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
];
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_HEADER,1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
$datas = curl_exec($ch);
curl_close($ch);
return $datas;
}这个是我封装好的函数,我们来发送一下登录请求:
<?php
header('Access-Control-Allow-Origin:*');
header('Content-type:application/json; charset=utf-8');
error_reporting(0);
$post_data=[
"login_name"=>"账号",
"pswd"=>"密码",
"ccode"=>"",
"token"=>"",
"remember"=>true,
"next"=>"/"
];
echo loginPost("https://www.duitang.com/login/",$post_data);
/**
* @param $url
* @param $data
* @return string
* 模拟登录
*/
function loginPost($url,$data){
$ch = curl_init();
$header=[
'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
];
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_HEADER,1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
$datas = curl_exec($ch);
curl_close($ch);
return $datas;
}我们来看输出结果:

我们看请求头信息就能看出来已经登录成功,第一个 Set-Cookie 就是我们要的东西,接下来我们可以验证一下这个 cookie 是否有效:
/**
* @param $url
* @param $cookie
* @return bool|string
* 携带cookie访问目标网址
*/
function get($url,$cookie){
$ch = curl_init();
$header = [
"Cookie: $cookie"
];
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36");
curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
$content = curl_exec($ch);
curl_close($ch);
return $content;
}
我们可以看到页面上已经显示我们登录进去的账号名字,说明 cookie 是有效的,但是里面的 cookie 有些是没有用的,而且我们每次都要模拟登录才能操作吗?我们接着来写:
用到的函数:
/**
* @param $str
* @param $leftStr
* @param $rightStr
* @return bool|string
* 截取字符串
*/
function getSubstr($str,$leftStr,$rightStr){
$left = strpos($str, $leftStr);
$right = strpos($str, $rightStr,$left);
if($left <= 0 or $right < $left) return '';
return substr($str, $left + strlen($leftStr), $right-$left-strlen($leftStr));
}
/**
* @param $cookie
* 设置cookie
*/
function CookieSet($cookie){
$newConfig = '<?php
$config = array(
"cookie" => "'.$cookie.'"
);';
@file_put_contents('config.php', $newConfig);
}这是我们用到的已经封装好的函数,我们可以直接在模拟登录那个地方返回精简有效的 Cookie,因为我们模拟登录就是为了拿到 cookie,所以我们直接在那里写就行了:
/**
* @param $url
* @param $data
* @return string
* 模拟登录
*/
function loginPost($url,$data){
$ch = curl_init();
$header=[
'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
];
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_HEADER,1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
$datas = curl_exec($ch);
curl_close($ch);
return "dt_auth=".getSubstr($datas,"dt_auth=",";").";";
}这个是我们修改以后的模拟登录,直接返回的是 cookie:

OK 没得问题,我们继续,cookie 也不是很快就会失效的,所以我们可以把它存储一下就不用每次请求都要模拟登录一次了,我们创建一个存 cookie 的文件:如果文件不存在则自动创建
if (!is_file('config.php')) {
CookieSet('dt_auth;');
}我们可以写一个判断,如果没有登录的 cookie,就模拟登录一下并且存储我们刚刚创建的 config.PHP 文件里面:
if (strpos(get("https://www.duitang.com/",$config['cookie']),"注册/登录")!==false){
CookieSet(loginPost("https://www.duitang.com/login/",$post_data));
}这个时候我们 cookie 就会自动更新存储了,接下来就可以拿我们得到的 cookie 进行带身份操作,比如修改昵称,具体你要做什么操作看你自己了(可以做图床哦,在上传背景那个地方抓接口)