¿Usar Puppeteer para seguir las redirecciones?

Desde hace tiempo necesito una herramienta o funcionalidad que dada una URL inicial me devuelva la última URL del conjunto de redirecciones.

En primera instancia lo había intentado con PHP, pero no funcionaba con las redirecciones JavaScript, así que me recomendaron usar un browser headless.

Me leí la documentación de PhantomJS, lo instalé y lo probé. Resulta que, según comentario de muchos y de pruebas mías, no funcionaba muy bien con las redirecciones así que ahora estoy probando Google Chrome sin cabeza, haciendo uso de Puppeteer.

Mi código actual es el siguiente:

const argv = require('minimist')(process.argv.slice(2)); var url = argv.url; const puppeteer = require('puppeteer'); (async () => {     const browser = await puppeteer.launch({args: ['--disable-setuid-sandbox', '--no-sandbox']});      const page = await browser.newPage();      await page.goto(url);      await page.waitForNavigation({waitUntil: 'load'});      console.log(page.url());      browser.close(); })(); 

Necesito ayuda con lo siguiente:

  • Parece que mi script espera indefinidamente la carga de la página, me gustaría limitarlo a cierto tiempo.

  • ¿Saben si existe una función que determine si la URL que se le está enviando es correcta? (Para evitar que salga un error al enviarle una URL incorrecta).

  • ¿Qué otras mejoras le harían?

Seguir una URL hasta la última y ejecutando código js

¿Qué necesito?

Necesito obtener la última URL, es decir, aquella que no redireccione habiendo pasado por N redirecciones previas (algunas de ellas realizadas por JS). En otras palabras, necesito desarrollar una función que dada una url vaya haciendo redirecciones y que mi código sea capaz de seguirlas independientemente si se hicieron desde apache, php, js u otros.

¿Qué he hecho?

He investigado un montón y he visto muchos ejemplos, sé que hay preguntas relacionadas pero ninguna que involucre javascript, por ende, no he podido solucionar mi problema en su totalidad, sólo parcialmente. ¿Por qué parcialmente? porque hay urls cuyas redirecciones no son hechas a través de javascript, por ende, el código que yo tengo funciona perfectamente con esas urls.

¿Qué código tengo?

    function get_final_url($  url, $  timeout = 5) {     //$  url = str_replace( "&", "&", urldecode(trim($  url)) );     $  cookie = tempnam ("/tmp", "CURLCOOKIE");     $  ch = curl_init();     curl_setopt( $  ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1" );     curl_setopt( $  ch, CURLOPT_URL, $  url );     curl_setopt( $  ch, CURLOPT_COOKIEJAR, $  cookie );     curl_setopt( $  ch, CURLOPT_FOLLOWLOCATION, true );     curl_setopt( $  ch, CURLOPT_ENCODING, "" );     curl_setopt( $  ch, CURLOPT_RETURNTRANSFER, true );     curl_setopt( $  ch, CURLOPT_AUTOREFERER, true );     curl_setopt( $  ch, CURLOPT_CONNECTTIMEOUT, $  timeout );     curl_setopt( $  ch, CURLOPT_TIMEOUT, $  timeout );     curl_setopt( $  ch, CURLOPT_MAXREDIRS, 10 );     $  content = curl_exec( $  ch );     $  response = curl_getinfo( $  ch );     curl_close ( $  ch );     if ($  response['http_code'] == 301 || $  response['http_code'] == 302)     {         ini_set("user_agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1");         $  headers = @get_headers($  response['url']);         if(!$  headers) return $  url;         $  location = "";         foreach($  headers as $  value)         {             if (substr(strtolower($  value), 0, 9) == "location:")                 return get_final_url( trim( substr( $  value, 9, strlen($  value) ) ) );         }     }     if(preg_match("/window\.location\.replace\('(.*)'\)/i", $  content, $  value) || preg_match("/window\.location\=\"(.*)\"/i", $  content, $  value))     {         return get_final_url($  value[1]);     }     else     {         return $  response['url'];     } }