使用 PHP cURL 登录远程站点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3008817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Login to remote site with PHP cURL
提问by Panama Hyman
I'm new to using cURL and its hard to find good resources for it. What I'm trying to do is login to a remote site, by having curl do the login form and then send back that it was successful.
我是使用 cURL 的新手,很难为它找到好的资源。我想要做的是登录到远程站点,让 curl 执行登录表单,然后发回它已成功。
The code I have doesn't seem to work and only tries to show the main page of the site.
我的代码似乎不起作用,只尝试显示站点的主页。
$username="[email protected]";
$password="mypassword";
$url="http://www.myremotesite.com/index.php?page=login";
$cookie="cookie.txt";
$postdata = "email=".$username."&password=".$password;
$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);
echo $result;
curl_close($ch);
What am I doing wrong. After this is working I want to redirect to another page and get content from my site.
我究竟做错了什么。完成此操作后,我想重定向到另一个页面并从我的网站获取内容。
采纳答案by Panama Hyman
I had let this go for a good while but revisited it later. Since this question is viewed regularly. This is eventually what I ended up using that worked for me.
我已经放弃了一段时间,但后来又重新审视了它。由于这个问题经常被查看。这最终是我最终使用的对我有用的东西。
define("DOC_ROOT","/path/to/html");
//username and password of account
$username = trim($values["email"]);
$password = trim($values["password"]);
//set the directory for the cookie using defined document root var
$path = DOC_ROOT."/ctemp";
//build a unique path with every request to store. the info per user with custom func. I used this function to build unique paths based on member ID, that was for my use case. It can be a regular dir.
//$path = build_unique_path($path); // this was for my use case
//login form action url
$url="https://www.example.com/login/action";
$postinfo = "email=".$username."&password=".$password;
$cookie_file_path = $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_COOKIE, "cookiename=0");
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, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postinfo);
curl_exec($ch);
//page with the content I want to grab
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/page/");
//do stuff with the info with DomDocument() etc
$html = curl_exec($ch);
curl_close($ch);
Update: This code was never meant to be a copy and paste. It was to show how I used it for my specific use case. You should adapt it to your code as needed. Such as directories, vars etc
更新:此代码绝不是复制和粘贴。这是为了展示我如何将它用于我的特定用例。您应该根据需要使其适应您的代码。例如目录、变量等
回答by ncm
I had same question and I found this answer on this website.
我有同样的问题,我在这个网站上找到了这个答案。
And I changed it just a little bit (the curl_close at last line)
我只是稍微改变了它(最后一行的 curl_close)
$username = 'myuser';
$password = 'mypass';
$loginUrl = 'http://www.example.com/login/';
//init curl
$ch = curl_init();
//Set the URL to work with
curl_setopt($ch, CURLOPT_URL, $loginUrl);
// ENABLE HTTP POST
curl_setopt($ch, CURLOPT_POST, 1);
//Set the post parameters
curl_setopt($ch, CURLOPT_POSTFIELDS, 'user='.$username.'&pass='.$password);
//Handle cookies for the login
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
//Setting CURLOPT_RETURNTRANSFER variable to 1 will force cURL
//not to print out the results of its query.
//Instead, it will return the results as a string return value
//from curl_exec() instead of the usual true/false.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//execute the request (the login)
$store = curl_exec($ch);
//the login is now done and you can continue to get the
//protected content.
//set the URL to the protected file
curl_setopt($ch, CURLOPT_URL, 'http://www.example.com/protected/download.zip');
//execute the request
$content = curl_exec($ch);
curl_close($ch);
//save the data to disk
file_put_contents('~/download.zip', $content);
I think this was what you were looking for.Am I right?
我想这就是你要找的。我说得对吗?
And one useful related question. About how to keep a session alive in cUrl: https://stackoverflow.com/a/13020494/2226796
还有一个有用的相关问题。关于如何在 cUrl 中保持会话处于活动状态:https://stackoverflow.com/a/13020494/2226796
回答by Joseph
View the source of the login page. Look for the formHTML tag. Within that tag is something that will look like action=Use that value as $url, not the URL of the form itself.
查看登录页面的来源。查找formHTML 标记。在该标签中看起来像action=使用该值作为$url,而不是表单本身的 URL。
Also, while you are there, verify the input boxes are named what you have them listed as.
此外,当您在那里时,请确认输入框的名称与您列出的名称相同。
For example, a basic login form will look similar to:
例如,一个基本的登录表单看起来类似于:
<form method='post' action='postlogin.php'>
Email Address: <input type='text' name='email'>
Password: <input type='password' name='password'>
</form>
Using the above form as an example, change your value of $urlto:
以上面的表格为例,将您的值更改$url为:
$url="http://www.myremotesite.com/postlogin.php";
Verify the values you have listed in $postdata:
验证您在 中列出的值$postdata:
$postdata = "email=".$username."&password=".$password;
and it should work just fine.
它应该可以正常工作。
回答by Mangirdas Skripka
This is how I solved this in ImpressPages:
这就是我在 ImpressPages 中解决这个问题的方法:
//initial request with login data
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.example.com/login.php');
curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/32.0.1700.107 Chrome/32.0.1700.107 Safari/537.36');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, "username=XXXXX&password=XXXXX");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie-name'); //could be empty, but cause problems on some hosts
curl_setopt($ch, CURLOPT_COOKIEFILE, '/var/www/ip4.x/file/tmp'); //could be empty, but cause problems on some hosts
$answer = curl_exec($ch);
if (curl_error($ch)) {
echo curl_error($ch);
}
//another request preserving the session
curl_setopt($ch, CURLOPT_URL, 'http://www.example.com/profile');
curl_setopt($ch, CURLOPT_POST, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, "");
$answer = curl_exec($ch);
if (curl_error($ch)) {
echo curl_error($ch);
}
回答by Pavel Kenarov
Panama Hyman Example not work for me - Give Fatal error: Call to undefined function build_unique_path(). I used this code - (more simple - my opinion) :
巴拿马Hyman示例对我不起作用 - 给出致命错误:调用未定义的函数 build_unique_path()。我使用了这段代码 - (更简单 - 我的意见):
// options
$login_email = '[email protected]';
$login_pass = 'alabala4807';
$cookie_file_path = "/tmp/cookies.txt";
$LOGINURL = "http://alabala.com/index.php?route=account/login";
$agent = "Nokia-Communicator-WWW-Browser/2.0 (Geos 3.0 Nokia-9000i)";
// begin script
$ch = curl_init();
// extra headers
$headers[] = "Accept: */*";
$headers[] = "Connection: Keep-Alive";
// basic curl options for all requests
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path);
// set first URL
curl_setopt($ch, CURLOPT_URL, $LOGINURL);
// execute session to get cookies and required form inputs
$content = curl_exec($ch);
// grab the hidden inputs from the form required to login
$fields = getFormFields($content);
$fields['email'] = $login_email;
$fields['password'] = $login_pass;
// set postfields using what we extracted from the form
$POSTFIELDS = http_build_query($fields);
// change URL to login URL
curl_setopt($ch, CURLOPT_URL, $LOGINURL);
// set post options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $POSTFIELDS);
// perform login
$result = curl_exec($ch);
print $result;
function getFormFields($data)
{
if (preg_match('/()/is', $data, $matches)) {
$inputs = getInputs($matches[1]);
return $inputs;
} else {
die('didnt find login form');
}
}
function getInputs($form)
{
$inputs = array();
$elements = preg_match_all("/(]+>)/is", $form, $matches);
if ($elements > 0) {
for($i = 0;$i $el = preg_replace('/\s{2,}/', ' ', $matches[1][$i]);
if (preg_match('/name=(?:["\'])?([^"\'\s]*)/i', $el, $name)) {
$name = $name[1];
$value = '';
if (preg_match('/value=(?:["\'])?([^"\'\s]*)/i', $el, $value)) {
$value = $value[1];
}
$inputs[$name] = $value;
}
}
}
return $inputs;
}
$grab_url='http://grab.url/alabala';
//page with the content I want to grab
curl_setopt($ch, CURLOPT_URL, $grab_url);
//do stuff with the info with DomDocument() etc
$html = curl_exec($ch);
curl_close($ch);
var_dump($html);
die;

