【问题标题】:PHP post request with cURL and cookie带有 cURL 和 cookie 的 PHP 发布请求
【发布时间】:2015-06-24 07:29:46
【问题描述】:

我正在尝试向需要登录的网页发出请求。 我成功获取了带有 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 新手。

无论我尝试什么,我都会被重定向到登录页面。 试图通过curl_setopt ($ch, CURLOPT_COOKIEFILE, $cookie);,没有成功。

【问题讨论】:

  • 请发布cookie.txt中的内容
  • 只是在cookie中有SESSID并不意味着你已经登录了,它只意味着服务器可以从SESSID识别你为客户端。您也必须登录。
  • 您好,文件中有如下信息:# Netscape HTTP Cookie File # curl.haxx.se/rfc/cookie_spec.html # 此文件由 libcurl 生成!编辑风险自负。 site.com FALSE / FALSE 1429265797 ZBW_SESSID
  • @NikolayMegdanov 请提供来自成功登录帖子请求的帖子和标题信息的 firefox firebug 输出。

标签: php post curl cookies request


【解决方案1】:

也许你会试试guzzle?我为一些游戏引擎编写了代理,我遇到了类似的 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);

【讨论】:

    【解决方案2】:

    我发现 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);
    

    如果有重定向,您可以看到正在发生的事情,并且需要获取在重定向 URL 的响应标头中设置的 cookie,然后 FOLLOWLOCATION 必须设置为 false。

    当 curl URL 将您带到重定向时,curl_getinfo 将获得重定向位置 URL。

    $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 表单的提交按钮。在这些情况下,可能需要从 curl 数据中抓取 cookie 和/或重定向位置。


    然后我使用 FireFox Inspector 或 Chrome 开发工具。

    我转到“网络”标签

    在 FireFox 中,我转到“设置”并打开“启用持久日志”
    在 Chrome 中,我单击“网络”选项卡上的“保留日志”

    然后我使用浏览器去任何我想 curl 去的地方。

    现在我可以看到每个请求和响应,包括重定向,并将它们与保存的标头进行比较。


    当您需要标题与保存的浏览器标题完全相同时:

    创建一个数组来放置请求标头键值
    使用您上传的请求标头中的确切内容填写请求数组。
    示例:

    $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,使用旧的摩托罗拉用户代理来检索标题和 HTML。然后我在 curl 的 HTTPHEADER:

    中使用相同的用户代理
    request[] = 'User-Agent: MOT-V9mm/00.62 UP.Browser/6.2.3.4.c.1.123 (GUI) MMP/2.0
    

    【讨论】:

      【解决方案3】:

      感谢大家的提示。 我是如何使用这段代码的(我实际上使用了错误的帖子数据):

      $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)的某个地方得到了这段代码。感谢发帖的人!不记得确切的名字。这就像一个魅力!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-02-10
        • 1970-01-01
        • 2015-12-06
        • 2022-11-29
        • 2011-04-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多