2016-06-09 17 views
5

Quindi desidero utilizzare la richiesta-promessa per estrarre il corpo di una pagina. Una volta che ho la pagina voglio raccogliere tutti i tag e ottenere una matrice di src di quelle immagini. Supponiamo che gli attributi src su una pagina abbiano percorsi relativi e assoluti. Voglio una matrice di percorsi assoluti per imgs su una pagina. So che posso usare alcune string manipulation e il percorso npm per costruire il percorso assoluto ma volevo trovare un modo migliore di farlo.Come ottengo il percorso assoluto per "<img src=''>" nel nodo da un response.body

var rp = require('request-promise'), 
    cheerio = require('cheerio'); 

var options = { 
    uri: 'http://www.google.com', 
    method: 'GET', 
    resolveWithFullResponse: true 
}; 

rp(options) 
    .then (function (response) { 
    $ = cheerio.load(response.body); 
    var relativeLinks = $("img"); 
    relativeLinks.each(function() { 
     var link = $(this).attr('src'); 
     console.log(link); 
     if (link.startsWith('http')){ 
      console.log('abs'); 
     } 
     else { 
      console.log('rel'); 
     } 
    }); 
}); 

risultati

/logos/doodles/2016/phoebe-snetsingers-85th-birthday-5179281716019200-hp.gif 
    rel 
+0

Possibile duplicato [ricevendo il percorso assoluto di un ] (http://stackoverflow.com/questions/ 3496491/getting-the-absolute-path-of-a-img) – Midas

+0

@Midas Questa domanda è strettamente correlata, ma non del tutto un duplicato di quell'altra domanda a causa delle differenze di implementazione tra DOM e jQuery in quel caso, e Cheerio in questo caso. Fare qualcosa come $ (this) o $ ('img') [0] .src non restituirà nulla in Cheerio. – Michael

risposta

0

Per ottenere un array di link di immagine in lo scenario, è possibile utilizzare url.resolve per risolvere gli attributi relativi src dei tag img con l'URL della richiesta, ottenendo un URL assoluto. La matrice viene passata all'ultima then; puoi fare altre cose con l'array diverso da console.log se lo desideri.

var rp = require('request-promise'), 
    cheerio = require('cheerio'), 
    url = require('url'), 
    base = 'http://www.google.com'; 

var options = { 
    uri: base, 
    method: 'GET', 
    resolveWithFullResponse: true 
}; 

rp(options) 
    .then (function (response) { 
     var $ = cheerio.load(response.body); 

     return $('img').map(function() { 
      return url.resolve(base, $(this).attr('src')); 
     }).toArray(); 
    }) 
    .then(console.log); 

Questo url.resolve funzionerà per gli URL assoluti o relativi (si risolve e restituisce l'URL assoluto combinato durante la risoluzione dal tuo URL richiesta a un percorso relativo, ma quando la risoluzione dal tuo URL richiesta di un URL assoluto è restituisce solo l'URL assoluto). Ad esempio, con img tag su google con /logos/cat.gif e https://test.com/dog.gif come src attributi, questo sarebbe uscita:

[ 
    'http://www.google.com/logos/cat.gif', 
    'https://test.com/dog.gif' 
] 
0

Sembra che si sta utilizzando jQuery, così si potrebbe

$('img').each(function(i, e) { 
    console.log(e.src) 
}); 

Se si utilizza src si espanderà percorsi relativi a quelli assoluti.

+0

Corretto, ma 'src' non è un attributo jQuery. È standard Javascript. – Midas

+1

È un attributo DOM - non devi usare jQuery per _everything_ –

+0

Per essere un po 'pedante, sta usando Cheerio, che è un modulo NodeJS che usa la sintassi simile a jQuery per attraversare il DOM. Inoltre, in questo caso l'accesso all'attributo src non sarà di aiuto perché restituirà comunque un URL relativo alla radice (o qualsiasi cosa sia presente nel DOM) quando ha bisogno del percorso assoluto. – Michael

3

Memorizza l'URL della pagina come variabile utilizzando url.resolve per unire i pezzi. Nel nodo REPL questo funziona per entrambi i percorsi relativi e assoluti (da qui il "risolvere"):

$:~/Projects/test$ node 
> var base = "https://www.google.com"; 
undefined 
> var imageSrc = "/logos/doodles/2016/phoebe-snetsingers-85th-birthday-5179281716019200-hp.gif"; 
undefined 
> var url = require('url'); 
undefined 
> url.resolve(base, imageSrc); 
'https://www.google.com/logos/doodles/2016/phoebe-snetsingers-85th-birthday-5179281716019200-hp.gif' 
> imageSrc = base + imageSrc; 
'https://www.google.com/logos/doodles/2016/phoebe-snetsingers-85th-birthday-5179281716019200-hp.gif' 
> url.resolve(base, imageSrc); 
'https://www.google.com/logos/doodles/2016/phoebe-snetsingers-85th-birthday-5179281716019200-hp.gif' 

Il tuo codice sarebbe cambiato in qualcosa di simile:

var rp = require('request-promise'), 
    cheerio = require('cheerio'), 
    url = require('url'), 
    base = 'http://www.google.com'; 

var options = { 
    uri: base, 
    method: 'GET', 
    resolveWithFullResponse: true 
}; 

rp(options) 
    .then (function (response) { 
    $ = cheerio.load(response.body); 
    var relativeLinks = $("img"); 
    relativeLinks.each(function() { 
     var link = $(this).attr('src'); 
     var fullImagePath = url.resolve(base, link); // should be absolute 
     console.log(link); 
     if (link.startsWith('http')){ 
      console.log('abs'); 
     } 
     else { 
      console.log('rel'); 
     } 
    }); 
});