【CURL】模拟登录网站并获取用户信息

标签: phpcurl表单前端
6724人阅读 评论(2) 收藏 举报
分类:

模拟登录网站并获取用户信息

前言

这次来做的是通过代码的方式,模拟登录秒拍官网,获取登录用户的信息。

前后端分离

本文的标题是CURL,传统的网站是PHP代码直接渲染项目视图,通过表单提交到控制器直接进行数据操作。

传统模拟登录的方式在页面上找到表单元素,直接进行模拟表单提交。

近两年前端技术趋于完善,实现了前后端分离。

前后端分离

分析页面元素

秒拍官网地址 http://www.miaopai.com/

通过审查元素以及源代码查找,在本页面并没有form标签,由此推断页面是通过js进行提交的。

查找提交地址

由于提交的js代码可能写在了外部的js文件中,直接查找很不方便,所以通过Chrome的调试模式寻找发送的http请求。

注意勾选下图的Preserve log,避免页面跳转的请求记录丢失。

Preserve log

填入手机号密码,在Chrome的Network中查找登录接口请求。

显然,得到登录请求接口 http://www.miaopai.com/cu/login

POSTMAN模拟登录

接口具体信息如下

这里写图片描述

首先使用postman进行模拟登录测试。

postman

模拟登录毫无压力。

pwd字段经过测试只是简单的md5加密,没有问题。

PHP模拟登录

注意的是,postman自带方法可以直接输出各种语言的代码。

输出PHP代码

经过整理的PHP代码如下


//手机号
$phone = 13000000000;
//密码
$pwd = md5("password");

$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => "http://www.miaopai.com/cu/login?phone={$phone}&pwd={$pwd}&checked=false&ph=0",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HEADER=>true,
    CURLOPT_HTTPHEADER => array(
        "cache-control: no-cache",
//        "postman-token: c13c9f1a-fce6-7ec8-4c91-3f13bd233284"
    ),
));

$response = curl_exec($curl);
$err = curl_error($curl);


if ($err) {
    echo "cURL Error #:" . $err;
    die();
}


//打印header
if (curl_getinfo($curl, CURLINFO_HTTP_CODE) == '200') {
    $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    $header = substr($response, 0, $headerSize);
    $body = substr($response, $headerSize);

}

curl_close($curl);

$body_arr = (json_decode($body,true));

var_dump($body_arr);

获取用户更多数据

我们发现登录接口的返回值中,还存在url字段,拼接美拍网址之后是当前登录用户的个人页面,可以通过正则匹配的方式,得到当前登录的其他信息。

完整代码如下


//手机号
$phone = 13000000000;
//密码
$pwd = md5("password");

$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => "http://www.miaopai.com/cu/login?phone={$phone}&pwd={$pwd}&checked=false&ph=0",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HEADER=>true,
    CURLOPT_HTTPHEADER => array(
        "cache-control: no-cache",
//        "postman-token: c13c9f1a-fce6-7ec8-4c91-3f13bd233284"
    ),
));

$response = curl_exec($curl);
$err = curl_error($curl);


if ($err) {
    echo "cURL Error #:" . $err;
    die();
}


//打印header
if (curl_getinfo($curl, CURLINFO_HTTP_CODE) == '200') {
    $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    $header = substr($response, 0, $headerSize);
    $body = substr($response, $headerSize);

}

curl_close($curl);

$body_arr = (json_decode($body,true));

//var_dump($body_arr);


//用户个人页面
$url = "http://www.miaopai.com".$body_arr['url'];

//echo $url ;

//获取对应的数据

$http_body  = curl(2,$url);


$http_body =   preg_replace("/[\t\n\r]+/","",$http_body);
$str = $http_body[0];
//var_dump($str);
//解析

/*

<a title="关注" href="http://www.miaopai.com/u/mob_76195866/relation/follow.htm">5 关注</a>

 */
$reg_follow='/<a title="关注".*?>(.*?)<\/a>/i';

if(preg_match_all($reg_follow, $str, $matches)){
    $body_arr['follow_num']= trim(str_replace("关注","",$matches[1][0]));
}

//粉丝
$reg_fans='/<a title="粉丝".*?>(.*?)<\/a>/i';

if(preg_match_all($reg_fans, $str, $matches)){
    $body_arr['fans_num'] = trim(str_replace("粉丝","",$matches[1][0]));
}

//视频
$reg_video='/<a title="视频".*?>(.*?)<\/a>/i';

if(preg_match_all($reg_video, $str, $matches)){
    $body_arr['video_num'] = strip_tags(trim(str_replace("视频","",$matches[1][0])));
}

//转发
$reg_feded='/<a title="转发".*?>(.*?)<\/a>/i';

if(preg_match_all($reg_feded, $str, $matches)){
    $body_arr['fwded_num'] =strip_tags(trim(str_replace("转发","",$matches[1][0])));
}
//赞
$reg_like='/<a title="赞".*?>(.*?)<\/a>/i';

if(preg_match_all($reg_like, $str, $matches)){
    $body_arr['like_num'] = strip_tags(trim(str_replace("赞","",$matches[1][0])));
}

var_dump($body_arr);



/**
 * curl处理函数
 * @param $url
 * @param string $method
 * @param array $fields
 * @param array $headers
 * @param bool $auth
 * @return array
 */
function curl($me=1,$url, $method='GET',$fields = [], $headers=[],$auth = false){
    $url=trim($url);
    if($method == "GET"){
        $fields_string = http_build_query($fields);
        $url=$url."?".$fields_string;
    }
    $curl = curl_init($url);
    curl_setopt ($curl, CURLOPT_CUSTOMREQUEST, $method );

    //手机
    if($me == 1){
        $ua="Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5";
    }

    //PC
    if($me == 2){
        $ua=-"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)";
    }


    curl_setopt($curl, CURLOPT_USERAGENT, $ua);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_VERBOSE, 1);
    curl_setopt($curl, CURLOPT_HEADER, 1);
    curl_setopt($curl, CURLOPT_ENCODING, "");
    $header[0] = "Accept: text/html,application/xhtml+xml,application/xml;";
    $header[0] .= "q=0.9,image/webp,*/*;q=0.8";
    $header[] = "Cache-Control: max-age=0";
    $header[] = "Connection: keep-alive";
    $header[] = "Keep-Alive: 10";
    $header[] = "Accept-Encoding: gzip, deflate, sdch";
    $header[] = "Accept-Language: zh-CN,zh;q=0.8,en;q=0.6";
    $header[] = "Pragma: "; // browsers keep this blank.
    curl_setopt($curl, CURLOPT_HTTPHEADER, array_merge($header,$headers));
    if($auth){
        curl_setopt($curl, CURLOPT_USERPWD, "$auth");
        curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    }
    if($fields){
        //POST
        if($method == "POST"){
            $fields_string = http_build_query($fields);
            if(count($fields) != 0 ){
                curl_setopt($curl, CURLOPT_POST, true);
                curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
                curl_setopt($curl, CURLOPT_POSTFIELDS, $fields_string);
            }

        }else{
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true) ;
        }
    }
    $response = curl_exec($curl);
    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    $header_string = substr($response, 0, $header_size);
    $body = substr($response, $header_size);
    $header_rows = explode(PHP_EOL, $header_string);
    foreach($header_rows as $key => $value){
        $header_rows[$key]=trim($header_rows[$key]);
    }
    $i=0;
    foreach((array)$header_rows as $hr){
        $colonpos = strpos($hr, ':');
        $key = $colonpos !== false ? substr($hr, 0, $colonpos) : (int)$i++;
        $headers[$key] = $colonpos !== false ? trim(substr($hr, $colonpos+1)) : $hr;
    }
    $j=0;
    foreach((array)$headers as $key => $val){
        $vals = explode(';', $val);
        if(count($vals) >= 2){
            unset($headers[$key]);
            foreach($vals as $vk => $vv){
                $equalpos = strpos($vv, '=');
                $vkey = $equalpos !== false ? trim(substr($vv, 0, $equalpos)) : (int)$j++;
                $headers[$key][$vkey] = $equalpos !== false ? trim(substr($vv, $equalpos+1)) : $vv;
            }
        }
    }
    curl_close($curl);
    return array($body, $headers);
}

得到的结果如下

数据结果

后记

前后端分离是个趋势,web端也变成了无状态通信,通过token进行身份验证。

结果不重要,重在方法和思路

参考资料

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:505410次
    • 积分:7690
    • 等级:
    • 排名:第3070名
    • 原创:284篇
    • 转载:13篇
    • 译文:4篇
    • 评论:68条
    博客专栏
    微信订阅号
    欢迎加入QQ群
    玩家老黄历(微信小程序)
    谢谢支持~
    最新评论