
Thomas Van Nuffel
Ich versuche, Curl dazu zu bringen, einer Umleitung zu folgen, aber ich kann es nicht richtig zum Laufen bringen. Ich habe eine Zeichenfolge, die ich als GET-Parameter an einen Server senden und die resultierende URL erhalten möchte.
Beispiel:
Zeichenkette = Kobold Ungeziefer
URL = www.wowhead.com/search?q=Kobold+Arbeiter
Wenn Sie zu dieser URL gehen, werden Sie zu “www.wowhead.com/npc=257” weitergeleitet. Ich möchte, dass Curl diese URL an meinen PHP-Code zurückgibt, damit ich „npc=257“ extrahieren und verwenden kann.
Aktueller Code:
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);
}
Dies kehrt jedoch zurück www.wowhead.com/search?q=Kobold+Arbeiter und nicht www.wowhead.com/npc=257.
Ich vermute, dass PHP zurückkehrt, bevor die externe Umleitung erfolgt. Wie kann ich das beheben?

Matt Gibson
Um cURL einer Umleitung folgen zu lassen, verwenden Sie:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
Ähm … Ich glaube nicht, dass Sie den Curl tatsächlich ausführen … Versuchen Sie:
curl_exec($ch);
…nach dem Einstellen der Optionen und vor dem curl_getinfo()
Anruf.
BEARBEITEN: Wenn Sie nur herausfinden möchten, wohin eine Seite weiterleitet, würde ich den Rat verwenden Hierund verwenden Sie einfach Curl, um die Header zu greifen und den Header Location: daraus zu extrahieren:
$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]);
}

Luca Camillo
Fügen Sie diese Zeile zur Curl-Initialisierung hinzu
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
und verwenden Sie getinfo vor curl_close
$redirectURL = curl_getinfo($ch,CURLINFO_EFFECTIVE_URL );
es:
$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_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);

GR1NN3R
Die obige Antwort hat bei mir auf einem meiner Server nicht funktioniert, etwas mit basedir, also habe ich sie ein wenig neu gehasht. Der folgende Code funktioniert auf allen meinen Servern.
$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;
Die hier gewählte Antwort ist anständig, aber ihre Groß- und Kleinschreibung schützt nicht vor relativ location:
Kopfzeilen (was einige Websites tun) oder Seiten, die tatsächlich die Phrase enthalten könnten Location:
in ihrem Inhalt … (was zallow derzeit tut).
Ein bisschen schlampig, aber ein paar schnelle Änderungen, um dies ein bisschen intelligenter zu machen, sind:
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;
}
Beachten Sie, dass dies immer noch nur 1 Umleitung tief geht. Um tiefer zu gehen, müssen Sie tatsächlich den Inhalt abrufen und den Weiterleitungen folgen.

Igor Parra
Manchmal müssen Sie HTTP-Header abrufen, möchten diese Header aber nicht zurückgeben.**
Dieses Skelett kümmert sich mithilfe von Rekursion um Cookies und HTTP-Weiterleitungen. Die Hauptidee hier ist um HTTP-Header zurückzugeben zum Kundencode.
Sie können eine sehr starke Curl-Klasse darüber bauen. Hinzufügen von POST-Funktionen usw.
<?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]);
}
}

AC
Sie können Folgendes verwenden:
$redirectURL = curl_getinfo($ch,CURLINFO_REDIRECT_URL);

Patrick Valibus
Viele Regex hier, obwohl ich sie wirklich mag, könnten auf diese Weise stabiler für mich sein:
$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;
Der Standortteil ist ein Link im HTML, der von Apache gesendet wird. Xpath ist also perfekt, um es wiederherzustellen.
9889700cookie-checkWie finde ich heraus, wohin ich mit cURL in PHP weitergeleitet werde?yes
Dies ist eine der Top-Fragen für „Curl Follow Redirects“. Um Umleitungen automatisch zu folgen, verwenden Sie die
curl
Befehl, übergeben Sie die-L
oder--location
Flagge. Z.Bcurl -L http://example.com/
– Rob W
9. September 2013 um 19:09 Uhr