xuyl
V2EX  ›  PHP

关于 php curl 模拟登录的问题。。。。

  •  
  •   xuyl · Aug 22, 2015 · 4350 views
    This topic created in 3957 days ago, the information mentioned may be changed or developed.

    第一步去登录页面 http://xxx.com/login.jsp 获取随机码;这里已经保存了 $cookie;

    第二步构造参数 post 请求认证页面 http://xxx.com/userlogin; 这里用到上一步的$cookie;

    前两步模拟登录成功,之后则是去登录后才能 ajax 请求的页面获取数据了。

    代码如下:

    function get_json ($url, $headers, $cookie, $post ) {
    $curl = curl_init ();//初始化 curl 模块
    curl_setopt ($curl, CURLOPT_URL, $url );//请求地址
    curl_setopt ($curl, CURLOPT_HEADER, 0 );//是否显示头信息
    curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1 );//是否自动显示返回的信息
    curl_setopt ($curl, CURLOPT_HTTPHEADER, $headers ); //设置请求头
    curl_setopt ($curl, CURLOPT_COOKIEFILE, $cookie ); //读取 cookie
    curl_setopt ($curl, CURLOPT_POST, 1 );//post 方式提交
    curl_setopt ($curl, CURLOPT_POSTFIELDS, $post );//要提交的信息
    ob_start ();
    curl_exec ($curl ); //执行 cURL
    curl_close ($curl );//关闭 cURL 资源,并且释放系统资源
    $json = ob_get_contents ();
    ob_clean ();
    return $json;
    }

    问题就出在这里了,没有获得数据。

    补充:
    登录后,直接打开那个 json 页面,返回结果是对数据进行替换了的,所有数据替换成了无意义数据。

    Supplement 1  ·  Aug 22, 2015
    所有请求头都写入$headers 里面了,我最终请求的页面,如果正常登录,用 Chrome 的调试工具看到的 json 数据是完整的,若直接打开这个页面则数据被替换了。
    正常的返回数据类似
    {
    "items": [
    {
    "alexaShard": "null_alexa",
    "avg": 0,
    "content": 0,
    "day": "2015-08-19",
    "defid": 15640923,
    "effectiveContent": 0,
    "excel": false,
    "ip": 956317,
    "limit": 30,
    }
    ]
    }

    我刚才调整了一下,获得了返回数据,却是乱码: � �P�j 1 ��3t� ��Q���Ar,!�^m���î����{d�B ���$�4 in� �+�� �Ws��2����?W �� 4g`cH R� �Ic��n��N pt� ]��W�0�qD�܆� D�Z��G�Wd�.D \�� �fG� ��]�2 �� ����gR�L1��3+R:��;���� ���JȮ�JqN1 :�DV��)&7cM�- ��#d�Z���ߚ��_֜Ȼ�� m\ 2Sޟ @���S
    17 replies    2015-08-30 17:05:49 +08:00
    xmoon
        1
    xmoon  
       Aug 22, 2015
    user agent 有给么? 有些网站防抓会限制 ua
    Strikeactor
        2
    Strikeactor  
       Aug 22, 2015
    你先把你用浏览器请求时候的 HTTP 头全部写程序里,要成功了再一个一个注释掉看看
    Dowding
        3
    Dowding  
       Aug 22, 2015 via Android
    什么数据都没有的话,用 curl_error 打印错误看看,还有就是不用 ob_get_contents 直接 echo 结果看看
    oott123
        4
    oott123  
       Aug 22, 2015   ❤️ 1
    目测 gzip
    xuyl
        5
    xuyl  
    OP
       Aug 22, 2015
    @oott123 大神!
    xuyl
        6
    xuyl  
    OP
       Aug 22, 2015
    @oott123 真大神! 问题已经解决了。就是需要设置一个 curl_setopt ($ch, CURLOPT_ENCODING ,'gzip');就可以正常显示了。但我不明白的是,明明我在 curl_setopt ($ch, CURLOPT_HTTPHEADER, $headers ); 这里的$headers 里面已经加了 Accept-Encoding:gzip, deflate 这样,怎么就不行呢?
    fising
        7
    fising  
       Aug 22, 2015
    @xuyl header 添加 Accept-Encoding:gzip, deflate 是像服务器声明,可以接收 gzip 压缩数据。并不能让 curl 自动解码数据。

    除了 curl_setopt ($ch, CURLOPT_ENCODING ,'gzip'); 这种方法,对拿到的数据进行 gzdecode 操作也可以。
    oott123
        8
    oott123  
       Aug 22, 2015   ❤️ 1
    @xuyl 因为你设置了 Accept-Encoding: gzip 之后,服务器才会用 gzip 给你传回数据
    因为你设置 CURLOPT_ENCODING=gzip 之后, curl 才会用 gzip 解压你的数据
    aprikyblue
        9
    aprikyblue  
       Aug 22, 2015
    @xuyl
    http header 会被 curl 传给服务器,相当于告诉服务器:客户端可以解码 gzip ,用 gzip 传输数据吧!
    而你并没有告诉 curl :服务器会用 gzip 传回数据
    Smilecc
        10
    Smilecc  
       Aug 23, 2015
    curl_setopt ($ch, CURLOPT_ENCODING ,'gzip');
    是告诉 Curl 使用 Gzip 进行解析。
    Header 里面写 Accept-Encoding:gzip 是告诉对方服务器使用 Gzip 进行传输。
    iyaozhen
        11
    iyaozhen  
       Aug 23, 2015
    学到了,受益匪浅呀。
    @oott123 一语点破
    msg7086
        12
    msg7086  
       Aug 23, 2015
    @xuyl
    @iyaozhen
    这个算是比较基础的问题。
    accept-encoding 里写 gzip 是表示你(或者你写的程序)有能力识别并处理 gzip 的返回。
    然而实际上你并没有这个能力。

    所以解决方案有两种。
    (1 ) 告诉服务器你没有能力处理 gzip ,也就是不加这个 accept-encoding 头,那么返回的就是原始数据。
    (2 ) 加入 gzip 处理流程,例如上面的 CURLOPT_ENCODING 选项。亦或者自己调用 PHP 的 gzip 相关函数去解压缩。

    通常我们会用(1 )。

    另外还有个 transfer-encoding ,会改变返回数据的封装格式,没有特殊需要的话也可以关掉,简化流程。
    Yien
        13
    Yien  
       Aug 23, 2015 via iPhone
    make
    qq3102328040
        14
    qq3102328040  
       Aug 23, 2015
    涨知识了
    nightspirit
        15
    nightspirit  
       Aug 24, 2015
    同上
    ThisDay
        16
    ThisDay  
       Aug 24, 2015
    我上次采集美丽说也是这个坑,返回的数据是 gzip 压缩过的,怎么调都是乱码
    mingyun
        17
    mingyun  
       Aug 30, 2015
    @Smilecc 学习
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   4039 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 72ms · UTC 05:16 · PVG 13:16 · LAX 22:16 · JFK 01:16
    ♥ Do have faith in what you're doing.