首页 > 解决方案 > PHP Curl 请求被阻止但在浏览器中有效

问题描述

我有一个脚本,可以从网站上进行一些网页抓取。该网站首先需要一个 OPTIONS 请求,然后是一个 POST 请求,该请求会返回一个包含我需要的数据的 json。它工作正常,我只运行了 6 或 7 次,结果还可以,但现在我的 POST 请求导致一个 HTML 页面显示“您对我们网站的访问被阻止。我们的网站正在使用安全服务来保护抵御攻击。您的访问触发了我们的一项安全措施。”

我知道他们没有阻止我的 IP,因为我可以通过浏览器使用相同的 IP 访问相同的站点并且它工作正常。那么他们怎么知道我使用的是 curl 而不是真正的浏览器呢?

正如您在下面的代码中看到的那样,我已更改用户代理以匹配浏览器中的用户代理,我正在发送与浏览器发送的完全相同的标头。

$useragent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36';

$headerOptions = array(
    ':authority: flight-pricing.maxmilhas.com.br',
    ':method: OPTIONS',
    ':path: /search?time='.$epochtime,
    ':scheme: https',
    'accept: */*',
    'accept-encoding: gzip, deflate, br',
    'accept-language: pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7',
    'access-control-request-headers: authorization,content-type',
    'access-control-request-method: POST',
    'origin: https://www.maxmilhas.com.br',
    'user-agent: '.$useragent
);

$url = 'https://flight-pricing.maxmilhas.com.br/search?time='.$epochtime;

$curl = curl_init();
    curl_setopt($curl, CURLOPT_USERAGENT, $useragent );
    curl_setopt($curl, CURLOPT_AUTOREFERER, true);
    curl_setopt($curl, CURLINFO_HEADER_OUT, true);
    curl_setopt($curl, CURLOPT_COOKIEJAR, "C:/wamp64/www/maxmilhas/tmp/cookieoptions.txt");
    curl_setopt_array($curl, array(
          CURLOPT_URL => $url,
          CURLOPT_RETURNTRANSFER => true,
          CURLOPT_ENCODING => "",
          CURLOPT_MAXREDIRS => 10,
          CURLOPT_TIMEOUT => 30,
          CURLOPT_CUSTOMREQUEST => "OPTIONS",
          CURLOPT_HTTPHEADER => $headerOptions  
    ));

    $response = curl_exec($curl);
    $err = curl_errno($curl);
    file_put_contents('log/headerout/options.txt',curl_getinfo($curl, CURLINFO_HEADER_OUT ));

curl_close($curl);

if ($err) {
    echo "cURL -OPTIONS Request- Error #:" . $err;
}

file_put_contents('log/options.txt',$response);

$headerPost = array(
    ':authority: flight-pricing.maxmilhas.com.br',
    ':method: POST',
    ':path: /search?time='.$epochtime,
    ':scheme: https',
    'accept: application/json, text/plain, */*',
    'accept-encoding: gzip, deflate, br',
    'accept-language: pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7',
    'authorization: '.$authorization,
    'content-length: 145',
    'content-type: application/json;charset=UTF-8',
    'origin: https://www.maxmilhas.com.br',
    'referer: '.$refererPost,
    'user-agent: '.$useragent
);

$curl2 = curl_init();
    curl_setopt($curl2, CURLOPT_URL, $url);
    curl_setopt($curl2, CURLOPT_USERAGENT, $useragent );
    curl_setopt($curl2, CURLOPT_REFERER, $refererPost);
    curl_setopt($curl2, CURLINFO_HEADER_OUT, true);
    curl_setopt($curl2, CURLOPT_AUTOREFERER, true);
    curl_setopt($curl2, CURLOPT_COOKIEJAR, "C:/wamp64/www/maxmilhas/tmp/cookiepost.txt");
    curl_setopt($curl2, CURLOPT_POSTFIELDS, $payload);
    curl_setopt_array($curl2, array(
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => "",
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_CUSTOMREQUEST => "POST",
        CURLOPT_HTTPHEADER => $headerPost
    ));

    $response2 = curl_exec($curl2);
    $err2 = curl_errno($curl2);
    file_put_contents('log/headerout/post.txt',curl_getinfo($curl2, CURLINFO_HEADER_OUT ));

curl_close($curl2);

if ($err2) {
    echo "cURL -POST Request- Error #:" . $err2;
}

file_put_contents('log/post.txt',$response2);

因此,我正在复制 Google Chrome 发送的完全相同的请求,如下图所示:

图 1:Chrome 的 OPTIONS 请求

图 2:Chrome 的 POST 请求

第一次被阻止时,我还没有使用 COOKIEJAR 选项,所以我认为这可能是问题所在。我启用了它,但仍然被阻止。

所以我知道我的代码运行良好,因为它在块之前甚至在启用 cookie 之前运行良好。从那以后我什么都没有改变。但似乎他们可以识别出这个请求来自 curl 然后他们阻止它。

所以我的问题是:如果不是通过我的 IP,他们如何阻止我?我的 curl 请求与普通浏览器请求有什么不同?

我敢打赌,这与 cookie 有关,但除了在 curl 请求上启用 COOKIEJAR 选项外,我不知道如何处理此问题。

我的两个 cookie 文件都是这样的:

图 3:Cookie 文件

谢谢。

标签: phphttpcurlweb-scraping

解决方案


推荐阅读