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

2015-08-22 19:18:41 +08:00
 xuyl

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

3797 次点击
所在节点    PHP
17 条回复
xmoon
2015-08-22 19:52:29 +08:00
user agent 有给么? 有些网站防抓会限制 ua
Strikeactor
2015-08-22 19:58:38 +08:00
你先把你用浏览器请求时候的 HTTP 头全部写程序里,要成功了再一个一个注释掉看看
takashiki
2015-08-22 20:24:21 +08:00
什么数据都没有的话,用 curl_error 打印错误看看,还有就是不用 ob_get_contents 直接 echo 结果看看
oott123
2015-08-22 20:31:07 +08:00
目测 gzip
xuyl
2015-08-22 20:33:46 +08:00
@oott123 大神!
xuyl
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
2015-08-22 20:45:00 +08:00
@xuyl header 添加 Accept-Encoding:gzip, deflate 是像服务器声明,可以接收 gzip 压缩数据。并不能让 curl 自动解码数据。

除了 curl_setopt ($ch, CURLOPT_ENCODING ,'gzip'); 这种方法,对拿到的数据进行 gzdecode 操作也可以。
oott123
2015-08-22 20:45:06 +08:00
@xuyl 因为你设置了 Accept-Encoding: gzip 之后,服务器才会用 gzip 给你传回数据
因为你设置 CURLOPT_ENCODING=gzip 之后, curl 才会用 gzip 解压你的数据
aprikyblue
2015-08-22 21:16:32 +08:00
@xuyl
http header 会被 curl 传给服务器,相当于告诉服务器:客户端可以解码 gzip ,用 gzip 传输数据吧!
而你并没有告诉 curl :服务器会用 gzip 传回数据
Smilecc
2015-08-23 00:33:49 +08:00
curl_setopt ($ch, CURLOPT_ENCODING ,'gzip');
是告诉 Curl 使用 Gzip 进行解析。
Header 里面写 Accept-Encoding:gzip 是告诉对方服务器使用 Gzip 进行传输。
iyaozhen
2015-08-23 00:37:27 +08:00
学到了,受益匪浅呀。
@oott123 一语点破
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
2015-08-23 08:14:33 +08:00
make
qq3102328040
2015-08-23 10:52:43 +08:00
涨知识了
nightspirit
2015-08-24 13:44:49 +08:00
同上
leeyuzhe
2015-08-24 14:16:37 +08:00
我上次采集美丽说也是这个坑,返回的数据是 gzip 压缩过的,怎么调都是乱码
mingyun
2015-08-30 17:05:49 +08:00
@Smilecc 学习

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/215183

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX