Как мне получить абсолютный путь для '<img src =''>' в узле из response.body

Поэтому я хочу использовать запрос-обещание, чтобы вытащить тело страницы. Получив страницу, я хочу собрать все теги и получить массив src для этих изображений. Предположим, что атрибуты src на странице имеют как относительные, так и абсолютные пути. Я хочу массив абсолютных путей для imgs на странице. Я знаю, что могу использовать некоторые манипуляции со строками и путь npm, чтобы построить абсолютный путь, но я хотел найти лучший способ сделать это.

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');
        }
   });
});

Результаты

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

4 ответа

Решение

Чтобы получить массив ссылок на изображения в вашем сценарии, вы можете использовать url.resolve разрешить относительный src атрибуты img теги с URL-адресом запроса, в результате чего получается абсолютный URL-адрес. Массив передается в финал then; Вы можете делать другие вещи с массивом, кроме console.log если так хочется.

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);

это url.resolve будет работать для абсолютных или относительных URL-адресов (он разрешает и возвращает объединенный абсолютный URL-адрес при преобразовании из URL-адреса вашего запроса в относительный путь, но при преобразовании из URL-адреса вашего запроса в абсолютный URL-адрес просто возвращает абсолютный URL-адрес). Например, с img теги на Google с /logos/cat.gif а также https://test.com/dog.gif как src атрибуты, это вывело бы:

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

Сохраните URL своей страницы как переменную url.resolve соединить части вместе. В узле REPL это работает как для относительных, так и для абсолютных путей (отсюда и "разрешение"):

$:~/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'

Ваш код изменится на что-то вроде:

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');
        }
   });
});

Похоже, вы используете JQuery, так что вы могли бы

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

Если вы используете src это расширит относительные пути к абсолютным.

Это 2022 год, и url.resolve устарел.

Вот как я это делаю (работает как для «href», так и для img «src»):

      import URI from 'urijs'

function absolutizeUri(maybeRelativeUri: string, baseUri: string): string {
    if (!maybeRelativeUri || maybeRelativeUri.length === 0) {
        return ''
    }
    let uri = new URI(maybeRelativeUri);
    if (uri.is('relative')) {
        uri = ur.absoluteTo(baseUri)
    }
    return uri.toString()
}

// ...
const baseUri = 'http://www.google.com'
const src = absolutizeUri($(this).attr('src'), baseUri)
Другие вопросы по тегам