“接收”;您的防伪令牌无效;在PHP cURL上,而不是在Python请求中

“接收”;您的防伪令牌无效;在PHP cURL上,而不是在Python请求中,python,php,curl,Python,Php,Curl,我正在开发一个从另一个网站抓取数据的应用程序。该网站受登录保护,但我在那里有一个帐户。我的应用程序应该登录到该网站并返回受保护网页的内容。我使用requests包在Python中成功地实现了这一点 现在我想用cURL在PHP中完成同样的事情。不幸的是,在这一刻之前,我无法完成这项工作,我需要你的帮助 在登录之前,网站需要验证令牌。因此,您首先必须获得令牌,然后登录。以下是我的(正在工作的!)Python代码: import requests url = "https://www.my

我正在开发一个从另一个网站抓取数据的应用程序。该网站受登录保护,但我在那里有一个帐户。我的应用程序应该登录到该网站并返回受保护网页的内容。我使用requests包在Python中成功地实现了这一点

现在我想用cURLPHP中完成同样的事情。不幸的是,在这一刻之前,我无法完成这项工作,我需要你的帮助

在登录之前,网站需要验证令牌。因此,您首先必须获得令牌,然后登录。以下是我的(正在工作的!)Python代码:

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(只在你付钱给他们的情况下才有效)
我想强调,Python版本可以工作,但PHP版本不行。(因此,我确信没有丢失或隐藏的参数、要处理的验证码等)


我的问题与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;