El uso de proxies
El uso de proxies para web scraping
Uno de los problemas comunes de scraping en un sitio con gran tamaño de datos es que su ip puede ser baneada o bloqueada por solicitar demasiadas paginas en poco tiempo, ya sea de forma automatica o por el administrador del servidor. Una manera de salir de esto es utilizar servidores proxy.
Un servidor proxy es un servidor que actua como intermediario para solicitudes de clientes en busca de recursos de otros servidores. El uso de servidores proxy permite a sus peticiones pasar por muchas direcciones ip diferentes y por lo tanto aparece ser que viene de diferentes lugares.
Existen muchos tipos de servidores proxy - tanto gratuitos como de paga. Proxies de paga son los mejores para trabajos de web scraping donde te estan pagando (trabajos serios), para servidores proxy gratis puede ver una lista aqui: http://www.freeproxylists.net/
Proxies con cURL
Suponiendo que haya reducido su lista de servidores proxy, tenemos que cargarla en una matriz para que podamos utilizarlo con cURL.
$proxies = array();
$proxies[] = '187.28.84.130';
$proxies[] = '190.0.58.58';
/* Algunas proxies usan puerto */
$proxies[] = '199.15.248.179:8089';
/* Algunas proxy requieren usuario y contraseña */
$proxies[] = 'user:password@121.9.214.133';
Si hay varios servidores proxy que figuran en la matriz, lo mejor es elegir al azar cada vez.
if (isset($proxies)) {
/* Seleccionamos una proxy aleatoria */
$proxy = $proxies[array_rand($proxies)];
}
Finalmente utilizamos el servidor proxy en nuestra sesion cURL.
$ch = curl_init('http://ejemplo.com');
if (isset($proxy)) {
curl_setopt($ch, CURLOPT_PROXY, $proxy);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$res = curl_exec($ch);
curl_close($ch);
A continuacion se muestra el codigo completo.
<?php
$proxies = array();
$proxies[] = '187.28.84.130';
$proxies[] = '190.0.58.58';
/* Algunas proxy usan numero de puerto */
$proxies[] = '199.15.248.179:8089';
/* Algunas proxy requieren usuario y contraseña */
$proxies[] = 'user:password@121.9.214.133';
if (isset($proxies))
{
/* Seleccionamos una proxy aleatoria */
$proxy = $proxies[array_rand($proxies)];
}
$ch = curl_init('http://ejemplo.com');
if (isset($proxy))
{
curl_setopt($ch, CURLOPT_PROXY, $proxy);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$res = curl_exec($ch);
curl_close($ch);
?>
Si la conexion falla, 'curl_exec' devuelve '0', asi que asegurese de comprobar con otro proxy. Sin embargo, puede suceder que ninguno de los servidores proxy son actualmente accesibles. Esto suele suceder cuando se utiliza proxy gratis. Asi que si usted tiene un proyecto de web scraping serio, me gustaria sugerirle el uso de proxies de paga que es fiable y que tenga soporte al cliente.
Por lo general encontramos que para los pequeños proyectos de web scraping no se requiere proxy si acabamos de escalonar las peticiones al servidor remoto, es decir, añadir un poco de retraso aleatorio entre sucesivas peticiones. Entonces para los pequeños proyectos, es mejor comprobar primero si las solicitudes trabajan bien y solo entonces utilizar un proxy.
Mostrando entradas con la etiqueta curl. Mostrar todas las entradas
Mostrando entradas con la etiqueta curl. Mostrar todas las entradas
lunes, 2 de febrero de 2015
domingo, 1 de febrero de 2015
[Parte 5] Web Scraping
Web scraping en paginas autenticadas
Sitios autenticados
Aunque la mayoria de los sitios webs no estan asegurados y puedan ser accedidos a traves de cURL, muchas de las mas importantes aseguran con diferentes maneras la autenticacion. Una de las maneras mas comunes para asegurar una pagina es utilizando autenticacion basica HTTP. Para acceder al contenido tenemos que autenticarnos por lo cual necesitamos utilizar la extension cURL de PHP. Pero antes de ello diremos unas pocas palabras acerca de la autenticacion basica HTTP.
Autenticacion basica HTTP
Autenticacion basica HTTP es una de las maneras mas faciles y mas rapidas para asegurar paginas web, ya que no requiere cookies, manejo de sesiones, o la creacion de paginas de inicio de sesion. En su lugar, la autenticacion basica HTTP utiliza encabezados HTTP estaticos, lo que significa que no hay handshakes (apretones de manos) necesarios entre clientes y servidores. Cada vez que se entre a la pagina el navegador solicitara una autenticacion basica HTTP. Los encabezados de la misma se muestran a continuacion.
HTTP/1.1 401 Access Denied
WWW-Authenticate: Basic realm="Mi Servidor"
Content-Length: 0
Esta solicitud debera ser enviada mediante HTTP 401 Not Authorized el codigo de respuesta contiene un encabezado WWW-Authenticate HTTP. La mayoria de los navegadores mostrara un cuadro de dialogo de inicio de sesion cuando recibe esta respuesta, lo que permite al usuario introducir un nombre de usuario y contraseña. Un ejemplo se muestra a continuacion. Cuando el user agent como navegador quiere enviar las credenciales de autenticacion al servidor, puede utilizar el encabezado de autorizacion. La cabecera de autorizacion se construye como sigue:
* Nombre de usuario y la contrase se combinan en una cadena "usuario:contraseña".
* La cadena resultante literal se codifica usando base64.
* El metodo authorization y un espacio es decir "Basic" se pone a continuacion, antes de la cadena codificada.
Por ejemplo, si el navegador utiliza "Patrick" como nombre de usuario y "thementalist" como contraseña y quiere acceder a algunos archivos de forma segura en el servidor ejemplo.com/archivosseguros/, las cabeceras enviadas por el navegador seran como el siguiente.
GET /archivosseguros/ HTTP/1.1
Host: www.ejemplo.com
Authorization: Basic UGF0cmljazp0aGVtZW50YWxpc3Q=
En PHP podemos codificar nombre de usuario y contraseña de cadena a base 64 utilizando el siguiente.
echo base64_encode('Patrick:thementalist');
Autentificacion basica HTTP con cURL
Ahora que estamos familiarizados con la autentificacion basica vamos a ver como podemos enviar la informacion de autentificacion utilizando cURL. El siguiente ejemplo nos permite acceder a un sitio con autenticacion basica HTTP utilizando cURL. Esto utiliza la opcion CURL_USERPWD para pasar el nombre de usuario y la contraseña para el servidor remoto para la autenticacion. Tenga en cuenta que cURL maneja todos los problemas de codificacion en base64 por nosotros. Solo tenemos que especificar las opciones adecuadas para cURL y se encarga del resto por nosotros. Las principales opciones en este ejemplo son CURLOPT_HTTPAUTH, CURLAUTH_BASIC.
<?php
$user = "admin";
$pass = "adminautenticacion";
$s = curl_init();
curl_setopt($s, CURLOPT_URL, 'http://ejemplo.com/index.php');
curl_setopt($s, CURLOPT_RETURNTRANSFER, true);
curl_setopt($s, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($s, CURLOPT_USERPWD, "$user:$pass");
curl_setopt($s, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$salida= curl_exec($s);
curl_close($s);
echo $salida;
?>
Incluso el tipo favorito de autenticacion, la autenticacion basica sin embargo esta perdiendo terreno a otras tecnicas debido a su debil naturaleza. Por ejemplo, con la autenticacion basica, no hay manera de cerrar sesion sin cerrar su navegador. Tampoco hay manera de cambiar el aspecto de la forma de autenticacion debido a que el navegador lo crea y el usuario no tiene control sobre eso. Es importante destacar que la autenticacion basica no es muy segura, ya que el navegador envia las credenciales de acceso al servidor en texto sin cifrar.
Almacenamiento y envio de cookies
La mayoria de los servidores despues de la autenticacion devuelven algo de informacion de la cookie que se requiere para trabajar correctamente con el resto del sitio una vez estamos con exito mas alla de la autenticacion. Necesitamos almacenar estos datos de las cookies en algun lugar para que podamos utilizarlo mas tarde con otras paginas. cURL hace que este trabajo sea mas facil para nosotros con la opcion CURLOPT_COOKIEJAR. Esta opcion tiene un nombre de archivo en el que la informacion de las cookies del sitio se almacenan; la hemos llamado "cookie.txt" en nuestro ejemplo a continuacion. A continuacion, podemos utilizar los datos de las cookies tarde como se requiere para trabajar con otras paginas.
<?php
$username = "admin";
$password = "adminautenticacion";
$s = curl_init();
curl_setopt($s, CURLOPT_URL, 'http://ejemplo.com/');
curl_setopt($s, CURLOPT_HEADER, 1);
curl_setopt($s, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($s, CURLOPT_USERPWD, "$username:$password");
curl_setopt($s, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($s, CURLOPT_TIMEOUT, 30);
curl_setopt($s, CURLOPT_RETURNTRANSFER, TRUE);
$page_data = curl_exec($s);
echo $page_data;
?>
Mas tarde, cuando queramos acceder a una pagina que require las cookies creadas anteriormente durante la autenticacion, podemos utilizar la opcion de curl CURLOPT_COOKIEFILE para cargar los datos de las cookies, que luego se envian al servidor cuando se solicita una pagina. A continuacion se da un ejemplo de codigo.
$s = curl_init();
curl_setopt($s, CURLOPT_URL, 'http://ejemplo.com/pagina2.php');
curl_setopt($s, CURLOPT_COOKIEFILE, 'cookie.txt');
curl_setopt($s, CURLOPT_TIMEOUT, 30);
curl_setopt($s, CURLOPT_RETURNTRANSFER, TRUE);
$page_data = curl_exec($s);
Ademas de la autenticacion HTTP basica, tambien existe la autenticacion estandar usuario/contraseña en un formulario, utilizado en la mayoria de los sitios. Los datos de autenticacion son normalmente enviados por metodo HTTP POST. En el siguiente ejemplo veremos como usar cURL para trabajar con este tipo de autenticaciones.
Autenticacion de sesion
A diferencia de la autenticacion basica, en las credenciales de acceso se envian cada vez que se solicita una pagina, la autenticacion de sesion valida a los usuarios una vez y crea un valor de sesion que representa la autenticacion. El formulario de inicio de sesion estandar usuario/contraseña utilizan autenticacion de sesion. Una vez que el usuario se autentica correctamente una sesion se crea con la ayuda de las cookies y los valores de sesion se pasan a cada peticion de la pagina posterior para indicar que el usuario es autenticado. Hay dos metodos basicos para el empleo de sesion de autenticacion con cookies y con cadenas de consulta. En el siguiente ejemplo vamos a ver como podemos usar cURL para iniciar sesion en un sitio de administracion de WordPress utilizando autenticacion de sesion.
Ingresando a un sitio de administracion WordPress con cURL
Actualmente WordPress es uno de los CMS mas instalados en el mundo, y hay millones de sitios que ejecutan esta plataforma versatil. El siguiente ejemplo muestra como se puede acceder a una seccion de administracion de WordPress remota utilizando cURL y agarrar cualquier contenido de interes. Por ejemplo si desea comprobar automaticamente los intervalos regulares del numero de comentarios publicados en su blog, puede utilizar el siguiente codigo para lograrlo. El siguiente ejemplo utiliza cURL para enviar los datos de acceso a su pagina de administracion de WordPress. Esto se logra mediante la opcion CURLOPT_POSTFIELDS junto con algunas otras opciones requeridas. Despues del inicio de sesion correcto WordPress devuelve un conjunto de cookies que se quedaran almacenadas en un archivo local utilizando CURLOPT_COOKIEJAR. Estos datos de cookies seran utilizados despues por nuestro codigo que solicito otras paginas de administracion.
<?php
$blog_url = "http://www.wordpress-blog.com/";
$blog_name = "wordpress-blog.com";
$username = "admin";
$password = "your-admin-password";
$post_data = "log={$username}&pwd={$password}&wp-submit=Acceder&redirect_to=http%3A%2F%2F{$blog_name}%2Fwp-admin%2F&testcookie=1";
$s = curl_init();
curl_setopt($s, CURLOPT_URL, $blog_url . 'wp-login.php');
curl_setopt($s, CURLOPT_TIMEOUT, 30);
curl_setopt($s, CURLOPT_POST, true);
curl_setopt($s, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($s, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($s, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($s, CURLOPT_COOKIEJAR, "cookie.txt");
curl_setopt($s, CURLOPT_RETURNTRANSFER, TRUE);
$downloaded_page = curl_exec($s);
?>
Una vez correctamente en la cuenta para admin, entonces podemos conseguir cualquier pagina de administracion requerida y raspar el contenido. Esto, sin embargo, sera necesario que establezcan las opciones correctas con cURL. El siguiente es otro ejemplo que se permitira el acceso a la administracion de WordPress y permitira obtener el contenido de la pagina para el enlace 'Todas las entradas'.
Un cambio importante a señalar aqui es la opcion CURLOPT_COOKIEFILE. Esto le permite continuar con la sesion cURL iniciada despues de inicio de sesion. cURL utiliza datos de la cookie de este archivo al mismo tiempo que solicita la nueva pagina.
/* Ahora que nosotros tenemos iniciada la sesion correctamente, podemos pedir la nueva pagina */
curl_setopt($s, CURLOPT_URL, $blog_url . 'wp-admin/edit.php');
curl_setopt($s, CURLOPT_COOKIEFILE, "cookie.txt");
$html = curl_exec($s);
/* $html ahora contiene los datos de la pagina ‘edit.php’ */
echo $html;
Una vez que tenemos el contenido de la pagina, podemos utilizar simplehtmldom para encontrar el elemento DOM relevante y devolver el numero total de comentarios. El recuento de los comentarios pendientes se almacena en el siguiente elemento span en el DOM. Tenga en cuenta que esto podria variar dependiendo de la version de WordPress, asi que asegurese de que esta comprobando el elemento de DOM correcto.
<span class="pending-count">6</span>
Ahora usamos el metodo "find" para obtener el recuento de comentario. Esto se logra mediante la siguiente linea. Devolvemos el primer nodo que se ajuste a los parametros de busqueda. Esto se especifica mediante el segundo parametro para 'find', '0' en nuestro ejemplo.
$data = @$html->find('span[class=pending-count]', 0);
Tambien podemos especificar el parametro de busqueda como a continuacion.
$data = $html->find('span.pending-count', 0);
Una vez encontrado el elemento relevante devolvemos los datos adecuados del objeto.
echo @$data->plaintext;
En el ejemplo anterior usted puede preguntarse como hemos llegado hasta los datos para la variable $post_data. La mejor manera es abrir el panel Firebug y enviar el formulario de WordPress. Ahora va conseguir todo el contenido solicitado en el panel de Firebug en la pestaña de red. Las urls mostradas en el panel seran tipicas de la administracion de WordPress despues del envio de formulario de inicio de sesion que se mostrara a continuacion. Se puede ver facilmente que los datos del formulario de inicio de sesion se han enviado en el archivo 'wp-login.php' utilizando el metodo POST. Tambien puede ver los detalles de POST y otras cabeceras haciendo clic en el enlace 'wp-login.php'. Una muestra parcial de lo capturado usando Firebug se mostrara a continuacion. El contenido de POST se muestra despues del campo 'Content-Length'. Solo tienes que copiar eso y reemplazar el nombre de usuario/contraseña correcta.
POST /wp-login.php HTTP/1.1
Host: www.ejemplo.com
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:16.0) Gecko/20100101 Firefox/16.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://www.ejemplo.com/wp-login.php
Cookie: __utma=101293715.944295703.1353556559; Content-Type: application/x-www\
-form-urlencoded
Content-Length: 102
log=admin&pwd=test&wp-submit=Acceder&redirect_to=http%3A%2F%ejemplo.com%2Fwp-ad\
min%2F&testcookie=1
HTTP/1.1 200 OK
Date: Fri, 08 Mar 2013 04:32:18 GMT
Server: Apache
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
Pragma: no-cache
x-frame-options: SAMEORIGIN
Set-Cookie: wordpress_test_cookie=WP+Cookie+check; path=/
Last-Modified: Fri, 08 Mar 2013 04:32:19 GMT
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
Con estos dos tipos de autenticacion debe ser capaz de obtener acceso a la mayoria de los sitios web. La otra arquitectura de autenticacion que necesitamos explorar es utilizar ajax para validar. Esto lo veremos mas adelante.
Sitios autenticados
Aunque la mayoria de los sitios webs no estan asegurados y puedan ser accedidos a traves de cURL, muchas de las mas importantes aseguran con diferentes maneras la autenticacion. Una de las maneras mas comunes para asegurar una pagina es utilizando autenticacion basica HTTP. Para acceder al contenido tenemos que autenticarnos por lo cual necesitamos utilizar la extension cURL de PHP. Pero antes de ello diremos unas pocas palabras acerca de la autenticacion basica HTTP.
Autenticacion basica HTTP
Autenticacion basica HTTP es una de las maneras mas faciles y mas rapidas para asegurar paginas web, ya que no requiere cookies, manejo de sesiones, o la creacion de paginas de inicio de sesion. En su lugar, la autenticacion basica HTTP utiliza encabezados HTTP estaticos, lo que significa que no hay handshakes (apretones de manos) necesarios entre clientes y servidores. Cada vez que se entre a la pagina el navegador solicitara una autenticacion basica HTTP. Los encabezados de la misma se muestran a continuacion.
HTTP/1.1 401 Access Denied
WWW-Authenticate: Basic realm="Mi Servidor"
Content-Length: 0
Esta solicitud debera ser enviada mediante HTTP 401 Not Authorized el codigo de respuesta contiene un encabezado WWW-Authenticate HTTP. La mayoria de los navegadores mostrara un cuadro de dialogo de inicio de sesion cuando recibe esta respuesta, lo que permite al usuario introducir un nombre de usuario y contraseña. Un ejemplo se muestra a continuacion. Cuando el user agent como navegador quiere enviar las credenciales de autenticacion al servidor, puede utilizar el encabezado de autorizacion. La cabecera de autorizacion se construye como sigue:
* Nombre de usuario y la contrase se combinan en una cadena "usuario:contraseña".
* La cadena resultante literal se codifica usando base64.
* El metodo authorization y un espacio es decir "Basic" se pone a continuacion, antes de la cadena codificada.
Por ejemplo, si el navegador utiliza "Patrick" como nombre de usuario y "thementalist" como contraseña y quiere acceder a algunos archivos de forma segura en el servidor ejemplo.com/archivosseguros/, las cabeceras enviadas por el navegador seran como el siguiente.
GET /archivosseguros/ HTTP/1.1
Host: www.ejemplo.com
Authorization: Basic UGF0cmljazp0aGVtZW50YWxpc3Q=
En PHP podemos codificar nombre de usuario y contraseña de cadena a base 64 utilizando el siguiente.
echo base64_encode('Patrick:thementalist');
Autentificacion basica HTTP con cURL
Ahora que estamos familiarizados con la autentificacion basica vamos a ver como podemos enviar la informacion de autentificacion utilizando cURL. El siguiente ejemplo nos permite acceder a un sitio con autenticacion basica HTTP utilizando cURL. Esto utiliza la opcion CURL_USERPWD para pasar el nombre de usuario y la contraseña para el servidor remoto para la autenticacion. Tenga en cuenta que cURL maneja todos los problemas de codificacion en base64 por nosotros. Solo tenemos que especificar las opciones adecuadas para cURL y se encarga del resto por nosotros. Las principales opciones en este ejemplo son CURLOPT_HTTPAUTH, CURLAUTH_BASIC.
<?php
$user = "admin";
$pass = "adminautenticacion";
$s = curl_init();
curl_setopt($s, CURLOPT_URL, 'http://ejemplo.com/index.php');
curl_setopt($s, CURLOPT_RETURNTRANSFER, true);
curl_setopt($s, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($s, CURLOPT_USERPWD, "$user:$pass");
curl_setopt($s, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$salida= curl_exec($s);
curl_close($s);
echo $salida;
?>
Incluso el tipo favorito de autenticacion, la autenticacion basica sin embargo esta perdiendo terreno a otras tecnicas debido a su debil naturaleza. Por ejemplo, con la autenticacion basica, no hay manera de cerrar sesion sin cerrar su navegador. Tampoco hay manera de cambiar el aspecto de la forma de autenticacion debido a que el navegador lo crea y el usuario no tiene control sobre eso. Es importante destacar que la autenticacion basica no es muy segura, ya que el navegador envia las credenciales de acceso al servidor en texto sin cifrar.
Almacenamiento y envio de cookies
La mayoria de los servidores despues de la autenticacion devuelven algo de informacion de la cookie que se requiere para trabajar correctamente con el resto del sitio una vez estamos con exito mas alla de la autenticacion. Necesitamos almacenar estos datos de las cookies en algun lugar para que podamos utilizarlo mas tarde con otras paginas. cURL hace que este trabajo sea mas facil para nosotros con la opcion CURLOPT_COOKIEJAR. Esta opcion tiene un nombre de archivo en el que la informacion de las cookies del sitio se almacenan; la hemos llamado "cookie.txt" en nuestro ejemplo a continuacion. A continuacion, podemos utilizar los datos de las cookies tarde como se requiere para trabajar con otras paginas.
<?php
$username = "admin";
$password = "adminautenticacion";
$s = curl_init();
curl_setopt($s, CURLOPT_URL, 'http://ejemplo.com/');
curl_setopt($s, CURLOPT_HEADER, 1);
curl_setopt($s, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($s, CURLOPT_USERPWD, "$username:$password");
curl_setopt($s, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($s, CURLOPT_TIMEOUT, 30);
curl_setopt($s, CURLOPT_RETURNTRANSFER, TRUE);
$page_data = curl_exec($s);
echo $page_data;
?>
Mas tarde, cuando queramos acceder a una pagina que require las cookies creadas anteriormente durante la autenticacion, podemos utilizar la opcion de curl CURLOPT_COOKIEFILE para cargar los datos de las cookies, que luego se envian al servidor cuando se solicita una pagina. A continuacion se da un ejemplo de codigo.
$s = curl_init();
curl_setopt($s, CURLOPT_URL, 'http://ejemplo.com/pagina2.php');
curl_setopt($s, CURLOPT_COOKIEFILE, 'cookie.txt');
curl_setopt($s, CURLOPT_TIMEOUT, 30);
curl_setopt($s, CURLOPT_RETURNTRANSFER, TRUE);
$page_data = curl_exec($s);
Ademas de la autenticacion HTTP basica, tambien existe la autenticacion estandar usuario/contraseña en un formulario, utilizado en la mayoria de los sitios. Los datos de autenticacion son normalmente enviados por metodo HTTP POST. En el siguiente ejemplo veremos como usar cURL para trabajar con este tipo de autenticaciones.
Autenticacion de sesion
A diferencia de la autenticacion basica, en las credenciales de acceso se envian cada vez que se solicita una pagina, la autenticacion de sesion valida a los usuarios una vez y crea un valor de sesion que representa la autenticacion. El formulario de inicio de sesion estandar usuario/contraseña utilizan autenticacion de sesion. Una vez que el usuario se autentica correctamente una sesion se crea con la ayuda de las cookies y los valores de sesion se pasan a cada peticion de la pagina posterior para indicar que el usuario es autenticado. Hay dos metodos basicos para el empleo de sesion de autenticacion con cookies y con cadenas de consulta. En el siguiente ejemplo vamos a ver como podemos usar cURL para iniciar sesion en un sitio de administracion de WordPress utilizando autenticacion de sesion.
Ingresando a un sitio de administracion WordPress con cURL
Actualmente WordPress es uno de los CMS mas instalados en el mundo, y hay millones de sitios que ejecutan esta plataforma versatil. El siguiente ejemplo muestra como se puede acceder a una seccion de administracion de WordPress remota utilizando cURL y agarrar cualquier contenido de interes. Por ejemplo si desea comprobar automaticamente los intervalos regulares del numero de comentarios publicados en su blog, puede utilizar el siguiente codigo para lograrlo. El siguiente ejemplo utiliza cURL para enviar los datos de acceso a su pagina de administracion de WordPress. Esto se logra mediante la opcion CURLOPT_POSTFIELDS junto con algunas otras opciones requeridas. Despues del inicio de sesion correcto WordPress devuelve un conjunto de cookies que se quedaran almacenadas en un archivo local utilizando CURLOPT_COOKIEJAR. Estos datos de cookies seran utilizados despues por nuestro codigo que solicito otras paginas de administracion.
<?php
$blog_url = "http://www.wordpress-blog.com/";
$blog_name = "wordpress-blog.com";
$username = "admin";
$password = "your-admin-password";
$post_data = "log={$username}&pwd={$password}&wp-submit=Acceder&redirect_to=http%3A%2F%2F{$blog_name}%2Fwp-admin%2F&testcookie=1";
$s = curl_init();
curl_setopt($s, CURLOPT_URL, $blog_url . 'wp-login.php');
curl_setopt($s, CURLOPT_TIMEOUT, 30);
curl_setopt($s, CURLOPT_POST, true);
curl_setopt($s, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($s, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($s, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($s, CURLOPT_COOKIEJAR, "cookie.txt");
curl_setopt($s, CURLOPT_RETURNTRANSFER, TRUE);
$downloaded_page = curl_exec($s);
?>
Una vez correctamente en la cuenta para admin, entonces podemos conseguir cualquier pagina de administracion requerida y raspar el contenido. Esto, sin embargo, sera necesario que establezcan las opciones correctas con cURL. El siguiente es otro ejemplo que se permitira el acceso a la administracion de WordPress y permitira obtener el contenido de la pagina para el enlace 'Todas las entradas'.
Un cambio importante a señalar aqui es la opcion CURLOPT_COOKIEFILE. Esto le permite continuar con la sesion cURL iniciada despues de inicio de sesion. cURL utiliza datos de la cookie de este archivo al mismo tiempo que solicita la nueva pagina.
/* Ahora que nosotros tenemos iniciada la sesion correctamente, podemos pedir la nueva pagina */
curl_setopt($s, CURLOPT_URL, $blog_url . 'wp-admin/edit.php');
curl_setopt($s, CURLOPT_COOKIEFILE, "cookie.txt");
$html = curl_exec($s);
/* $html ahora contiene los datos de la pagina ‘edit.php’ */
echo $html;
Una vez que tenemos el contenido de la pagina, podemos utilizar simplehtmldom para encontrar el elemento DOM relevante y devolver el numero total de comentarios. El recuento de los comentarios pendientes se almacena en el siguiente elemento span en el DOM. Tenga en cuenta que esto podria variar dependiendo de la version de WordPress, asi que asegurese de que esta comprobando el elemento de DOM correcto.
<span class="pending-count">6</span>
Ahora usamos el metodo "find" para obtener el recuento de comentario. Esto se logra mediante la siguiente linea. Devolvemos el primer nodo que se ajuste a los parametros de busqueda. Esto se especifica mediante el segundo parametro para 'find', '0' en nuestro ejemplo.
$data = @$html->find('span[class=pending-count]', 0);
Tambien podemos especificar el parametro de busqueda como a continuacion.
$data = $html->find('span.pending-count', 0);
Una vez encontrado el elemento relevante devolvemos los datos adecuados del objeto.
echo @$data->plaintext;
En el ejemplo anterior usted puede preguntarse como hemos llegado hasta los datos para la variable $post_data. La mejor manera es abrir el panel Firebug y enviar el formulario de WordPress. Ahora va conseguir todo el contenido solicitado en el panel de Firebug en la pestaña de red. Las urls mostradas en el panel seran tipicas de la administracion de WordPress despues del envio de formulario de inicio de sesion que se mostrara a continuacion. Se puede ver facilmente que los datos del formulario de inicio de sesion se han enviado en el archivo 'wp-login.php' utilizando el metodo POST. Tambien puede ver los detalles de POST y otras cabeceras haciendo clic en el enlace 'wp-login.php'. Una muestra parcial de lo capturado usando Firebug se mostrara a continuacion. El contenido de POST se muestra despues del campo 'Content-Length'. Solo tienes que copiar eso y reemplazar el nombre de usuario/contraseña correcta.
POST /wp-login.php HTTP/1.1
Host: www.ejemplo.com
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:16.0) Gecko/20100101 Firefox/16.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://www.ejemplo.com/wp-login.php
Cookie: __utma=101293715.944295703.1353556559; Content-Type: application/x-www\
-form-urlencoded
Content-Length: 102
log=admin&pwd=test&wp-submit=Acceder&redirect_to=http%3A%2F%ejemplo.com%2Fwp-ad\
min%2F&testcookie=1
HTTP/1.1 200 OK
Date: Fri, 08 Mar 2013 04:32:18 GMT
Server: Apache
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
Pragma: no-cache
x-frame-options: SAMEORIGIN
Set-Cookie: wordpress_test_cookie=WP+Cookie+check; path=/
Last-Modified: Fri, 08 Mar 2013 04:32:19 GMT
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
Con estos dos tipos de autenticacion debe ser capaz de obtener acceso a la mayoria de los sitios web. La otra arquitectura de autenticacion que necesitamos explorar es utilizar ajax para validar. Esto lo veremos mas adelante.
jueves, 1 de mayo de 2014
[Parte 5] CURL en PHP
Funciones interesantes
curl_multi_init
Una de las extensiones mas usadas en PHP es cURL, y es genial para devolver documentos remotos. Para situaciones donde necesitas devolver multiples documentos se usa curl_multi_init y curl_multi_exec trabajan mejor con multiples documentos.
La funcion curl_multi_exec es muy poderosa, pero en la documentacion de PHP la hacen ver mas dificil de lo que realmente es. Aqui una demostracion usando Google, Bing y Facebook todos devueltos:
$urls = array('http://www.google.com/', 'http://www.facebook.com/', 'http://www.bing.com/'); $url_count = count($urls); // cuenta el numero de urls $curl_array = array(); // creamos un array llamado curl_array $ch = curl_multi_init(); // iniciamos un multirecurso curl // para las urls hay una clave que contiene su url foreach($urls as $count => $url) {
$curl_array[$count] = curl_init($url); // establecemos la url en una sesion curl refiriendonos a cada 1 con su clave curl_setopt($curl_array[$count], CURLOPT_FOLLOWLOCATION, 1); // le damos una opcion de seguir el header location curl_setopt($curl_array[$count], CURLOPT_RETURNTRANSFER, 1); // devolvemos el contenido curl_multi_add_handle($ch, $curl_array[$count]); // añadimos a cada url con sus opciones en el multirecurso } // mientras se esten ejecutando las urls realiza lo siguiente do { curl_multi_exec($ch, $exec); } while($exec > 0);
En este ejemplo hay 3 urls establecidas para devolverse al mismo tiempo.
curl_multi_getcontent
Para leer el contenido de las peticiones que hicimos anteriormente podriamos usar la funcion curl_multi_getcontent. Vamos a ver como podemos hacerlo... (el codigo siguiente se puede añadir al anterior)://para cada url devolvemos el contenido junto con la url
foreach($urls as $count => $url) { $returned = curl_multi_getcontent($curl_array[$count]); echo "$url - $returned"; }
Cerrar el manejador de cURL
Algunos programadores prefieren usar curl_close() despues de haberlo usado. Usted en lugar de utilizar curl_close() deberia utilizar curl_multi_close(), y curl_multi_remove_handle() despues de que el contenido se haya devuelto. Veamos un ejemplo:
//para cada url eliminamos el manejador, cerramos la peticion multi recurso y cada peticion de una sesion curl la cerramos
foreach($urls as $count => $url) { curl_multi_remove_handle($ch, $curl_array[$count]); } curl_multi_close($ch); foreach($urls as $count => $url) { curl_close($curl_array[$count]); }
Como anteriormente dijimos el codigo anterior puede añadirse a lo que habiamos puesto antes... de esta manera todo el codigo quedaria asi:
<?php $urls = array('http://www.google.com/', 'http://www.facebook.com/', 'http://www.bing.com/'); $url_count = count($urls); $curl_array = array(); $ch = curl_multi_init(); foreach($urls as $count => $url) { $curl_array[$count] = curl_init($url); curl_setopt($curl_array[$count], CURLOPT_FOLLOWLOCATION, 1); curl_setopt($curl_array[$count], CURLOPT_RETURNTRANSFER, 1); curl_multi_add_handle($ch, $curl_array[$count]); } do { curl_multi_exec($ch, $exec); } while($exec > 0); foreach($urls as $count => $url) { $returned = curl_multi_getcontent($curl_array[$count]); echo "$url - $returned"; } foreach($urls as $count => $url) { curl_multi_remove_handle($ch, $curl_array[$count]); } curl_multi_close($ch); foreach($urls as $count => $url) { curl_close($curl_array[$count]); } ?>
Fuente: http://www.fusionswift.com/2011/08/php-curl_multi_exec-example/
curl_setopt_array()
Con esta funcion podemos configurar multiples opciones para una transferencia cURL. Veamos un ejemplo:
<?php // creamos un nuevo recurso curl $ch = curl_init(); // establecemos las opciones apropiadas para la url $options = array( CURLOPT_URL => 'http://www.google.com/', CURLOPT_FOLLOWLOCATION => true, CURLOPT_USERAGENT => 'Googlebot/2.1 (+http://www.google.com/bot.html)', CURLOPT_RETURNTRANSFER => true ); curl_setopt_array($ch, $options); $output = curl_exec($ch); curl_close($ch); echo $output; ?>
curl_getinfo()
Esta funcion obtiene informacion relativa a una transferencia especifica. Los valores que devuelve son los siguientes:
- "url"
- "content_type"
- "http_code"
- "header_size"
- "request_size"
- "filetime"
- "ssl_verify_result"
- "redirect_count"
- "total_time"
- "namelookup_time"
- "connect_time"
- "pretransfer_time"
- "size_upload"
- "size_download"
- "speed_download"
- "speed_upload"
- "download_content_length"
- "upload_content_length"
- "starttransfer_time"
- "redirect_time"
- "certinfo"
- "request_header"
curl_version()
Obtiene la informacion de la version de cURLcURL File
Como veíamos en la parte 4 de curl, subiamos un archivo con el uso de @, pero apartir de PHP 5.5.0 ese prefijo esta obsoleto, por lo que se recomienda utilizar esta funcion.CURLFile::__Construct--curl_file_create - Crea un objeto CURLFile
Estilo orientado a objetos:
public CURLFile::__construct ( string$filename
[, string$mimetype
[, string$postname
]] )
Estilo orientado a procedimientos:
CURLFile curl_file_create ( string$filename
[, string$mimetype
[, string$postname
]] )
Crea un objeto CurlFile, utilizado para transferir (upload) un fichero con CURLOPT_POSTFIELDS.
filename - indica la ruta de acceso al fichero a ser transferido
mimetype - Tipo mime del fichero
postname - nombre del fichero
Ejemplo, estilo orientado a objetos:
<?php /* http://example.com/upload.php: <?php var_dump($_FILES); ?> */ // Crea un gestor cURL $ch = curl_init('http://example.com/upload.php'); // Crea un objeto CURLFile $cfile = new CURLFile('cats.jpg','image/jpeg','test_name'); // Asigna los datos POST $data = array('test_file' => $cfile); curl_setopt($ch, CURLOPT_POST,1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // Ejecuta el gestor curl_exec($ch); ?>
Estilo por procedimientos:
<?php /* http://example.com/upload.php: <?php var_dump($_FILES); ?> */ // Crea un gestor cURL $ch = curl_init('http://example.com/upload.php'); // Crea un objeto CURLFile $cfile = curl_file_create('cats.jpg','image/jpeg','test_name'); // Asigna los datos POST $data = array('test_file' => $cfile); curl_setopt($ch, CURLOPT_POST,1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // Ejecuta el gestor curl_exec($ch); ?>
Usar cURL con Expresiones regulares
Como en ejemplos anteriores usabamos la funcion preg_match y preg_match_all para ver si se encontraba determinado texto o link para poder mostrar el resultado que necesitabamos, para mas informacion sobre expresiones regulares por favor consulte:http://www.arthusu.com.mx/2013/07/phpexpresiones-regulares-pcre.html
Como en el ejemplo de subidas de archivos en la parte 4 de curl, veíamos un upload con el cual sacábamos los links usando expresiones regulares:
<?php set_time_limit(0); $url = "http://www0.xup.in/exec/xupload.php?uid=&key="; $user_agent = "Mozilla/5.0 (Windows NT 6.1; rv:28.0) Gecko/20100101 Firefox/28.0"; $referer = "http://www.xup.in/"; $directory=dirname(__FILE__).'\files/'; if(isset($_FILES['f1'])){ move_uploaded_file($_FILES['f1']['tmp_name'],"files/".$_FILES['f1']['name']); $ch = curl_init(); curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); curl_setopt($ch, CURLOPT_REFERER, $referer); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POSTFIELDS, array("F1"=>"@".$directory.$_FILES['f1']['name'])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); $result = curl_exec($ch); if(curl_errno($ch)) { echo 'Curl error: ' . curl_error($ch); } curl_close($ch); unlink($directory.$_FILES['f1']['name']); //echo $result; preg_match_all('/<input type="text" name="t1" size="90" class="inp" value="(.*?)" onclick="highlight\(this\);" \/>/', $result, $matches); //echo '<p><img src="'.$matches[1][0].'" alt="img" /></p>'; echo '<p><b>Link: <a href="'.$matches[1][0].'" target="_blank">Archive Link</a></p>'; //print_r($matches); }else{ echo ' <form action="upload_curl.php" method="post" enctype="multipart/form-data"> <label for="f1">Filename:</label> <input type="file" name="f1" id="f1"><br> <input type="submit" name="submit" value="Submit"> </form> '; } ?>
sábado, 19 de abril de 2014
[Parte 3] CURL en PHP
Cookies
El medio por el cual los navegadores web hacen "client side state control (control del estado del lado del cliente)" es por medio de cookies. Las cookies solo son nombres asociadas con contenido. Las cookies son enviadas desde el cliente al servidor. El servidor llama al cliente para saber que ruta y hostname quiere el cliente, devolviendoles asi una fecha de expiracion y unas propiedades mas.Cuando el cliente se comunica con el servidor con el nombre y ruta previamente especificado y recibido en la cookie, el cliente envia de regreso las cookies y su contenido para el servidor, a menos que claro estas hayan expirado.
Muchas aplicaciones y servidores usan este metodo para conectar una serie de peticiones dentro de una sola sesion. Para ser capaces de usar curl en tales ocasiones, nosotros deberiamos ser capaces de guardar y enviar de regreso las cookies a la aplicacion web.
Esto es muy importante para script en cURL para verificacion de inicios de sesion o paginas con una seccion segura en el sitio web. Estas son 3 cosas que requerimos implementar:
1.- La ruta del archivo para la cookie en tu servidor:
<?php $cookie_file_path = "C:/xampp/htdocs/cookie/cook"; // Este archivo debe tener permisos chmod 777 (leer / escribir) ?>
2.- Las funciones cURL:
<?php curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path); // el nombre del archivo contiene los datos de la cookie. La cookie puede ser en formato netscape, o solo texto plano http-style con las cabeceras puestas dentro del archivo curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path); // el nombre del archivo guarda todas las cookies internas para cuando la conexion cierra. ?>
Por favor realice lo siguiente:
1.- Suba este archivo prueba.php a su servidor con el siguiente codigo:
<?php print realpath('prueba.php'); ?>
2.- Accede al archivo tuhost.com/prueba.php y copia la ruta que arroja, en este ejemplo:
/home/a8131XXX/public_html/prueba.php
3.- Crea un archivo .txt y ponle de nombre cookie.txt y subelo a tu servidor
4- Dale permisos CHMOD 777. En windows no es necesario realizar esto.
5.- Ahora simplemente formas una cadena con lo que salio en el paso 2 y con el archivo del paso 3, quedando de la siguiente forma:
/home/a8131XXX/public_html/cookie.txt
<?php // ejemplo 8 $user = "tusuario"; $pass = "tucontraseña"; $url = "https://www.facebook.com/login.php"; $post_fields = 'lsd=AVolpnen&email='.$user.'&pass='.$pass.'&default_persistent=0&timezone=360&lgnrnd=222458_oW23&lgnjs=1397971500&locale=es_LA'; $referer = "https://www.facebook.com/login.php"; $agent = "Mozilla/5.0 (Windows NT 6.1; rv:28.0) Gecko/20100101 Firefox/28.0"; $cookie_file_path = "C:/xampp/htdocs/cookie.txt"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_USERAGENT, $agent); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_REFERER, $referer); curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path); curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path); $result = curl_exec($ch); curl_close($ch); echo $result; ?>
CURLOPT_COOKIEFILE - Nombre del fichero que contiene datos de las cookies. El fichero de las cookies puede estar en formato Netscape, o simplemente tipo HTTP plano dentro de un fichero. Si el nombre es una cadena vacia, no se cargaran cookies, aunque el manejo de cookies aun esta habilitado.
CURLOPT_COOKIEJAR - Nombre del fichero donde guardar cookies internas cuando se cierra se cierra, por ejemplo: despues de llamar a curl_close().
HTTPS (SSL)
Hay varias formas de realizar transferencias HTTP seguras. A lo lejos el protocolo mas comun que realiza esto es conocido como HTTPS, HTTP encima de SSL. SSL encripta todos los datos que son enviados y recibidos atraves de la red, asi hace mas dificil que los atacantes espien la informacion sensitiva.SSL (o TLS como la ultima version del estandar es llamada) ofrece un camino para caracteristicas avanzadas para permitir estas encriptaciones y claves de mecanismos de infraestructura para encriptar HTTP como es requerido.
cURL soporta recuperaciones encriptadas gracias a las librerias OpenSSL.
En el ejemplo anterior de la peticion con cURL a facebook, usamos esto que eran las opciones CURLOPT_SSL_VERIFYPEER y CURLOPT_SSL_VERIFYHOST.
CURLOPT_SSL_VERIFYPEER - FALSE para que cURL no verifique el PEER del certificado. Para usar diferentes certificados para la verificacion se puede especificar con la opcion CURLOPT_CAINFO o se puede especificar el directorio donde se encuentra el certificado con la opcion CURLOPT_CAPATH. TRUE por omision desde cURL 7.10. Paquete instalado por defecto en la version de CURL 7.10.
CURLOPT_SSL_VERIFYHOST - 1 para comprobar que existe un nombre comun en el peer del certificado SSL. 2 para comprobar que existe un nombre comun y tambien para verificar que el hostname coincide con el proporcionado. En entornos de produccion el valor de esta opcion debe de mantenerse en 2 (valor por omision).
Depuracion
Muchas veces cuando corremos curl en un sitio, tienes un aviso de que el sitio no se muestra, para responder de la misma forma las peticiones curl tu debes hacer como el navegador.Entonces tu necesitas empezar a crear tus peticiones mas similar a tus peticiones del navegador:
- Estar seguro que checa las cookies cuando son necesarias
- Establecer User-Agent de los navegadores mas actuales y populares
- Establecer el Referer como esta establecido en el navegador
- Si contiene datos POST, debes acomodarlos de la misma manera que lo hace el navegador.
CURLOPT_HEADER - TRUE para incluir el header (encabezado) en la salida
CURLOPT_VERBOSE - TRUE para mostrar informacion verbose. Escribe la salida en STDERR, o el fichero especificado usando CURLOPT_STDERR.
[Parte 2] CURL en PHP
Formularios
Los formularios son generalmente presentados como campos donde el usuario puede meter datos, y al presionar Ok o Submit estos son enviados al servidor para ser procesados. El servidor procesa datos tipicamente como por ejemplo: una busqueda a la base de datos, un inicio de sesion, etc.GET y POST
En el metodo GET todos los campos se ven mostrados en la URL. Esto generalmente suele ser una ventaja para sistemas de modulacion, pero una desventaja en si, ya que muchos atacantes lo primero que verifican es este tipo de URLs. El protocolo HTTP ofrecere otro metodo que es POST el cual envia los campos ocultos separados de la URL los cuales son enviados por las cabeceras HTTP.Una buena practica seria enviar en una pagina donde los datos son enviados por el metodo POST y darle nuestros valores... En el metodo post se usa el content-type: application/x-www-form-urlencoded por lo cual es necesario encodear a urlencode nuestros datos que vamos a enviar, por ejemplo: si tiene un espacio pondriamos %20, pero para no hacerlo tan pesado podriamos hacer uso de la funcion urlencode().
Vamos a ver como ejemplo la API de anonscanner que me paso ZanGetsu:
<?php /* AnonScanner.com API sample PHP code. You must edit the $uid, $api_key and $file variables to make this work. */ $url = "https://anonscanner.com/api.php"; $uid = "YOUR_USER_ID"; //Your user id, from the home page. $api_key = "YOUR_API_KEY"; //Your API key from the home page. $file = $_FILES['file']; $ch = curl_init(); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_VERBOSE, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, true); $post = array( "uid" => $uid, "api_key" => $api_key, "file" => "@".$_SERVER['DOCUMENT_ROOT']."/".$file, "return" => "link" //"link", "image" or "all". Leave empty for default(all). ); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); $response = curl_exec($ch); $response = json_decode($response,true); print_r($response); //JSON output ?>
En este caso esta pequeña API lo que hace es devolvernos los resultados de los antivirus, para ello envia un archivo por medio de POST, nuestro iud, nuestra api,y el modo en que devolveremos los resultados.
Lo unico nuevo y que voy a explicar aqui es CURLOPT_POST, CURLOPT_POSTFIELDS.
CURLOPT_POST - TRUE para hacer un HTTP POST normal. Este post del tipo application/x-www-form-urlencoded, el mas comun en los formularios HTML.
CURLOPT_POSTFIELDS - Todos los datos para enviar via HTTP "POST". Para enviar un fichero, prefija el nombre de fichero con @ y utiliza la ruta completa. Se puede especificar explicitamente el tipo de fichero añadiendo el tipo al nombre del fichero, en el formato ';type=mimetype'. Se puede enviar una cadena urlencoded como 'para1=val1¶2=val2&...' o tambien como un array con el nombre del campo como key y los datos como value. Si value es un array, el encabezado Content-Type sera definido como multipart/form-data. Apartir de PHP 5.2.0, value debe ser un array si los archivos son pasados a esta con la opcion con el prefijo @. Apartir de PHP 5.5.0, el prefijo @ esta obsoleto, por lo que los ficheros se pueden enviar usando CURLFile.
Nota: Para los campos ocultos de un formulario podemos usar lo mismo, solamente que como estos no se ven nosotros tendriamos que aplicarlos.
Descagar una imagen (Archivo Binario)
Tu puedes descargar archivos como imagenes, pdfs, psd, docs, zip usando curl. Google usa esta tecnica para mostrar sus imagenes.<?php // Ejemplo 3 $url = "http://most-security.com/foro/image.php?u=138&dateline=1397283113"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); // URL para descargar la imagen curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // devuelve el contenido curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; rv:28.0) Gecko/20100101 Firefox/28.0"); // especificamos el navegador que usamos curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); // retorna esta transferencia, como contenido binario $data = curl_exec($ch); // graba la imagen jpg y lo guarda en la variable $data curl_close($ch); // cierra el recurso, y libera memoria del sistema header("Content-type: image/jpeg"); // le indicamos en la cabecera lo que se muestra contiene imagenes echo $data; // muestra el contenido ?>
Autentificacion
La autentificacion es capaz de verificar si tienes permiso a acceder a un recurso. La autentificacion basica usada en HTTP es basada en texto plano es decir usuario y contraseña ligeramente ofuscados, pero puede ser leido si te olfatean la red.Para usar la autenticacion en una caja de dialogo, que nos pide usuario y contraseña:
<?php // Ejemplo 4 $url = "http://tuhost.com/sinacceso/"; $post_fields = 'arthusu:test'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); // URL para descargar la imagen curl_setopt($ch, CURLOPT_USERPWD, $post_fields); // la caja de dialogo curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // devuelve el contenido $results = curl_exec($ch); // graba la imagen jpg y lo guarda en la variable $data curl_close($ch); // cierra el recurso, y libera memoria del sistema echo $results; ?>
CURLOPT_USERPWD - Nombre de usuario y contraseña siguiendo el formato "[username]:[password]" para ser usado en la conexion.
Referer
Muchas paginas chequean desde donde llega el cliente, mas que nada que pagina anterior uso, para llegar a la suya, esto puede ser muy util para muchas cosas, pero esto se puede engañar facilmente modificando la cabecera 'referer'.<?php // ejemplo 5 $url = "http://tuhost.com/logsasd/"; // URL $referer = "http://www.mirasoyunsitiofalso.com/"; // Sitio referido $ch = curl_init(); // inicia una sesion curl curl_setopt($ch, CURLOPT_URL, $url); // pasa la url como parametro curl_setopt($ch, CURLOPT_REFERER, $referer); // establece el sitio referido curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // devuelve el contenido de la pagina $result = curl_exec($ch); // graba la url pasada y la mete en la variable result curl_close($ch); // cierra la url, y libera recursos del sistema echo $result; // muestra el contenido de la pagina ?>
User Agent
La cabecera User-Agent contiene datos importantes como son el navegador que esta usando el cliente y su sistema operativo, tambien indica si esta entrando desde un dispositivo Ipad, Iphone, etc.Muchas paginas dejan entrar al Bot de google solo por que ven su cabecera, una buena practica que podriamos hacer es intentar entrar a varias paginas con acceso restringido en algunas zonas y ver como con el User-Agent de google tenemos mas privilegios.
O simplemente, si intentas hacer una peticion most-security por medio de cURL te arrojara cloudflare con un error detectando que estas usando cURL por lo cual puedes usar esta cabecera User-Agent evitando que te salga ese error.
<?php // ejemplo 6 $url = "http://tuhost.com/logsasd/"; // es la url que veremos $agent = " Googlebot/2.1 (+http://www.google.com/bot.html)"; // es el navegador que usaremos $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); // inicia una sesion curl curl_setopt($ch, CURLOPT_USERAGENT, $agent); // establece el navegador curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // devuelve el contenido de la pagina $result = curl_exec($ch); // guarda el contenido de la pagina en $result curl_close($ch); // cierra la sesion curl echo $result; // muestra la pagina ?>
Redirecciones
Cuando pides una pagina web, muchas veces te envia un mensaje de error 301 el cual dice que el objeto se ha movido, esto pasa que cuando tu lo pides con cURL no sigue el objeto que se movio, entonces para poder retornar o ver la pagina necesitamos seguir ese recurso...Este tipo de recursos se ven reflejados en la cabecera Location.
Esto nos pasa cuando no seguimos la cabecera Location en el caso de google y si lo activamos.
Siguiendo la cabecera Location.
<?php // ejemplo 7 $url = "http://www.google.com"; // es la url que veremos $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); // inicia una sesion curl curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // redirige a la pagina, en caso de un login te redirige a la pagina de entrada curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // devuelve el contenido de la pagina $result = curl_exec($ch); // guarda el contenido de la pagina en $result curl_close($ch); // cierra la sesion curl echo $result; // muestra la pagina ?>
Hasta aqui terminamos la parte 2.
viernes, 18 de abril de 2014
[Parte 1] CURL en PHP
Instalacion
Lo primero que debemos hacer para comenzar a utilizar cURL es instarlo, para ello puedes descargarlo desde: http://curl.haxx.se/La guia para la instalacion de cURL compilandolo esta aqui: http://curl.haxx.se/docs/install.html
En este caso no veremos en detalle esto ya que pues vienen los pasos muy detallados en la pagina de la documentacion de cURL, por lo cual veremos solamente como instarlo en la distribucion de ubuntu usando un solo comando:
Instalar cURL con un solo comando desde la terminal:
sudo apt-get install php5-curl
Reiniciar el servidor apache para que funcione cURL:
sudo /etc/init.d/apache2 restart
Como ves es demasiado facil, y de hecho ya existen muchos paquetes que te incluyen un servidor apache,mysql,php tal como puede ser XAMPP, AppServ... los cuales pueden descagar desde su web oficial y son faciles de instalar y casi siempre ya traen soporte para cURL:
XAMPP: https://www.apachefriends.org/es/index.html
AppServ: http://www.appservnetwork.com/?newlang=spanish
Para saber si nuestro servidor soporta cURL solamente creamos un archivo como el siguiente info.php:
<?php phpinfo(); ?>
Entramos al archivo y veremos algo como lo siguiente:
¿Que es cURL?
cURL es una herramienta para usar en un interprete de comandos para transferir archivos con sintaxis URL, soporta FTP, FTPS, HTTP, HTTPS, TFTP, SCP, Telnet, DICT, FILE, y LDAP. cURL soporta certificados HTTPS,HTTP POST, HTTP PUT,Subidas FTP, Kerberos, Subidas mediante formulario HTTP, proxies, cookies, autenticacion mediante usuario+contraseña (Basic, Digest, NTLM y Negotiate para HTTP y Kerberos4 para FTP), continuacion de transferencia de archivos, tunneling de proxy http y muchas otras prestaciones. cURL es opensource/software libre distribuido bajo la licencia MIT. El proposito y uso para cURL es automatizar transferencia de archivos o secuencia de operaciones no supervisadas. Es por ejemplo una buena herramienta para simular las acciones de un usuario en un navegador web. Libcurl es la biblioteca/API correspondiente que los usuarios pueden incorporar en sus programas, cURL actua como un envoltorio (wrapper) aislado para la biblioteca libcurl. libcurl se usa para proveer capacidades de transferencia de URL a numerosas aplicaciones, tanto libres y open source como asi tambien privativas. La biblioteca "libcurl" se puede usar desde mas de 30 lenguajes distintos.HTTP
Hypertext transfer protocol o http (en español protocolo de transferencia de hipertexto) es el protocolo usado en cada transaccion de la world wide web. Es un protocolo orientado a transacciones y sigue el esquema peticion-respuesta entre cliente y un servidor. Al cliente que efectua la peticion (un navegador o un spider) se conoce como "user-agent" (agente del usuario). A la informacion transmitida se le llama recurso y se la identifica mediante un localizador uniforme de recursos (URL). Los recursos pueden ser archivos, el resultado de la ejecucion de un programa, una consulta a una base de datos,la traduccion automatica de un documento, etc. HTTP es un protocolo sin estado, es decir, no guarda ninguna informacion sobre conexiones anteriores. El desarrollo de aplicaciones web necesita frecuentemente mantener el estado. Para eso se usan las cookies, que es informacion que un servidor puede almacenar en el sistema cliente. Esto permite a las aplicaciones web instruir la nocion de "sesion", y tambien permite rastrear usuarios ya que las cookies pueden guardarse en el cliente por tiempo indeterminado.Uso simple de cURL
La operacion mas comun es obtener una URL. Podriamos hacer referencia a una pagina, imagen o archivo. El cliente hace una peticion GET y recibe el documento que pidio.curl_init() - esta funcion inicializa una sesion cURL y retorna un manejador cURL.
curl_exec($ch) - esta funcion deberia ser llamada despues de inicializar una sesion cURL y todas las opciones establecidas en la sesion. Su proposito es simple, ejecutar la sesion CURL predefinida, dada por $ch.
curl_setopt($ch, opcion, valor) - establece una opcion para la sesion de CURL identificada por el parametro $ch, opcion especifica la opcion que se desea establecer, y valor especifica el valor dada la opcion.
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1) - Retorna el contenido de la pagina. Si se establece en 0 no se retornara ninguna salida.
curl_setopt($ch,CURLOPT_URL, $url) - Pasa la url como parametro. Este el el sitio objetivo la direccion url. Esta es la url que vas a obtener desde internet.
curl_exec($ch) - Graba la url y la pasa para la variable a mostrar.
curl_close($ch) - cierra un recurso curl, libera los recursos del sistema.
<?php // Ejemplo 1 // Obtener una pagina simple $url = "http://arthusu.com.mx/"; $ch = curl_init(); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // Retorna el contenido de la pagina curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // sigue las redirecciones curl_setopt($ch, CURLOPT_URL, $url); // Pasa la url como parametro $resultado = curl_exec($ch); // graba la url y la pasa para una variable curl_close($ch); // cierra el recurso y libera recursos para el sistema echo $resultado; // Imprime el contenido de la pagina ?>
Etiquetas:
curl,
definicion,
http,
instalacion,
parte1,
php
Suscribirse a:
Entradas (Atom)