“接收”;您的防伪令牌无效;在PHP cURL上,而不是在Python请求中
我正在开发一个从另一个网站抓取数据的应用程序。该网站受登录保护,但我在那里有一个帐户。我的应用程序应该登录到该网站并返回受保护网页的内容。我使用requests包在Python中成功地实现了这一点 现在我想用cURL在PHP中完成同样的事情。不幸的是,在这一刻之前,我无法完成这项工作,我需要你的帮助 在登录之前,网站需要验证令牌。因此,您首先必须获得令牌,然后登录。以下是我的(正在工作的!)Python代码:“接收”;您的防伪令牌无效;在PHP cURL上,而不是在Python请求中,python,php,curl,Python,Php,Curl,我正在开发一个从另一个网站抓取数据的应用程序。该网站受登录保护,但我在那里有一个帐户。我的应用程序应该登录到该网站并返回受保护网页的内容。我使用requests包在Python中成功地实现了这一点 现在我想用cURL在PHP中完成同样的事情。不幸的是,在这一刻之前,我无法完成这项工作,我需要你的帮助 在登录之前,网站需要验证令牌。因此,您首先必须获得令牌,然后登录。以下是我的(正在工作的!)Python代码: import requests url = "https://www.my
import requests
url = "https://www.mywebsite.com/login.php"
headers = {'user-agent': "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36"}
s = requests.Session()
// Get token
r1 = s.get(url, headers = headers)
cacheToken = ExtractTokenFromText(r1.text) // some function defined by me
// Login
data = {'username': 'myusername', \
'password': 'mypassword', \
'__RequestVerificationToken': cacheToken}
r2 = s.post(url, headers = headers, data = data)
my_content = r2.text
现在,我尝试使用cURL库在PHP中实现相同的功能。我的PHP代码是:
$url = "https://www.mywebsite.com/login.php";
$ch = curl_init();
// Get token
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADERFUNCTION, "curlResponseHeaderCallback");
$r1 = curl_exec($ch);
function curlResponseHeaderCallback($ch, $headerLine) {
global $cache_token;
$cache_token = ExtractTokenFromHeader($headerline); // some function defined by me
return strlen($headerLine); // Needed by curl
}
// Login
$post_data = array('username' => $myusername,
'password' => $mypassword,
'__RequestVerificationToken' => $cache_token);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
$r2 = curl_exec($ch);
$my_content = $r2;
PHP文件正确接收$cache_令牌,因此正确执行GET请求。不幸的是,POST请求不起作用,因为PHP文件给出以下错误消息:
“您的反伪造令牌无效。”HTTP 400错误请求
我尝试了很多方法来解决这个问题,但没有一种有效:
- 添加用户代理curl_setopt($ch,CURLOPT_USERAGENT, “Mozilla/5.0(Windows NT 10.0;WOW64)AppleWebKit/537.36(KHTML,像Gecko)Chrome/57.0.2987.98 Safari/537.36”)李>
- 添加curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);第二个请求
- 添加curl_setopt($ch,CURLOPT_COOKIEJAR,$cookiefile);使用以下三个选项之一:
- 添加curl_setopt($ch,CURLOPT_COOKIEFILE,$COOKIEFILE);(同上)
- 添加curl_setopt($ch,CURLOPT_FOLLOWLOCATION,TRUE)李>
- 启用错误报告以查找问题
- 直接使用他们的API(只在你付钱给他们的情况下才有效)
我的问题与and相似,但它们的解决方案要么对我不起作用,根本没有答案……因此这当然取决于网站,但我想我在GitHub上也遇到过类似的情况。我有一个GitHub登录名,我想通过编程访问一些API中不可用的信息。要使用GitHub登录,请执行以下操作:
<?php
$get_r = curl_init('https://github.com/login');
curl_setopt($get_r, CURLOPT_RETURNTRANSFER, true);
# Get response cookie from login page. "curl_close" creates the file.
curl_setopt($get_r, CURLOPT_COOKIEJAR, 'github.txt');
$log_s = curl_exec($get_r);
curl_close($get_r);
# Get authenticity token
preg_match('/name="authenticity_token" value="([^"]*)"/', $log_s, $auth_a);
$post_m['authenticity_token'] = $auth_a[1];
# Set username
$post_m['login'] = getenv('USERNAME');
# Set password
$post_m['password'] = getenv('PASSWORD');
$post_r = curl_init('https://github.com/session');
curl_setopt($post_r, CURLOPT_COOKIEFILE, 'github.txt');
curl_setopt($post_r, CURLOPT_POSTFIELDS, $post_m);
curl_exec($post_r);
多亏了@Steven Penny,我终于让它工作起来了。主要区别:
- 从第一次获取令牌的方式完全不同:不使用CURLOPT_RETURNTRANSFER,而是直接从$r1.text获取令牌
- 增加了curl_setopt($ch,CURLOPT_COOKIEJAR,$cookiefile);两个电话
- 增加了curl_setopt($ch,CURLOPT_FOLLOWLOCATION,true);只打第二个电话
我最后的剧本:
$url = "https://www.mywebsite.com/login.php";
$cookiefile = 'cookie.txt';
$ch = curl_init();
// Get token
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiefile);
$r1 = curl_exec($ch);
$dom = new DOMDocument;
$dom->loadHTML($response);
$tags = $dom->getElementsByTagName('input');
$token = '';
for($i=0; $i<$tags->length; $i++)
{
$grab = $tags->item($i);
if ($grab->getAttribute('name') === '__RequestVerificationToken')
{
$token = $grab->getAttribute('value');
}
}
// Login
$post_data = array('username' => $myusername,
'password' => $mypassword,
'__RequestVerificationToken' => $cache_token);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiefile);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$r2 = curl_exec($ch);
$my_content = $r2;
$url=”https://www.mywebsite.com/login.php";
$cookiefile='cookie.txt';
$ch=curl_init();
//领取代币
curl_setopt($ch,CURLOPT_URL,$URL);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_COOKIEJAR,$cookiefile);
$r1=旋度执行($ch);
$dom=新的DOMDocument;
$dom->loadHTML($response);
$tags=$dom->getElementsByTagName('input');
$token='';
对于($i=0;$i长度;$i++)
{
$grab=$tags->item($i);
如果($grab->getAttribute('name')=='\uu请求验证登录')
{
$token=$grab->getAttribute('value');
}
}
//登录
$post_data=array('username'=>$myusername,
“密码”=>$mypassword,
“\uu RequestVerificationToken”=>$cache\u令牌);
curl_setopt($ch,CURLOPT_URL,$URL);
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_POSTFIELDS,http_build_query($post_data));
curl_setopt($ch,CURLOPT_COOKIEJAR,$cookiefile);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,true);
$r2=旋度执行($ch);
$my_content=$r2;
谢谢,我已使用您的示例脚本修复了我的问题!请参阅已接受的解决方案。
$url = "https://www.mywebsite.com/login.php";
$cookiefile = 'cookie.txt';
$ch = curl_init();
// Get token
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiefile);
$r1 = curl_exec($ch);
$dom = new DOMDocument;
$dom->loadHTML($response);
$tags = $dom->getElementsByTagName('input');
$token = '';
for($i=0; $i<$tags->length; $i++)
{
$grab = $tags->item($i);
if ($grab->getAttribute('name') === '__RequestVerificationToken')
{
$token = $grab->getAttribute('value');
}
}
// Login
$post_data = array('username' => $myusername,
'password' => $mypassword,
'__RequestVerificationToken' => $cache_token);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiefile);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$r2 = curl_exec($ch);
$my_content = $r2;