সিআরএল ব্যবহার করে যেখানে আমাকে পুনঃনির্দেশিত করা হবে সেখানে কীভাবে খুঁজে পাব?


149

আমি কার্লটিকে একটি পুনর্নির্দেশ অনুসরণ করার চেষ্টা করছি তবে আমি এটি সঠিকভাবে কাজ করতে পারি না। আমার কাছে একটি স্ট্রিং রয়েছে যা আমি একটি সার্ভারে জিইটি পরম হিসাবে প্রেরণ করতে এবং ফলাফল প্রাপ্ত URL পেতে চাই।

উদাহরণ:

স্ট্রিং = কোবোল্ড ভার্মিন
url = www.wowhead.com/search?q= কোবোল্ড + ওয়ার্কার

আপনি যদি সেই url এ যান তবে এটি আপনাকে "www.wowhead.com/npc=257" এ পুনর্নির্দেশ করবে। আমি এই ইউআরএলটি আমার পিএইচপি কোডে ফিরিয়ে আনতে চাই যাতে আমি "এনপিসি = 257" বের করতে পারি এবং এটি ব্যবহার করতে পারি।

বর্তমান কোড:

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 না ।

আমার সন্দেহ হয় বাহ্যিক পুনর্নির্দেশের আগে পিএইচপি ফিরে আসবে। আমি এটা কিভাবে ঠিক করবো?


8
এটি "কার্ল অনুসরণ পুনর্নির্দেশগুলি" এর শীর্ষ প্রশ্নের মধ্যে একটি। curlকমান্ডটি ব্যবহার করে পুনঃনির্দেশগুলি স্বয়ংক্রিয়ভাবে অনুসরণ করতে -Lবা --locationপতাকাটি পাস করুন । উদাহরণস্বরূপcurl -L http://example.com/
রব ডব্লু

উত্তর:


256

সিআরএলকে পুনর্নির্দেশের অনুসরণ করতে, ব্যবহার করুন:

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

এরম ... আমি মনে করি না আপনি আসলে কার্ল চালাচ্ছেন ... চেষ্টা করুন:

curl_exec($ch);

... বিকল্পগুলি সেট করার পরে এবং curl_getinfo()কল করার আগে ।

সম্পাদনা: আপনি যদি কোনও পৃষ্ঠায় কোথায় পুনঃনির্দেশিত হন তা সন্ধান করতে চাইলে আমি এখানে পরামর্শটি ব্যবহার করতাম এবং কেবল শিরোনামগুলি দখল করতে এবং কার্লটি ব্যবহার করে অবস্থানটি বের করতে: সেগুলি থেকে শিরোনাম:

$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
এটি পিএইচপি পুনঃনির্দেশ অনুসরণ করে। আমি পুনঃনির্দেশটি অনুসরণ করতে চাই না, আমি কেবল পুনঃনির্দেশিত পৃষ্ঠার url জানতে চাই।
টমাস ভ্যান নফল

9
ওহ, সুতরাং আপনি আসলে পৃষ্ঠাটি আনতে চান না? শুধু লোকেশন সন্ধান করবেন? সেক্ষেত্রে, আমি এখানে ব্যবহৃত কৌশলটি পরামর্শ দেব: zzz.rezo.net/HowTo-Expand-Short- URLs.html - মূলত কেবল পৃষ্ঠাটি যা পুনর্নির্দেশ করে তা হ্যান্ডারটি ধরে ফেলুন এবং অবস্থান: এটি থেকে শিরোনামটি দখল করুন। যে কোনও উপায়ে, যদিও, কার্লকে আসলে কিছু করার জন্য আপনার এখনও এক্সিকিউট () করতে হবে ...
ম্যাট গিবসন

1
আমি নীচে লুকা ক্যামিলোস সমাধানটি একবার দেখার পরামর্শ দিই, কারণ এই সমাধানটি একাধিক পুনঃনির্দেশকে বিবেচনায় নেয় না।
খ্রিস্টান এঙ্গেল

এই সমাধানটি একই url এর মধ্যে নতুন ওয়েবপৃষ্ঠাটি খুলবে। আমি সেই ইউআরএলটিতে প্যারামিটারগুলি পোস্ট করার সাথে সাথে ইউআরএলও পরিবর্তন করতে চাই। আমি কীভাবে এটি অর্জন করতে পারি?
আমানপুরোহিত

@ ম্যাটগিবসন যখন আমি $ httpCode = curl_getinfo ($ হ্যান্ডেল, CURLINFO_HTTP_CODE) ব্যবহার করি; সিআরএলএপপিএফএলএলওএকপিএল দিয়ে ঠিক কী কোডপোস্ট হবে তা সেট করে। আমি বোঝাতে চাইছি এটি কি প্রথম url এর জন্য হবে বা পুনর্নির্দেশ করা ইউআরএলটির জন্য হবে
মণিগ্যান্ড অর্জুনান

26

ইনিশিয়ালাইজেশন কার্ল করতে এই লাইনটি যুক্ত করুন

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);

2
আমি মনে করি এটি সর্বোত্তম সমাধান, কারণ এটি একাধিক পুনঃনির্দেশগুলিও উদ্ঘাটন করে।
খ্রিস্টান এঙ্গেল

মনে রাখবেন: (ঠিক আছে, ডু) পুনর্নির্দেশের পরে পোস্ট ডেটা পুনরায় জমা দেওয়া হবে না। আমার ক্ষেত্রে এটি ঘটেছিল এবং পরে আমি বোকা বোধ করি কারণ: কেবলমাত্র উপযুক্ত ইউআরএল ব্যবহার করুন এবং এটি স্থির হয়ে গেছে।
twojr

ব্যবহার curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);করা একটি সুরক্ষা দুর্বলতা। এটি মূলত বলেছে "এসএসএল ত্রুটিগুলি যদি এটি ভেঙে যায় তবে তা উপেক্ষা করুন - আপনি যেমন একটি এনক্রিপ্ট না করা URL তেমন বিশ্বাস করুন” "
দুরত্ব 2

8

উপরের উত্তরটি আমার কোনও সার্ভারে কাজ করে না, ভিত্তির সাথে কিছু করার জন্য, তাই আমি এটি আবার সামান্য পুনরায় হ্যাশ করেছি। নীচের কোডটি আমার সমস্ত সার্ভারে কাজ করে।

$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;

Location: হেডার সবসময় একটি পুনঃচালনা অনুসরণ করতে নয়। এছাড়াও দয়া করে একটি প্রশ্ন যা স্পষ্টভাবে এটি দেখুন: curl অনুসরণ করুন লোকেশন ত্রুটি
hakre

5

এখানে নির্বাচিত উত্তরটি শালীন তবে এর ক্ষেত্রে সংবেদনশীল, আপেক্ষিক location:শিরোলেখগুলি (যা কিছু সাইটগুলি করে) বা যে পৃষ্ঠাগুলিতে Location:তাদের সামগ্রীতে বাক্যাংশ থাকতে পারে ... (যা বর্তমানে জিলো করে) রক্ষা করে না।

কিছুটা opিলে ,ালা, তবে এটি কিছুটা চৌকস করার জন্য একটি দম্পতি দ্রুত সম্পাদনাগুলি হ'ল:

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

কখনও কখনও আপনার এইচটিটিপি শিরোনাম পাওয়া প্রয়োজন তবে একই সময়ে আপনি এই শিরোনামগুলি ফিরে আসতে চান না * **

এই কঙ্কাল পুনরাবৃত্তি ব্যবহার করে কুকিজ এবং এইচটিটিপি পুনর্নির্দেশগুলির যত্ন নেয়। এখানে মূল ধারণাটি হল ক্লায়েন্ট কোডটিতে 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]);
  }

}

0

লোটের এখানে রিজেক্সের সত্যতা সত্ত্বেও আমি তাদের সত্যই পছন্দ করি এইভাবে আমার পক্ষে আরও স্থিতিশীল হতে পারে:

$resultCurl=curl_exec($curl); //get curl result
//Optional line if you want to store the http status code
$headerHttpCode=curl_getinfo($curl,CURLINFO_HTTP_CODE);

//let's use dom and xpath
$dom = new \DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($resultCurl, LIBXML_HTML_NODEFDTD);
libxml_use_internal_errors(false);
$xpath = new \DOMXPath($dom);
$head=$xpath->query("/html/body/p/a/@href");

$newUrl=$head[0]->nodeValue;

অবস্থানের অংশটি হ'ল এইচটিএমএলের একটি লিঙ্ক যা অ্যাপাচে পাঠিয়েছে। সুতরাং এক্সপাথ এটি পুনরুদ্ধার করার জন্য নিখুঁত।


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.