0

私はこのコードhttp://martinsikora.com/how-to-steal-google-s-did-you-mean-featureを使用して私のsearhで「didyoumean」を実行していますが、私のホスティングプロバイダーにはopen_basedirが設定されており、leytはありません私は変わります。いくつかの回避策を見てきましたが、これらを彼のコードにどのように実装するかはわかりません。

ここにスニペットがあります:

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, $agents[rand(0, count($agents) - 1)]);
$data = curl_exec($ch);
curl_close($ch);
4

1 に答える 1

1

特に簡単に回避できる場合は、なんと奇妙で厄介な(そして基本的に文書化されていない)制限です。3xx応答コードを確認し、Location:ヘッダーの内容を調べて、リダイレクト先のURLを見つけるだけです。

これは、RFCに違反し、ロケーションヘッダーのデータとして完全なURLを使用しないアプリケーションが多数あるため、私のように簡単ではありません。そのため、適切に処理するには少し手間をかける必要があります。位置。

このようなものがあなたのコードで機能するはずです(テストされていません):

function make_url_from_location ($oldUrl, $locationHeader) {
  // Takes a URL and a location header and calculates the new URL
  // This takes relative paths (which are non-RFC compliant) into
  // account, which most browsers will do. Requires $oldUrl to be
  // a full URL

  // First check if $locationHeader is a full URL
  $newParts = parse_url($locationHeader);
  if (!empty($newParts['scheme'])) {
    return $locationHeader;
  }

  // We need a path at a minimum. If not, return the old URL.
  if (empty($newParts['path'])) {
    return $oldUrl;
  }

  // Construct the start of the new URL
  $oldParts = parse_url($oldUrl);
  $newUrl = $oldParts['scheme'].'://'.$oldParts['host'];
  if (!empty($oldParts['port'])) {
    $newUrl .= ':'.$oldParts['port'];
  }

  // Build new path
  if ($newParts['path'][0] == '/') {
    $newUrl .= $newParts['path'];
  } else {
    // str_replace() to work around (buggy?) Windows behaviour where one level
    // paths cause dirname to return a \ instead of a /
    $newUrl .= str_replace('\\', '/', dirname($oldParts['path'])).$newParts['path'];
  }

  // Add a query string
  if (!empty($newParts['query'])) {
    $newUrl .= '?'.$newParts['query'];
  }

  return $newUrl;

}

$maxRedirects = 30;

$redirectCount = 0;
$complete = FALSE;

// Get user agent string once at start - array_rand() is tidier
// For these purposes, a single static string will probably be fine
$userAgent = $agents[array_rand($agents)];

do {

  // Make the request
  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
  curl_setopt($ch, CURLOPT_TIMEOUT, 10);
  curl_setopt($ch, CURLOPT_HEADER, true);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_USERAGENT, $userAgent]);
  $data = curl_exec($ch);

  // Get the response code (easier than parsing it from the headers)
  $responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

  // Split header from body
  $data = explode("\r\n\r\n", $data, 2);
  $header = $data[0];
  $data = $data[1];

  // Check for redirect response codes
  if ($responseCode >= 300 && $responseCode < 400) {

    if (!preg_match('/^location:\s*(.+?)$/mi', $header, $matches)) {
      // This is an error. If you get here the response was a 3xx code and
      // no location header was set. You need to handle that error here.
      $complete = TRUE;
    }

    // Get URL for next iteration
    $url = make_url_from_location(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL), trim($matches[1]));

  } else {

    // Non redirect response code (might still be an error code though!)
    $complete = TRUE;

  }

// Loop until no more redirects or $maxRedirects is reached
} while (!$complete && ++$redirectCount < $maxRedirects);

// Perform whatever error checking is necessary here

// Close the cURL handle
curl_close($ch);
于 2012-07-10T22:35:28.550 に答える