복붙노트

cURL을 사용하여 리디렉션되는 위치를 찾으려면 어떻게합니까?

PHP

cURL을 사용하여 리디렉션되는 위치를 찾으려면 어떻게합니까?

컬링이 리디렉션을 따르도록하려하지만 제대로 작동하지 않습니다. 서버에 GET 매개 변수로 보내고 결과 URL을 가져 오려는 문자열이 있습니다.

예:

해당 URL로 이동하면 "www.wowhead.com/npc=257"로 리디렉션됩니다. 나는 "npc = 257"을 추출하여 사용할 수 있도록이 URL을 PHP 코드에 반환하도록하고 싶다.

현재 코드 :

function npcID($name) {
    $urltopost = "http://www.wowhead.com/search?q=" . $name;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1");
    curl_setopt($ch, CURLOPT_URL, $urltopost);
    curl_setopt($ch, CURLOPT_REFERER, "http://www.wowhead.com");
    curl_setopt($ch, CURLOPT_HTTPHEADER, Array("Content-Type:application/x-www-form-urlencoded"));
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
    return curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
}

그러나 www.wowhead.com/search?q=Kobold+Worker는 반환하지만 www.wowhead.com/npc=257은 반환하지 않습니다.

외부 리디렉션이 발생하기 전에 PHP가 돌아가고 있다고 의심됩니다. 이 문제를 어떻게 해결할 수 있습니까?

해결법

  1. ==============================

    1.cURL이 리디렉션을 따르게하려면 다음을 사용하십시오.

    cURL이 리디렉션을 따르게하려면 다음을 사용하십시오.

    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    

    음 ... 네가 실제로 컬을하고 있다고 생각하지 않는다. 시도해 보라.

    curl_exec ($ ch);

    ... 옵션을 설정 한 후 curl_getinfo () 호출 전에.

    편집 : 페이지가 리디렉션되는 곳을 찾고 싶다면 여기서 조언을 사용하고 Curl을 사용하여 헤더를 가져 와서 Location : 헤더를 추출하십시오.

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $result = curl_exec($ch);
    if (preg_match('~Location: (.*)~i', $result, $match)) {
       $location = trim($match[1]);
    }
    
  2. ==============================

    2.curl 초기화에이 행 추가

    curl 초기화에이 행 추가

    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    

    curl_close 전에 getinfo를 사용하십시오.

    $redirectURL = curl_getinfo($ch,CURLINFO_EFFECTIVE_URL );
    

    :

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,0); 
    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
    $html = curl_exec($ch);
    $redirectURL = curl_getinfo($ch,CURLINFO_EFFECTIVE_URL );
    curl_close($ch);
    
  3. ==============================

    3.위의 대답은 내 서버 중 하나에서 작동하지 않았으며, basedir과 함께 할 일이 너무 많았 기 때문에 조금 바꿨습니다. 아래 코드는 모든 서버에서 작동합니다.

    위의 대답은 내 서버 중 하나에서 작동하지 않았으며, basedir과 함께 할 일이 너무 많았 기 때문에 조금 바꿨습니다. 아래 코드는 모든 서버에서 작동합니다.

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    $a = curl_exec($ch);
    curl_close( $ch ); 
    // the returned headers
    $headers = explode("\n",$a);
    // if there is no redirection this will be the final url
    $redir = $url;
    // loop through the headers and check for a Location: str
    $j = count($headers);
    for($i = 0; $i < $j; $i++){
    // if we find the Location header strip it and fill the redir var       
    if(strpos($headers[$i],"Location:") !== false){
            $redir = trim(str_replace("Location:","",$headers[$i]));
            break;
        }
    }
    // do whatever you want with the result
    echo redir;
    
  4. ==============================

    4.여기에 선택한 대답은 알맞지 만 대소 문자를 구분합니다. 상대적 위치 (헤더가있는 사이트 또는 페이지가 실제로 위치라는 문구가 포함 된 페이지)를 보호하지 못합니다 (현재 zillow가 수행).

    여기에 선택한 대답은 알맞지 만 대소 문자를 구분합니다. 상대적 위치 (헤더가있는 사이트 또는 페이지가 실제로 위치라는 문구가 포함 된 페이지)를 보호하지 못합니다 (현재 zillow가 수행).

    약간 지저분하지만 조금 더 똑똑해 지도록 몇 가지 빠른 수정이 있습니다.

    function getOriginalURL($url) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        $result = curl_exec($ch);
        $httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
    
        // if it's not a redirection (3XX), move along
        if ($httpStatus < 300 || $httpStatus >= 400)
            return $url;
    
        // look for a location: header to find the target URL
        if(preg_match('/location: (.*)/i', $result, $r)) {
            $location = trim($r[1]);
    
            // if the location is a relative URL, attempt to make it absolute
            if (preg_match('/^\/(.*)/', $location)) {
                $urlParts = parse_url($url);
                if ($urlParts['scheme'])
                    $baseURL = $urlParts['scheme'].'://';
    
                if ($urlParts['host'])
                    $baseURL .= $urlParts['host'];
    
                if ($urlParts['port'])
                    $baseURL .= ':'.$urlParts['port'];
    
                return $baseURL.$location;
            }
    
            return $location;
        }
        return $url;
    }
    

    이는 여전히 리다이렉션 깊이가 1만큼만 진행된다는 점에 유의하십시오. 더 깊이 들어가려면 실제로 콘텐츠를 가져와 리디렉션을 따라야합니다.

  5. ==============================

    5.때로는 HTTP 헤더를 가져와야하지만 그와 동시에 헤더를 반환하지 않으려는 경우도 있습니다. **

    때로는 HTTP 헤더를 가져와야하지만 그와 동시에 헤더를 반환하지 않으려는 경우도 있습니다. **

    이 스켈레톤은 재귀를 사용하여 쿠키 및 HTTP 리디렉션을 처리합니다. 주요 아이디어는 클라이언트 코드로 HTTP 헤더를 반환하지 않는 것입니다.

    그 위에 매우 강한 컬 클래스를 만들 수 있습니다. POST 기능 추가 등

    <?php
    
    class curl {
    
      static private $cookie_file            = '';
      static private $user_agent             = '';  
      static private $max_redirects          = 10;  
      static private $followlocation_allowed = true;
    
      function __construct()
      {
        // set a file to store cookies
        self::$cookie_file = 'cookies.txt';
    
        // set some general User Agent
        self::$user_agent = 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)';
    
        if ( ! file_exists(self::$cookie_file) || ! is_writable(self::$cookie_file))
        {
          throw new Exception('Cookie file missing or not writable.');
        }
    
        // check for PHP settings that unfits
        // correct functioning of CURLOPT_FOLLOWLOCATION 
        if (ini_get('open_basedir') != '' || ini_get('safe_mode') == 'On')
        {
          self::$followlocation_allowed = false;
        }    
      }
    
      /**
       * Main method for GET requests
       * @param  string $url URI to get
       * @return string      request's body
       */
      static public function get($url)
      {
        $process = curl_init($url);    
    
        self::_set_basic_options($process);
    
        // this function is in charge of output request's body
        // so DO NOT include HTTP headers
        curl_setopt($process, CURLOPT_HEADER, 0);
    
        if (self::$followlocation_allowed)
        {
          // if PHP settings allow it use AUTOMATIC REDIRECTION
          curl_setopt($process, CURLOPT_FOLLOWLOCATION, true);
          curl_setopt($process, CURLOPT_MAXREDIRS, self::$max_redirects); 
        }
        else
        {
          curl_setopt($process, CURLOPT_FOLLOWLOCATION, false);
        }
    
        $return = curl_exec($process);
    
        if ($return === false)
        {
          throw new Exception('Curl error: ' . curl_error($process));
        }
    
        // test for redirection HTTP codes
        $code = curl_getinfo($process, CURLINFO_HTTP_CODE);
        if ($code == 301 || $code == 302)
        {
          curl_close($process);
    
          try
          {
            // go to extract new Location URI
            $location = self::_parse_redirection_header($url);
          }
          catch (Exception $e)
          {
            throw $e;
          }
    
          // IMPORTANT return 
          return self::get($location);
        }
    
        curl_close($process);
    
        return $return;
      }
    
      static function _set_basic_options($process)
      {
    
        curl_setopt($process, CURLOPT_USERAGENT, self::$user_agent);
        curl_setopt($process, CURLOPT_COOKIEFILE, self::$cookie_file);
        curl_setopt($process, CURLOPT_COOKIEJAR, self::$cookie_file);
        curl_setopt($process, CURLOPT_RETURNTRANSFER, 1);
        // curl_setopt($process, CURLOPT_VERBOSE, 1);
        // curl_setopt($process, CURLOPT_SSL_VERIFYHOST, false);
        // curl_setopt($process, CURLOPT_SSL_VERIFYPEER, false);
      }
    
      static function _parse_redirection_header($url)
      {
        $process = curl_init($url);    
    
        self::_set_basic_options($process);
    
        // NOW we need to parse HTTP headers
        curl_setopt($process, CURLOPT_HEADER, 1);
    
        $return = curl_exec($process);
    
        if ($return === false)
        {
          throw new Exception('Curl error: ' . curl_error($process));
        }
    
        curl_close($process);
    
        if ( ! preg_match('#Location: (.*)#', $return, $location))
        {
          throw new Exception('No Location found');
        }
    
        if (self::$max_redirects-- <= 0)
        {
          throw new Exception('Max redirections reached trying to get: ' . $url);
        }
    
        return trim($location[1]);
      }
    
    }
    
  6. ==============================

    6.당신이 사용할 수있는:

    당신이 사용할 수있는:

    $redirectURL = curl_getinfo($ch,CURLINFO_REDIRECT_URL);
    
  7. from https://stackoverflow.com/questions/3519939/how-can-i-find-where-i-will-be-redirected-using-curl by cc-by-sa and MIT license