如何分析curl抓取页面的编码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何分析curl抓取页面的编码相关的知识,希望对你有一定的参考价值。

示例如下:

$curlPost = \'a=1&b=2\';//模拟POST数据
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array(\'X-FORWARDED-FOR:0.0.0.0\', \'CLIENT-IP:0.0.0.0\'));  //构造IP
curl_setopt($ch, CURLOPT_REFERER, "目标URL");   //构造来路 
curl_setopt($ch,CURLOPT_URL, \'目标URL\');//需要抓取的页面路径
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt ($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);//post值
$file_contents = curl_exec($ch);//抓取的内容放在变量中
curl_close($ch)
参考技术A $ch = curl_init(); //初始化curl
curl_setopt($ch, CURLOPT_URL, ORDERPOSTURL); //抓取指定网页
curl_setopt($ch, CURLOPT_HEADER, 0); //设置header
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //设置是否返回信息
curl_setopt($ch, CURLOPT_POST, 1); //post提交方式
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);//发送数据
$response = curl_exec($ch); //接收返回信息
if (curl_errno($ch))
//出错则记录错误信息
Logger::getLogger("reqLogger")->error("错误信息:" . curl_error($ch));

curl_close($ch); //关闭curl链接
$obj=json_decode($myLogger);//json字符串转化为对象
$arry=json_decode($response,true);//json字符串转化为数组

如何使用 cURL 和 PHP 抓取 LinkedIn 公司页面?在标头错误中找不到 CSRF 令牌

【中文标题】如何使用 cURL 和 PHP 抓取 LinkedIn 公司页面?在标头错误中找不到 CSRF 令牌【英文标题】:How can I scrape LinkedIn company pages with cURL and PHP? No CSRF token found in headers error 【发布时间】:2017-07-08 20:41:25 【问题描述】:

我想用 cURL 和 PHP 抓取一些 LinkedIn 公司页面。 LinkedIn 的 API 不是为此而构建的,所以我必须用 PHP 来做这件事。如果还有其他选择,请告诉我...

在抓取公司页面之前,我必须使用个人帐户通过 cURL 登录 LinkedIn,但它似乎不起作用。

我收到“标头中未找到 CSRF 令牌”错误。

有人可以帮我吗?

谢谢!

<?php

require_once 'dom/simple_html_dom.php';

$linkedin_login_page = "https://www.linkedin.com/uas/login";

$username = 'linkedin_username';
$password = 'linkedin_password';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $linkedin_login_page);
curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17');
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_VERBOSE, 1);

$login_content = str_get_html(curl_exec($ch));

if(curl_error($ch)) 
  echo 'error:' . curl_error($ch);


if ($login_content) 

  if (($login_content->find('input[name=isJsEnabled]', 0))) 
    foreach($login_content->find('input[name=isJsEnabled]') as $element) 

      $isJsEnabled = trim($element->value);

      if ($isJsEnabled === "false") 
        $isJsEnabled = "true";
      

    
  

  if (($login_content->find('input[name=source_app]', 0))) 
    foreach($login_content->find('input[name=source_app]') as $element) 
      $source_app = trim($element->value);
    
  

  if (($login_content->find('input[name=tryCount]', 0))) 
    foreach($login_content->find('input[name=tryCount]') as $element) 
      $tryCount = trim($element->value);
    
  

  if (($login_content->find('input[name=clickedSuggestion]', 0))) 
    foreach($login_content->find('input[name=clickedSuggestion]') as $element) 
      $clickedSuggestion = trim($element->value);
    
  

  if (($login_content->find('input[name=session_redirect]', 0))) 
    foreach($login_content->find('input[name=session_redirect]') as $element) 
      $session_redirect = trim($element->value);
    
  

  if (($login_content->find('input[name=trk]', 0))) 
    foreach($login_content->find('input[name=trk]') as $element) 
      $trk = trim($element->value);
    
  

  if (($login_content->find('input[name=loginCsrfParam]', 0))) 
    foreach($login_content->find('input[name=loginCsrfParam]') as $element) 
      $loginCsrfParam = trim($element->value);
    
  

  if (($login_content->find('input[name=fromEmail]', 0))) 
    foreach($login_content->find('input[name=fromEmail]') as $element) 
      $fromEmail = trim($element->value);
    
  

  if (($login_content->find('input[name=csrfToken]', 0))) 
    foreach($login_content->find('input[name=csrfToken]') as $element) 
      $csrfToken = trim($element->value);
    
  

  if (($login_content->find('input[name=sourceAlias]', 0))) 
    foreach($login_content->find('input[name=sourceAlias]') as $element) 
      $sourceAlias = trim($element->value);
    
  



curl_setopt($ch, CURLOPT_URL, "https://www.linkedin.com/uas/login-submit");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'isJsEnabled='.$isJsEnabled.'&source_app='.$source_app.'&tryCount='.$tryCount.'&clickedSuggestion='.$clickedSuggestion.'&session_key='.$username.'&session_password='.$password.'&session_redirect='.$session_redirect.'&trk='.$trk.'&loginCsrfParam='.$loginCsrfParam.'&fromEmail='.$fromEmail.'&csrfToken='.$csrfToken.'&sourceAlias='.$sourceAlias);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$store = curl_exec($ch);

curl_setopt($ch, CURLOPT_URL, 'https://www.linkedin.com/company/facebook');
curl_setopt($ch, CURLOPT_POST, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, "");
$content = curl_exec($ch);
curl_close($ch);

echo $content;

?>

【问题讨论】:

您的问题可能会被关闭,因为您的要求不是很清楚,而且您提供的代码并未在您的问题中真正引用,也没有针对它提出具体问题。但是你应该看看这个名为Scrapy的Python网站抓取框架,它使从网站中提取内容变得非常容易,甚至允许你让你的抓取工具登录到LinkedIn,这样你就可以查看内容。祝你好运。 嗨,诺亚,感谢您提到 Scrapy。我认为我的问题很清楚;如何使用 cURL 和 PHP 抓取 LinkedIn 公司页面? 尝试提出更具体的问题,cURL 和 PHP 是两个巨大的工具/技术。试着澄清你做了什么,什么是行不通的。 身份验证不起作用。我有一个“在标头中找不到 CSRF 令牌”错误 好了!我看到您还使用此信息编辑了您的问题,干得好。您很快就会发现您的问题是否在本网站上得到回答几乎 100% 与您提出问题的方式有关。结帐this guide about how to ask good questions 【参考方案1】:

这里是登录的解决方案,如果你想确保它正常工作,只需将内容保存在一个文件中,你就会看到登录成功

除了使用我们在 fetch_value 上面使用的 simple_html_dom,你仍然可以使用 simple_html_dom

<?php
function fetch_value($str, $find_start = '', $find_end = '')

    if ($find_start == '')
    
        return '';
    
    $start = strpos($str, $find_start);
    if ($start === false)
    
        return '';
    
    $length = strlen($find_start);
    $substr = substr($str, $start + $length);
    if ($find_end == '')
    
        return $substr;
    
    $end = strpos($substr, $find_end);
    if ($end === false)
    
        return $substr;
    
    return substr($substr, 0, $end);


$linkedin_login_page = "https://www.linkedin.com/uas/login";
$linkedin_ref = "https://www.linkedin.com";

$username = 'username';
$password = 'password';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $linkedin_login_page);
curl_setopt($ch, CURLOPT_REFERER, $linkedin_ref);
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_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');


$login_content = curl_exec($ch);


if(curl_error($ch)) 
  echo 'error:' . curl_error($ch);


$var = array(
            'isJsEnabled' => 'false',
            'source_app' => '',
            'clickedSuggestion' => 'false',
            'session_key' => trim($username),
            'session_password' => trim($password),
            'signin' => 'Sign In',
            'session_redirect' => '',
            'trk' => '',
            'fromEmail' => '');
        $var['loginCsrfParam'] = fetch_value($login_content, 'type="hidden" name="loginCsrfParam" value="', '"');
        $var['csrfToken'] = fetch_value($login_content, 'type="hidden" name="csrfToken" value="', '"');
        $var['sourceAlias'] = fetch_value($login_content, 'input type="hidden" name="sourceAlias" value="', '"');

        $post_array = array();
            foreach ($var as $key => $value)
            
                $post_array[] = urlencode($key) . '=' . urlencode($value);
            
        $post_string = implode('&', $post_array);

curl_setopt($ch, CURLOPT_URL, "https://www.linkedin.com/uas/login-submit");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);

$store = curl_exec($ch);


if (stripos($store, "session_password-login-error") !== false)
    $err = trim(strip_tags(fetch_value($store, '<span class="error" id="session_password-login-error">', '</span>')));
    echo "Login error : ".$err;
elseif (stripos($store, 'profile-nav-item') !== false) 
        curl_setopt($ch, CURLOPT_URL, 'https://www.linkedin.com/company-beta/10667/?pathWildcard=10667');
        curl_setopt($ch, CURLOPT_POST, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, "");
        $content = curl_exec($ch);
        curl_close($ch);

        echo $content;
else
    echo "unknown error";



?>

您会注意到公司页面没有加载,因为linkedin 刚刚更改了他们的设计和他们的公司链接以继续跟踪打开的公司页面。

【讨论】:

谢谢,它有效!公司页面的数据在源头,所以你可以刮一下。。。推荐代理和假账号吗? 是的,我建议只使用假帐户,因为它可能会被关闭 您好,我已尝试实现您的代码,但它返回错误消息“您必须通过身份验证才能访问此页面”。从代码的第 84 行开始输入块后 @faxsy 嗨,我收到“您必须通过身份验证才能访问此页面”响应,就像 tonmoy 一样【参考方案2】:

不要尝试抓取登录信息,只需使用浏览器登录并将会话 cookie 复制到 curl 脚本即可。这将欺骗链接到认为它只是你在你的网络浏览器上。有时,Web 服务器足够聪明,可以查看传递的其他标头(如浏览器类型)并在这种情况下使请求无效,只要确保在 curl 脚本中设置与用于登录的浏览器相同的标头即可。如果您需要我解释如何执行此操作,请告诉我。

【讨论】:

感谢 Mike 帮助我...我不明白你的意思。你的意思是我可以在我的本地浏览器中将 LinkedIn 的 cookie 'JSESSIONID' 存储到我的 curl 脚本中?你能解释一下怎么做吗?这是否也适用于不同的服务器而不是本地? 由于 OP 已经收到“在标头中未找到 CSRF 令牌”错误,因此我非常怀疑这是否可行。这种技术实际上是一种 CSRF 攻击!所以如果他们有 CSRF 保护,它应该停止这种方法。 @Adam 你应该检查我上面的答案,CSRF 被绕过并且登录过程很顺利。 @Adam,大声笑,不,这不是 CSRF。然而,这是一个会话劫持。 @MikeSchem:如果您还复制所有帖子数据,是的。只要你前进时令牌没有改变。

以上是关于如何分析curl抓取页面的编码的主要内容,如果未能解决你的问题,请参考以下文章

好用的 curl 抓取 页面的封装函数

php中curl抓取页面

php curl 模拟post表单向提交数据

php curl抓取淘宝页面显示空白页

PHP cURL库函数抓取页面内容

如何使用 CURL 解析页面中的实际 HTML?