我正在尝试向需要登录的网页发出请求。 我成功地使用SESSID获取cookie并将其写入curl文件:
$username = 'xxx';
$password = 'xxxxxxx';
$url = 'http://example.com';
$cookie="cookie.txt";
$postdata = "username=$username&userpass=$password&autologin=1&userlogin=Login";
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt ($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6");
curl_setopt ($ch, CURLOPT_TIMEOUT, 60);
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_COOKIEJAR, $cookie);
curl_setopt ($ch, CURLOPT_REFERER, $url);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt ($ch, CURLOPT_POST, 1);
$result = curl_exec ($ch);
curl_close($ch);
现在,在此之后,我想使用cookie向网站发出POST请求,以便将其识别为已登录。如果您请求,则使用返回JSON信息的API:
site.com/API/command.get(x)
- 只是一个例子。因此,如果您在浏览器中打开它,它将返回JSON数据。
任何人都可以帮我一个方法,怎么做?我是新来的卷曲。
无论我尝试什么,我都会被重定向到登录页面。
试图通过curl_setopt ($ch, CURLOPT_COOKIEFILE, $cookie);
,但没有成功。
答案 0 :(得分:1)
我发现curl的cookie jar有问题,所以我编写了自己的例程。还有一些时候我需要添加从页面中删除的cookie
为此CURLOPT_HEADER
必须为真。
curl_setopt($ch, CURLOPT_HEADER, true);
$data = curl_exec($ch);
$skip = intval(curl_getinfo($ch, CURLINFO_HEADER_SIZE));
$requestHeader= substr($data,0,$skip);
$data = substr($data,$skip);
$e = 0;
while(true){
$s = strpos($requestHeader,'Set-Cookie: ',$e);
if (!$s){break;}
$s += 12;
$e = strpos($requestHeader,';',$s);
$cookie = substr($requestHeader,$s,$e-$s) ;
$s = strpos($cookie,'=');
$key = substr($cookie,0,$s);
$value = substr($cookie,$s);
$cookies[$key] = $value;
}
然后使用$ cookies []:
$cookie = '';
$show = '';
$delim = '';
foreach ($cookies as $k => $v){
$cookie .= "$delim$k$v";
$delim = '; ';
}
然后使用$ cookie:
curl_setopt($ch, CURLOPT_COOKIE, $cookie );
遇到问题时,我经常将FOLLOWLOCATION
设为false:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
如果有重定向,您可以看到正在发生的事情,并且需要获取在重定向网址的响应标头中设置的Cookie,然后FOLLOWLOCATION
必须设置为false。
当curl网址转到重定向curl_getinfo
时,会获得重定向位置网址。
$status = intval(curl_getinfo($ch,CURLINFO_HTTP_CODE));
if ($status > 299 && $status < 400){
$url= curl_getinfo($ch,CURLINFO_REDIRECT_URL );
}
// update cookies, do not clear `cookies()`;
当它变得困难时,我使用这些选项来获取响应和响应标头。响应标题将返回curl_exec()
数据。请求标题将由curl_getinfo()
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $request);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_HEADER, true);
$data = curl_exec($ch);
if (curl_errno($ch)){
$data .= 'Retreive Base Page Error: ' . curl_error($ch);
}
else {
$info = rawurldecode(var_export(curl_getinfo($ch),true));
$data = curl_exec($ch);
$skip = intval(curl_getinfo($ch, CURLINFO_HEADER_SIZE));
$requestHeader= substr($data,0,$skip);
$data = substr($data,$skip);
$filename = parse_url($url, PHP_URL_HOST);
$filename .= parse_url($url, PHP_URL_PATH) . '.txt';
$fp = fopen($filename,'w');
fwrite($fp,$info\n$data");
fclose($fp);
$data = substr($data,$skip);
}
标题和HTML都存储在文件中。然后,您可以查看HTTP标头,HTML和JavaScript。有时cookie由JavaScript document.cookie设置,或者使用window.location重定向的页面,或者使用JS单击HTML表单的提交按钮。在这些情况下,可能需要刮掉饼干和/或从卷曲数据中重定向位置。
然后我使用FireFox Inspector或Chrome开发工具。
我转到网络标签页
在FireFox中,我转到“设置”并启用“启用持久日志”
在Chrome中,我点击网络标签页上的“保留日志”
然后我使用浏览器去任何我想要卷曲的地方。
现在我可以看到每个请求和响应,包括重定向,并将它们与保存标题进行比较。
当您需要标题看起来与保存的浏览器标题完全相同时:
创建一个数组以放置请求标头键值
使用您上传的Request标头中的确切内容填写Request数组
示例:强>
$request = array();
$request[] = "Host: www.example.com";
$request[] = "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
$request[] = "User-Agent: MOT-V9mm/00.62 UP.Browser/6.2.3.4.c.1.123 (GUI) MMP/2.0";
$request[] = "Accept-Language: en-US,en;q=0.5";
$request[] = "Connection: keep-alive";
$request[] = "Cache-Control: no-cache";
$request[] = "Pragma: no-cache";
添加到卷曲:
curl_setopt($ch, CURLOPT_HTTPHEADER, $request);
很多时候,使用移动版本要容易得多。很多时候,桌面版本页面需要JavaScript而移动版本则不需要。我使用FireFox与用户代理切换器使用旧的Motorola用户代理来检索标头和HTML。然后我在curl的HTTPHEADER
:
request[] = 'User-Agent: MOT-V9mm/00.62 UP.Browser/6.2.3.4.c.1.123 (GUI) MMP/2.0
答案 1 :(得分:1)
谢谢你的提示。 我如何使用这段代码(我实际上使用了错误的帖子数据):
$username = 'xxx';
$password = 'xxxx';
$url = 'http://example.com'; //request to the page i want the content from
$cookie="cookie.txt";
$url1 = "http://example.com/command..";
//login form action url
$postinfo = "act=login&login=$username&pass=$password";
$cookie_file_path = "cookie.txt";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path);
//set the cookie the site has for certain features, this is optional
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path);
curl_setopt($ch, CURLOPT_USERAGENT,
"Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_REFERER, $_SERVER['REQUEST_URI']);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postinfo);
$result = curl_exec($ch);
//var_dump($result);
//page with the content I want to grab
curl_setopt($ch, CURLOPT_URL, $url1);
//do stuff with the info with DomDocument() etc
$html = curl_exec($ch);
var_dump($html);
curl_close($ch);
我在这里的某处(stackoverflow)得到了这段代码。感谢发布它的那个人!不记得确切的名字。这就像一个魅力!
答案 2 :(得分:0)
也许你会尝试guzzle?我为一些游戏引擎编写了代理,我遇到了与cookie类似的问题。
重要:我没有找到以键值方式操作Cookie的简便方法。所以,对我而言,它的决定更接近于破解而不是解决方案。我将cookie粘贴到字符串:
foreach ($request->cookies as $key => $cookie) {
$cookie_str .= $key .'='.$cookie . ';
}
我的解决方案如下:
$client = new GuzzleHttp\Client([
'headers' => [
'Cookie' => $cookie_str
]
]);
$reqv = $client -> createRequest('POST', 'some_url');
$resp = $client -> send($reqv);