编辑:,为什么是负1?
我想做的是:
因此,我需要使用我的通行证和号码登录,但在学校网站上的表单也需要一个隐藏的‘令牌’。
<form action="index.php" method="post">
<input type="hidden" name="token" value="becb14a25acf2a0e697b50eae3f0f205" />
<input type="text" name="user" />
<input type="password" name="password" />
<input type="submit" value="submit">
</form>我可以成功地检索令牌。然后我尝试登录,但失败了。
// Getting the whole website
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.school.com');
$data = curl_exec($ch);
// Retrieving the token and putting it in a POST
$regex = '/<regexThatWorks>/';
preg_match($regex,$data,$match);
$postfields = "user=<number>&password=<secret>&token=$match[1]";
// Should I use a fresh cURL here?
// Setting the POST options, etc.
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
// I won't use CURLOPT_RETURNTRANSFER yet, first I want to see results.
$data = curl_exec($ch);
curl_close($ch); 好吧..。不管用..。
发布于 2011-12-26 01:59:11
我就是这样解决的。问题可能是“不使用饼干”部分。不过,这可能是“丑陋”的代码,所以任何改进都是受欢迎的!
// This part is for retrieving the token from the hidden field.
// To be honest, I have no idea what the cookie lines actually do, but it works.
$getToken= curl_init();
curl_setopt($getToken, CURLOPT_URL, '<schoolsite>'); // Set the link
curl_setopt($getToken, CURLOPT_COOKIEJAR, 'cookies.txt'); // Magic
curl_setopt($getToken, CURLOPT_COOKIEFILE, 'cookies.txt'); // Magic
curl_setopt($getToken, CURLOPT_RETURNTRANSFER, 1); // Return only as a string
$data = curl_exec($token); // Perform action
// Close the connection if there are no errors
if(curl_errno($token)){print curl_error($token);}
else{curl_close($token);}
// Use a regular expression to fetch the token
$regex = '/name="token" value="(.*?)"/';
preg_match($regex,$data,$match);
// Put the login info and the token in a post header string
$postfield = "token=$match[1]&user=<number>&paswoord=<mine>";
echo($postfields);
// This part is for logging in and getting the data.
$site = curl_init();
curl_setopt($site, CURLOPT_URL, '<school site');
curl_setopt($site, CURLOPT_COOKIEJAR, 'cookies.txt'); // Magic
curl_setopt($site, CURLOPT_COOKIEFILE, 'cookies.txt'); // Magic
curl_setopt($site, CURLOPT_POST, 1); // Use POST (not GET)
curl_setopt($site, CURLOPT_POSTFIELDS, $postfield); // Insert headers
$forevil_uuh_no_GOOD_purposes = curl_exec($site); // Output the results
// Close connection if no errors
if(curl_errno($site)){print curl_error($site);}
else{curl_close($site);} 发布于 2011-12-26 01:00:19
你收到的错误信息是什么?与此无关;您的学校网站可能会检查推荐人的标题,并确保请求来自(假装是.)的应用程序。它的登录页面。
发布于 2011-12-26 13:52:24
当您正在构建一个刮板时,您可以创建您自己的类来完成您需要在您的域中所做的工作。您可以从创建自己的请求和响应类开始,这些类处理需要处理的内容。
创建自己的请求类将允许您以需要的方式实现curl请求。创建自己的响应类可以帮助您访问/解析返回的HTML。
这是我为演示创建的一些类的简单用法示例:
# simple get request
$request = new MyRequest('http://hakre.wordpress.com/');
$response = new MyResponse($request);
foreach($response->xpath('//div[@id="container"]//div[contains(normalize-space(@class), " post ")]') as $node)
{
if (!$node->h2->a) continue;
echo $node->h2->a, "\n<", $node->h2->a['href'] ,">\n\n";
}它将返回我的博客帖子:
Will Automattic join Dec 29 move away from GoDaddy day?
<http://hakre.wordpress.com/2011/12/23/will-automattic-join-dec-29-move-away-from-godaddy-day/>
PHP UTF-8 string Length
<http://hakre.wordpress.com/2011/12/13/php-utf-8-string-length/>
Title belongs into Head
<http://hakre.wordpress.com/2011/11/02/title-belongs-into-head/>
...发送get请求就像派一样简单,可以使用xpath表达式轻松地访问响应(这里是SimpleXML)。XPath可以帮助您从表单字段中选择令牌,因为它允许您比使用正则表达式更容易地查询文档的数据。
发送一个帖子请求是下一件要构建的事情,我试图为我的博客编写一个登录脚本,结果它运行得很好。我还需要解析响应头,所以我在请求和响应类中添加了更多的例程。
# simple post request
$request = new MyRequest('https://example.wordpress.com/wp-login.php');
$postFields = array(
'log' => 'username',
'pwd' => 'password',
);
$request->setPostFields($postFields);
$response = new MyResponse($request->returnHeaders(1)->execute());
echo (string) $response; # output to view headers考虑到您的场景,您可能希望编辑自己的请求类,以便更好地处理所需的内容,而我的类已经使用了cookie,因为您也在使用它们。因此,您的场景中基于这些类的一些代码可能如下所示:
# input values
$url = '<schoolsite>';
$user = '<number>';
$password = '<secret>';
# execute the first get request to obtain token
$response = new MyResonse(new MyRequest($url));
$token = (string) $response->xpath('//input[@name="token"]/@value');
# execute the second login post request
$request = new MyRequest($url);
$postFields = array(;
'user' => $user,
'password' => $password,
'token' => $token
);
$request->setPostFields($postFields)->execute();演示和代码作为依据.
如果您想进一步改进这一点,下一步是为“学校服务”创建一个类,您可以使用该类获取时间表:
class MySchoolService
{
private $url, $user, $pass;
private $isLoggedIn;
public function __construct($url, $user, $pass)
{
$this->url = $url;
...
}
public function getSchedule()
{
$this->ensureLogin();
# your code to obtain the schedule, e.g. in form of an array.
$schedule = ...
return $schedule;
}
private function ensureLogin($reuse = TRUE)
{
if ($reuse && $this->isLoggedIn) return;
# execute the first get request to obtain token
$response = new MyResonse(new MyRequest($this->url));
$token = (string) $response->xpath('//input[@name="token"]/@value');
# execute the second login post request
$request = new MyRequest($this->url);
$postFields = array(;
'user' => $this->user,
'password' => $this->password,
'token' => $token
);
$request->setPostFields($postFields)->execute();
$this->isLoggedIn = TRUE;
}
}将请求/响应逻辑很好地封装到您的MySchoolService类之后,只需使用适当的配置实例化它,您就可以在您的网站内轻松地使用它:
$school = new MySchoolService('<schoolsite>', '<number>', '<secret>');
$schedule = $school->getSchedule();您的主脚本只使用MySchoolService。
MySchoolService负责使用MyRequest和MyResponse对象。
MyRequest负责使用cookies等处理HTTP请求(这里使用cUrl)。
MyResponse在解析HTTP响应方面有一点帮助。
将其与标准的internet浏览器进行比较:
Browser: Handles cookies and sessions, does HTTP requests and parses responses.
MySchoolService: Handles cookies and sessions for your school, does HTTP requests and parses responses.所以,你现在的脚本中有一个学校浏览器,可以做你想做的事。如果您需要更多的选项,您可以轻松地扩展它。
我希望这是有帮助的,出发点是防止重复编写相同的cUrl代码,并为您提供一个更好的接口来解析返回值。MySchoolService是一些糖在顶部,使事情更容易处理在您自己的网站/应用程序代码。
https://stackoverflow.com/questions/8632366
复制相似问题