lunes, diciembre 12, 2011

Copiar/duplicar una web con usuario y password en local con WGET

En ocasiones necesitamos crear una replica en local de una web. Bien porque va a dejar de estar activa, bien porque tenemos que usarla sin tener acceso a Internet. Una de las opciones podría ser guardar cada una de las páginas a mano, pero aparte de ser farragoso perdemos la capacidad de navegar entre páginas. Así que necesitamos una herramienta, que partiendo de una página, la recorra descargando todos los enlaces así como las páginas que dependan de ella. El comando wget, disponible en cualquier distribución de linux/unix y para el que existen versiones para windows, permite hacer eso mismo.

Duplicando una web
El comando más sencillo posible con wget para duplicar una página en nuestro ordenador es este:
$ wget -m -k http://www.example.com/
La opción -m (mirror) equivale a varias opciones pero esencialmente significa que recorra todos los enlaces dentro del dominio www.example.com y los descargue. La opción -k (convert links) transforma los enlaces (http) de la página para que apunten a los archivos locales y podamos navegar por la página sin acceder a Internet. Ojo, no convierte los enlaces hasta que no ha descargado todas las páginas.

Estableciendo límites y filtros
Rápidamente nos damos cuenta que hay que establecer unos límites o, en ocasiones, puede que estemos intentando descargar muchas más páginas de las que queremos. Poniendo el caso de un foro, en cada uno de los mensajes suele aparecer un enlace a "Responder", está claro que no interesa guardar cada una de las páginas "Responder" porque no aportan contenido y, sin embargo, multiplican el número de páginas a descargar.
Otro caso sería, que puede interesarnos descartar carpetas enteras del servidor, por ejemplo, imaginemos que dentro de www.example.com hay una carpeta www.example.com/help con un montón de archivos, enlaces e imágenes que no queremos guardar. Estaría bien filtrar todas los archivos que cuelguen de esa carpeta para reducir la cantidad de trabajo.
Una tercera razón para limitar los ficheros que se descargan de una página es que muchos servidores detectan como sospechosa la acción de descargar de forma rápida un montón de páginas, pudiendo bloquear el acceso desde nuestra dirección. Para evitarlo, además de limitar la cantidad de ficheros a descargar, es conveniente indicar un intervalo de espera entre cada solicitud de forma que no sobrecarguemos el servidor.
Bien modifiquemos el comando anterior con unos cuantos parámetros para añadir lo que acabamos de comentar.
$ wget -r -l 3 -nc -k -R "*reply*","*subscribe*" -X /help,/admin  -w 2 --random-wait http://www.example.com/
Describimos las nuevas opciones

  • -r -l 3 -nc: Vemos que hemos cambiado -m por este grupo de opciones, -r significa que debe recorrer las páginas recursivamente descargándolas todas, -l 3 que debe profundizar como máximo 3 niveles y -nc que no debe descargar una página si ya lo ha hecho previamente. La opción -l se puede ajustar dependiendo de la profundidad de copia que queremos o se puede prescindir de ella.
  • -R "*reply*","*subscribe*": significa que debe rechazar cualquier enlace que contenga las palabras reply o subscribe. Fijaos en el uso del símbolo "*" como comodín para el resto de cadena.
  •  -X /help,/admin: ignora cualquier enlace que esté bajo esos directorios. Funciona de forma similar a -R pero es mucho más efectivo y rápido.
  •  -w 2 --random-wait : -w 2 establece una pausa de 2 segundos entre cada descarga, --random-wait modifica en cada ocasión el intervalo de forma aleatoria (multiplica por un valor entre 0.5 y 1.5) para las peticiones no sean tan mecánicas, algo más similar a lo que sería un navegación "humana". Es más fácil que el servidor no nos limite el acceso si las peticiones tienen un comportamiento "normal".
Páginas privadas con usuario y password
Este sistema funciona de forma cómoda en páginas públicas en las que no es necesario identificarse. El problema es que en ocasiones queremos duplicar una web que necesite un usuario/password. Si intentasemos aplicar el comando anterior, obtendríamos algún mensaje del tipo "no está autorizado para acceder a esta página".
Suponiendo que tenemos este usuario/password hay varias formas combinarlos con wget para poder acceder a la información. Para mi este ha sido el método más sencillo.

  1. Usando el navegador Chrome, instala la extensión Kojiki que ayuda a usar wget.
  2. Accede a la página normalmente con tu usuario/password
  3. Una vez dentro, vas a la página desde la que queremos iniciar la copia, haz clic con el botón derecho del ratón y busca "Copy wget this page"
  4. Ahora tienes en el portapapeles el comando wget con la información de la cookie que estás usando en la página. La cookie guarda información sobre la sesión: nombre de usuario, id de la sesión... y permite al wget "hacerse pasar" por el navegador que ha abierto la sesión.
  5. Pega el comando en una terminal que tengas abierta y añade los parámetros que quieras. En el ejemplo vamos a usar las opciones anteriores añadiendo la cookie que nos han dado. Recuerda que la cookie es personal y distinta para cada página, persona y momento. El siguiente comando no lo puedes "copiar y pegar".
$wget -r -l 3 -nc -k -R "*reply*","*subscribe*" -X /help,/admin  -w 2 --random-wait --cookies=off --header "Cookie: __unam=617b174-132asdfasdfasdfd75-2e3fecea-9; __utma=44907040.106181225.1318317690.1318317690.1318317690.1; __utmz=44907040.1318317690.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic; settings-time-2=1320664165; wp-settings-time-4=1321952914; wp-settings-6=hidetb%3D1; wp-settings-time-6=1322140725; wp-settings-1=editor%3Dtinymce%26m0%3Do%26wplink%3D1%26hidetb%3D1%26imgsize%3Dfull%26align%3Dcenter; wp-settings-time-1=1322226356;  __utma=208883906.2022691319.1315818628.1323264640.1323680669.60; __utmb=208883906.2.10.1323680669; __utmc=208883906; __utmz=208883906.1319800966.18.7.utmcsr=192.168.0.254:81|utmccn=(referral)|utmcmd=referral|utmcct=/es/; " 'http://www.example.com/' --content-disposition


Haciendo sustituciones de cadenas en todos los archivos
Puede que una vez hayas descargado todos los archivos tengas problemas en la navegación por algún carácter. En mi caso no conseguía enlazar bien las páginas que contenían la cadena "....php?loquesea..." porque no era capaz de encontrar los archivos, había que sustituirlo por una cadena de escape "...php%3Floquesea...". Bien, existe otro comando llamado sed que sirve exactamente para eso, encontrar patrones dentro de un archivo y sustituirlos por otros. Combinándolo con los comandos find y xargs, recorro todos los archivos de la carpeta haciendo la sustitución de "php?" por "php%3F".
find carpeta_objetivo/ -type f | xargs sed -i 's/php?/php%3F/g'
En principio los tres comandos están disponibles en cualquier distribución de linux  pero existen versiones de todos para windows.

Cuestiones legales y de propiedad intelectual
Que algo sea técnicamente posible no significa que pueda hacerse. Aunque es muy posible que si tienes acceso a una página no haya problema en que la guardes deberías estar seguro de tienes autorización para copiarla. Algunos servicios podrían considerar que estás cometiendo un abuso y bloquearte indefinidamente. Utiliza estos comandos con responsabilidad.

No hay comentarios:

Publicar un comentario