【问题标题】:How do I avoid IP-based redirections in target page with cURL?如何使用 cURL 在目标页面中避免基于 IP 的重定向?
【发布时间】:2012-11-03 11:48:09
【问题描述】:

我正在尝试从 Web 获取数据并将其显示给用户使用 cURL 和 Simple HTML Dom PHP 类。

某些页面有重定向,具体取决于客户端的语言,我正在使用一个函数来确定要抓取的最终页面。

为了像用户看到的那样显示它,我使用这个:

$useragent = $_SERVER['HTTP_USER_AGENT'];
curl_setopt($ch, CURLOPT_USERAGENT,  $useragent);

目前我的大部分用户都是说西班牙语的,因此我暂时限制接受的语言,所以如果目标页面上有语言重定向,它将首先显示西班牙语或英语。

$header[] = "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3";

但是,由于我的服务器位于荷兰,并且某些页面具有基于 IP 的重定向器,因此有时页面会重定向到 /nl/ 目录,而忽略语言参数。

例如,www.econsultancy.com 网站会发生这种情况。

是否有可能避免这种重定向,也许在 cURL 请求中使用 客户端的 IP 地址

另外,是否可以使用客户端的浏览器语言设置来使 Accept-Language 参数动态化?

这是整个函数脚本:

<?
function redirector($originalurl) {

$ch = curl_init();

$useragent = $_SERVER['HTTP_USER_AGENT'];

    $header[0] = "Accept: text/xml,application/xml,application/xhtml+xml,";
    $header[0] .= "text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
    $header[] = "Cache-Control: max-age=0";
    $header[] = "Connection: keep-alive";
    $header[] = "Keep-Alive: 300";
    $header[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7";
    $header[] = "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3";
    $header[] = "Pragma: ";

curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_USERAGENT,  $useragent); 
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    curl_setopt($ch, CURLOPT_URL, $originalurl);
    $out = curl_exec($ch);

    $out = str_replace("\r", "", $out);

    $headers_end = strpos($out, "\n\n");
    if( $headers_end !== false ) { 
        $out = substr($out, 0, $headers_end);
    }   

    $headers = explode("\n", $out);
    foreach($headers as $header) {
        if( substr($header, 0, 10) == "Location: " ) { 
            $target = substr($header, 10);

            $targeturl = $target;
        }   
    }

return $targeturl;
}
?>

提前致谢!

【问题讨论】:

  • 使用$header[] = "X-Forwarded-For: {$_SERVER['REMOTE_ADDR']}";,希望一切顺利
  • 您无法控制远程服务器的重定向设置,所以不能。编辑:@Esailija 的建议是你唯一的希望。
  • 感谢您的提示。我试过了,但没有成功……至少在我测试过的页面上。

标签: php curl http-headers ip user-agent


【解决方案1】:

某些基于 IP 的重定向非常顽固(几乎不可能将某些页面从 切换为英文),但您可以尝试通过使用拦截任何重定向CURLOPT_FOLLOWLOCATION 设置为 False 并解析 Location 标头(此解决方案需要您正确猜测 URL):

$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if( $status_code >= 300 && $status_code < 400){
    // Was redirect, parse header
    if( substr( $location, '/nl/') !== false){
         // Try to load page $url = str_replace( $location, '/nl/', '/en/');
         // Remember to check whether page exists
    } else {
         // Continue request
    }
}

编辑 - 每个网站

如果您有能力在“每个站点”的基础上执行此操作(为每个站点创建切换语言的功能),您可以跟踪切换语言时发生的情况(例如 Firefox 有完美的plugin for this)和大多数您最终将使用的时间:

  • 硬核(用户无法控制语言) - 你完蛋了
  • 不同的 URL(我们已经介绍过)- 你会在 URL 中看到 /nl/lang=nll=nl、...
  • 语言存储在 cookie 中 - 你只需要设置一次 cookie [tutorial] 然后它就正确了
  • 注册用户可以更改语言 - 您需要在每个网站上创建用户,将他的(其)语言切换为 然后(打开页面时)您首先在页面上模拟登录(使用 cookie 打开登录表单和POST 用户名和密码)

如果运气好的话,你会很好地结合“大数组”的 cookie 值对,如下所示:

array (
    'lang' => 'eng',
    'l' => 'en',
    'Language' => 'Engligh',
    ...
)

但是一旦你遇到两个页面使用相同的“cookie 变量名”和不同的值:

lang=eng
lang=en
lang=7

你搞砸了,你将不得不再次使用某种switch($domain)

【讨论】:

  • 感谢 Vyktor,您的解决方案看起来可能可行。我将尝试实施它并给你反馈。
  • 确实,基于 IP 的重定向真的很顽固!我将不得不用 /en/ /eng/ (等等)编写几个猜测,或者如果猜测失败,则重定向到原始 /nl/。非常感谢!
  • @emman 我给了它更多思考并添加了全新的块,希望它会有所帮助
猜你喜欢
  • 2013-05-11
  • 1970-01-01
  • 2014-12-02
  • 2019-03-05
  • 1970-01-01
  • 2019-11-06
  • 2021-12-27
  • 1970-01-01
  • 2016-01-12
相关资源
最近更新 更多