Descargar Paginas Web Usando PHP – cURL – file_get_contents

 Via: www.forosdelweb.com/wiki/PHP:_file_get_contents(),_cURL,_HTTP_Request

En ForosDelWeb he encontrado varias maneras de descargar paginas web utilizando PHP.


Definiciones

Introducción

Hay varias maneras de mostrar un URL remoto en PHP. La elección de un método sobre otro depende de las necesidades de su simplicidad, control y portabilidad. Los tres métodos que vamos a describir son:

  • Las funciones estandares de "filesystem"
  • La extensión cURL
  • La clase de PEAR HTTP_Request.

Estos tres métodos pueden generalmente hacer todo lo que necesita y por lo menos uno de ellos deben estar disponibles, sea cual sea su configuración del servidor o capacidad de instalar las extensiones personalizadas. Otras formas de recuperar las URL remotas incluye la extesión pecl_http (http://pecl.php.net/package/pecl_http), que, aunque todavía en desarrollo, ofrece algunas características prometedoras, y utilizando el fsockopen() para abrir un zócalo sobre el que envía una petición HTTP que lo construye pieza por pieza.

El uso de las funciones estandares de "filesystem" como la funciónfile_get_contents() es simple y conveniente. Sigue automaticamente las redirecciones, así que si utiliza esta función para recuperar el directoriohttp://www.example.com/persona/ y el servidor le redirecciona ahttp://www.example.com/people/, obtendrá el contenido de la página de índice de directorio, no un mensaje que le diga que la URL ha cambiado de dirección. El inconveniente de este método es que requiere la directiva de configuraciónallow_url_fopen a estar activado.

La extensión CURL es una poderosa herramienta. Se basa en el popular libcurl para proporcionar un rápido, configurable mecanismo para el manejo de una amplia variedad de peticiones de red. Si esta extensión está disponible en su servidor, le recomendamos que la utilice.

Si se desactiva allow_url_fopen y cURL no está disponible, el módulo PEARHTTP_Request salva el día. Al igual que todos los módulos de PEAR, es puro PHP, por lo que si puede guardar un archivo PHP en su servidor, puede utilizarlo.HTTP_Request soporta casi cualquier cosa que te gustaría hacer cuando se solicite una URL remota, incluyendo la modificación de cabeceras de petición y el cuerpo, utilizando un método arbitrario, respuesta y recuperación de los encabezados. Para mas informacion sobre como instalar los modulo de PEAR puedes ir ahttp://pear.php.net/manual/en/installation.getting.php

Para recibir información de URL seguras, solo escribe https en vez de http. Siempre y cuando en PHP haya sido construido en una libreria SSL, tal como OpenSSL. Todas las funciones que pueden recibir información de URL regulares pueden recibir información de URL seguras. Verifica la sección de OpenSSL en la salida de phpinfo() para ver si tu configuración de php tiene soporte de SSL.

Ejemplos

Obteniendo una URL

file_get_contents()

 

<?php
$page = file_get_contents('http://www.example.com/algo.txt');
echo $page;

cURL

 

<?php
$c = curl_init('http://www.example.com/algo.txt');
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
$page = curl_exec($c);
curl_close($c);
echo $page;

HTTP_Request

 

<?php
require_once 'HTTP/Request.php';
$r = new HTTP_Request('http://www.example.com/algo.txt');
$r->sendRequest();
$page = $r->getResponseBody();
echo $page;

 

Mostrar una página protegida

file_get_contents()

 

<?php
$url = 'http://FDW:[email protected]/proyecto.php';
$page = file_get_contents($url);
echo $page;

cURL

 

<?php
$c = curl_init('http://www.example.com/proyecto.php');
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_USERPWD, 'FDW:PASS');
$page = curl_exec($c);
curl_close($c);
echo $page;

HTTP_Request

 

<?php
$r = new HTTP_Request('http://www.example.com/proyecto.php');
$r->setBasicAuth('FDW','PASS');
$r->sendRequest();
$page = $r->getResponseBody();
echo $page;

 

Usar el metodo de POST

Enviar por el método de POST requiere de manejo especial en cada argumento. Con el método de GET, estos argumentos están en la cadena de consulta, pero en un POST van en la solicitud cuerpo. Además, la solicitud necesita una cabecera Content-Length que le dice al servidor el tamaño del contenido a esperar en la solicitud cuerpo.

Mostrar una dirección URL con el método de POST en vez del metdo de GET es bien útil cuando la cadena es muy larga, más de 200 caracteres aproximadamente. La especificación de HTTP 1.1 en el RFC 2616 no impone una longitud máxima en las URL, por lo que el comportamiento varía entre las diferentes web y servidores proxy. Si al mostrar las URL con GET y recibes resultados inesperados o resultados con el código de estado 414 ( "Request-URI Too Long"), convierte la solicitud al método de POST.

file_get_contents()

 

<?php
$url = 'http://www.example.com/submit.php';
$body = 'FDW=programacion&PHP=f18';
$options = array('method' => 'POST', 'content' => $body);
$context = stream_context_create(array('http' => $options));
$page = file_get_contents($url, false, $context);
echo $page;

cURL

 

<?php
$url = 'http://www.example.com/submit.php';
$body = 'FDW=programacion&PHP=f18';
$c = curl_init($url);
curl_setopt($c, CURLOPT_POST, true);
curl_setopt($c, CURLOPT_POSTFIELDS, $body);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
$page = curl_exec($c);
curl_close($c);
echo $page;

HTTP_Request

 

<?php
require 'HTTP/Request.php';
$url = 'http://www.example.com/submit.php';
$r = new HTTP_Request($url);
$r->setMethod(HTTP_REQUEST_METHOD_POST);
$r->addPostData('FDW','programacion');
$r->addPostData('PHP','f18');
$r->sendRequest();
$page = $r->getResponseBody();
echo $page;

 

Enviar cookies

Las cookies se envían al servidor en el encabezado de solicitud de cookies. La extensión cURL tiene una opción específica en cookies, pero con HTTP_Request, tienes que agregar el encabezado de cookies al igual que con otras cabeceras de petición. Los valores de Cookie múltiples se envían en una lista delimitada por coma. En los ejemplos vamos a enviar dos cookies: una con el nombre de user y con el valor FDW y otra con el nombre de actividad y con el valor de programacion.

file_get_contents()

 

<?php
$options = array('http' =>
    array(
        'method'  => 'GET',
        'header'  => 'Content-type: text/plain;charset=UTF-8\r\n'.
        'Referer: http://www.forosdelweb.com\r\n'.
        'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6\r\n'.
        'Cookie: user=FDW; actividad=programacion;\r\n'
    )
);
$context = stream_context_create($options);
$page = file_get_contents('http://www.example.com/enviar-cookies.php', false, $context);
echo $page;

cURL

 

<?php
$c = curl_init('http://www.example.com/enviar-cookies.php');
curl_setopt($c, CURLOPT_COOKIE, 'user=FDW; actividad=programacion');
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
$page = curl_exec($c);
curl_close($c);
echo $page;

HTTP_Request

 

<?php
require 'HTTP/Request.php';
$r = new HTTP_Request('http://www.example.com/enviar-cookies.php');
$r->addHeader('Cookie','user=FDW; actividad=programacion');
$r->sendRequest();
$page = $r->getResponseBody();
echo $page;

 

Seguir redireccionamientos

file_get_contents()

Nota: El file_get_contents() sigue automáticamente las redirecciones (header("Location: redireccion.php")).

<?php
$url = 'http://www.example.com/redireccionar.php';
$page = file_get_contents($url);
echo $page;

cURL

 

<?php
$c = curl_init('http://www.example.com/redireccionar.php');
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_FOLLOWLOCATION, true);
$page = curl_exec($c);
curl_close($c);
echo $page;

HTTP_Client

Nota: HTTP_request no sigue las redirecciones, pero el módulo de PEAR HTTP_Client logra lo que queremos

<?php
$url = 'http://www.example.com/redireccionar.php';
require_once 'HTTP/Client.php';
$client = new HTTP_Client();
$client->get($url);
$page = $client->currentResponse();
echo $page['body'];

 

No seguir redirecciones

Como hemos indicado anteriormente el file_get_contents() sigue automáticamente las redirecciones (header("Location: redireccion.php")). A partir de PHP 5.0.0, file_get_contents() y fopen() nos da unas opciones especificas acerca de como obtener el stream. En PHP 5.1.0 y posteriores, una de esas opciones esmax_redirects el número máximo de redirecciones a seguir. Si indicamos el max_redirects a 0 o 1, solo hace una solicitud.

El max_redirects realmente no indica el número de redirecciones deben seguirse, pero el número máximo de solicitudes que deben efectuarse en el momento siguiente a la cadena de redireccionamiento. Es decir, un valor de 1 le dice a PHP que al menos una solicitud debe seguir, y no un redireccionamiento. Un valor de 2 le dice a PHP para que al menos de 2 solicitudes deben seguir y no más de 1 redireccionamiento. Un valor de 0, sin embargo, se comporta como un valor de 1, PHP hace sólo 1 solicitud.

file_get_contents()

 

<?php
$url = 'http://www.example.com/redireccionar.php';
$options = array('max_redirects' => 1 );
$context = stream_context_create(array('http' => $options));
$page = file_get_contents($url, false, $context);
echo $page; 

cURL

Nota: Para no seguir las redirecciones no uses CURLOPT_FOLLOWLOCATION

<?php
$c = curl_init('http://www.example.com/redireccionar.php');
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
$page = curl_exec($c);
curl_close($c);
echo $page;

HTTP_Request

Nota: HTTP_Request no sigue redirecciones

<?php
require_once 'HTTP/Request.php';
$r = new HTTP_Request('http://www.example.com/redireccionar.php');
$r->sendRequest();
$page = $r->getResponseBody();
echo $page;

 

Configurar tiempo limite

Si quieres obtener una URL remota, pero no quieres esperar demasiado tiempo si el servidor remoto está ocupado o lento.

file_get_contents()

Nota: Estableceremos el tiempo limite a 15 segundos

<?php
ini_set('default_socket_timeout', 15);
$page = file_get_contents('http://slow.example.com/');

cURL

Nota: Estableceremos el tiempo limite a 15 segundos

<?php
$c = curl_init('http://slow.example.com/');
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 15);
$page = curl_exec($c);
curl_close($c);
echo $page;

HTTP_Request

Nota: Estableceremos el tiempo limite a 15 segundos

<?php
require_once 'HTTP/Request.php';
$opts = array('timeout' => 15);
$r = new HTTP_Request('http://slow.example.com/', $opts);
$page = $r->sendRequest();
echo $page;

 

Configurar el tiempo de leer

Si dependes de un servicio remoto, puede estar funcionando y en marcha, pero no estara en condiciones de manejar sus pedidos debido a problemas de red entre tu servidor y el servidor remoto. Limitar la cantidad de tiempo que espera de PHP para conectar a un servidor remoto es una buena idea, si se utilizan datos procedentes de fuentes remotas que sea parte del proceso de construcción de la página.

Todas las técnicas que describiremos limita la cantidad de tiempo de espera de PHP para conectar a un servidor remoto. Si estas realmente preocupado por las respuestas rápidas, adicionalmente configura el límite de cuánto tiempo PHP espera recibir los datos de los zócalos conectados. Para una conexión stream, utilice la función de [B]stream_set_timeout()[/B]. Para esta función necesitas abrir un stream con [B]fopen()[/B] y no con [B]file_get_contents()[/B]. En los ejemplo limitaremos el tiempo de leer a 20 segundos.

Aunque el establecimiento de conexión y los tiempos de lectura puede mejorar el rendimiento, también puede dar lugar a respuestas ilegibles. La secuencia de comandos puede leer sólo una respuesta parcial ante un tiempo de expiración. Si ha establecido los tiempos, asegúrese de validar toda la respuesta que ha recibido. Por otra parte, en situaciones en las que la generación de la página rápido es fundamental, puedes recuperar los datos externos en un proceso separado y escribir a una memoria caché local. De esta forma, sus páginas pueden usar el caché, sin temor a límites de tiempo o respuestas parciales.

fopen()

 

<?php
$url = 'http://slow.example.com';
$stream = fopen($url, 'r');
stream_set_timeout($stream, 20);
$page = stream_get_contents($stream);
fclose($stream);
echo $page;

cURL

 

<?php
$c = curl_init('http://slow.example.com/');
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 15);
curl_setopt($c, CURLOPT_TIMEOUT, 20);
$page = curl_exec($c);
curl_close($c);
echo $page;

HTTP_Request

 

<?php
require_once 'HTTP/Request.php';
$opts = array('readTimeout' => array(20,0));
$r = new HTTP_Request('http://slow.example.com/', $opts);
$page = $r->sendRequest();
echo $page;

 

Otro método para incluir las variables y valores en la consulta

Haciendo uso de http_build_query() puedes mostrar una página incluyendo las variables con sus respectivos valores en la consulta. Se acepta una serie de clave/valor en pares y devuelve una única cadena con todo escapado correctamente. Tu eres responsable del símbolo de ? en el URL para establecer la consulta.

file_get_contents

 

<?php
$vars = array('FDW' => 4, 'Programación' => 'PHP & f18');
$qs = http_build_query($vars);
$url = 'http://www.example.com/search.php?' . $qs;
$page = file_get_contents($url);

 

Bajar archivos

file_get_contents

 

<?php
$url = "http://www.example.com/zip.zip";
$g=basename($url);
$content = file_get_contents($url);
file_put_contents($g,$content);

cURL

 

<?php
$url = 'http://www.example.com/hola.zip'; 
 
$g=basename($url); 
 
if(!is_file($g)){
    $fp=fopen ($g, "w");
 
    $ch=curl_init($url);
    curl_setopt ($ch,CURLOPT_FILE, $fp);
    curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,60);
    curl_exec ($ch);
    curl_close ($ch);
 
    fclose($fp); 
}

 

Subir archivos

cURL

 

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://example.com/send_file.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
// lo mismo que <input type="file" name="nombre_del_input" />
$post = array(
    "nombre_del_input"=>"@C:/directorio/hacia/el/archivo.jpg",
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post); 
$page = curl_exec($ch);

Descargar Paginas Web Usando PHP – cURL – file_get_contents
0 votes, 0.00 avg. rating (0% score)

About this entry