首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >PHP 模拟登录后实现爬虫获取数据

PHP 模拟登录后实现爬虫获取数据

作者头像
程序猿的栖息地
发布于 2022-04-29 15:29:26
发布于 2022-04-29 15:29:26
3K0
举报

之前看到有博友给我留言说想看 “PHP 的 Curl 利用账号密码获取一个网站登录后的内容”,最近也不知道发啥文章了,那正好上代码吧!

目标网站:

今天我们拿 “堆糖,美图壁纸兴趣社区” 这个网站做案例吧。 网址:https://www.duitang.com/

实现过程:

先说一下这个不分语言,能发送请求就能实现,别问我为什么不用 java,PHP 简单(PHP 是最好的语言滑稽)

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

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

我这边是已经注册好了,那我就直接输入账号密码了。

我们点击登录按钮的时候可以看到有一条 url 是为:https://www.duitang.com/login/ 的请求, 那个就是登录请求,这个登录没有任何验证,这会让我们方便许多,我们再来看请求的参数,login_name 这个是登录的账号;pswd 这个我们看名字就知道是密码了,来 curl 模拟这个请求:

代码语言:javascript
复制
/**
 * @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;
}

这个是我封装好的函数,我们来发送一下登录请求:

代码语言:javascript
复制
<?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 是否有效:

代码语言:javascript
复制
/**
 * @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 有些是没有用的,而且我们每次都要模拟登录才能操作吗?我们接着来写:

用到的函数:

代码语言:javascript
复制
/**
 * @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,所以我们直接在那里写就行了:

代码语言:javascript
复制
/**
 * @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 的文件:如果文件不存在则自动创建

代码语言:javascript
复制
if (!is_file('config.php')) {
    CookieSet('dt_auth;');
}

我们可以写一个判断,如果没有登录的 cookie,就模拟登录一下并且存储我们刚刚创建的 config.PHP 文件里面:

代码语言:javascript
复制
if (strpos(get("https://www.duitang.com/",$config['cookie']),"注册/登录")!==false){
    CookieSet(loginPost("https://www.duitang.com/login/",$post_data));
}

这个时候我们 cookie 就会自动更新存储了,接下来就可以拿我们得到的 cookie 进行带身份操作,比如修改昵称,具体你要做什么操作看你自己了(可以做图床哦,在上传背景那个地方抓接口)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-03,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 目标网站:
  • 实现过程:
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档