V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xuyl
V2EX  ›  PHP

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

  •  
  •   xuyl · 2015-08-22 19:18:41 +08:00 · 3824 次点击
    这是一个创建于 3381 天前的主题,其中的信息可能已经有所发展或是发生改变。

    第一步去登录页面 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 页面,返回结果是对数据进行替换了的,所有数据替换成了无意义数据。

    第 1 条附言  ·  2015-08-22 20:17:03 +08:00
    所有请求头都写入$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 条回复    2015-08-30 17:05:49 +08:00
    xmoon
        1
    xmoon  
       2015-08-22 19:52:29 +08:00
    user agent 有给么? 有些网站防抓会限制 ua
    Strikeactor
        2
    Strikeactor  
       2015-08-22 19:58:38 +08:00
    你先把你用浏览器请求时候的 HTTP 头全部写程序里,要成功了再一个一个注释掉看看
    takashiki
        3
    takashiki  
       2015-08-22 20:24:21 +08:00 via Android
    什么数据都没有的话,用 curl_error 打印错误看看,还有就是不用 ob_get_contents 直接 echo 结果看看
    oott123
        4
    oott123  
       2015-08-22 20:31:07 +08:00   ❤️ 1
    目测 gzip
    xuyl
        5
    xuyl  
    OP
       2015-08-22 20:33:46 +08:00
    @oott123 大神!
    xuyl
        6
    xuyl  
    OP
       2015-08-22 20:40:32 +08:00
    @oott123 真大神! 问题已经解决了。就是需要设置一个 curl_setopt ($ch, CURLOPT_ENCODING ,'gzip');就可以正常显示了。但我不明白的是,明明我在 curl_setopt ($ch, CURLOPT_HTTPHEADER, $headers ); 这里的$headers 里面已经加了 Accept-Encoding:gzip, deflate 这样,怎么就不行呢?
    fising
        7
    fising  
       2015-08-22 20:45:00 +08:00
    @xuyl header 添加 Accept-Encoding:gzip, deflate 是像服务器声明,可以接收 gzip 压缩数据。并不能让 curl 自动解码数据。

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

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

    通常我们会用(1 )。

    另外还有个 transfer-encoding ,会改变返回数据的封装格式,没有特殊需要的话也可以关掉,简化流程。
    Yien
        13
    Yien  
       2015-08-23 08:14:33 +08:00 via iPhone
    make
    qq3102328040
        14
    qq3102328040  
       2015-08-23 10:52:43 +08:00
    涨知识了
    nightspirit
        15
    nightspirit  
       2015-08-24 13:44:49 +08:00
    同上
    leeyuzhe
        16
    leeyuzhe  
       2015-08-24 14:16:37 +08:00
    我上次采集美丽说也是这个坑,返回的数据是 gzip 压缩过的,怎么调都是乱码
    mingyun
        17
    mingyun  
       2015-08-30 17:05:49 +08:00
    @Smilecc 学习
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2655 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 02:49 · PVG 10:49 · LAX 18:49 · JFK 21:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.