Как получить все шрифты, используемые на странице, используя node.js? - PullRequest
0 голосов
/ 02 мая 2018

Мне нужно сканировать все страницы на сайте (эта часть работает нормально), и поэтому мне нужно запустить THIS скрипт на моем сервере, используя node.js. Я попытался реализовать следующую логику:

var request = require('request');
var cheerio = require('cheerio');
var URL = require('url-parse');
var jsdom = require("jsdom");
var { JSDOM } = jsdom;

var START_URL = "http://balneol.com/";
var SEARCH_FONT = "helvetica";
var MAX_PAGES_TO_VISIT = 100000;

var pagesVisited = {};
var numPagesVisited = 0;
var pagesToVisit = [];
var url = new URL(START_URL);
var baseUrl = url.protocol + "//" + url.hostname;

pagesToVisit.push(START_URL);
crawl();

function crawl() {
  if(numPagesVisited >= MAX_PAGES_TO_VISIT) {
    console.log("Reached max limit of number of pages to visit.");
    return;
  }
  var nextPage = pagesToVisit.pop();
  if (nextPage in pagesVisited) {
    // We've already visited this page, so repeat the crawl
    crawl();
  } else {
    // New page we haven't visited
    visitPage(nextPage, crawl);
  }
}

function visitPage(url, callback) {
  // Add page to our set
  pagesVisited[url] = true;
  numPagesVisited++;

  // Make the request
  console.log("Visiting page " + url);
  request(url, function(error, response, body) {
     // Check status code (200 is HTTP OK)

     console.log("Status code: " + response.statusCode);
     if(response.statusCode !== 200) {
       callback();
       return;
     }
     // Parse the window.document body
    //  var window  = jsdom.jsdom(body).defaultView();

    var { window } = new JSDOM(body);

     //var $ = cheerio.load(body);
     var helveticaFound = searchForHelvetica(window, 'font-family');
     if(helveticaFound) {
       console.log('Word ' + SEARCH_FONT + ' found at page ' + url);
     } else {
       collectInternalLinks($);
       // In this short program, our callback is just calling crawl()
       // callback();
     }
  });
}

function searchForHelvetica( window , css) {

    if(typeof getComputedStyle == "undefined")
    getComputedStyle= function(elem){
        return elem.currentStyle;
    }
    var who, hoo, values= [], val,
    nodes= window.document.body.getElementsByTagName('*'),
    L= nodes.length;

    for(var i= 0; i<L; i++){
        who= nodes[i];

        console.log(nodes[i]);

        if(who.style){
            hoo= '#'+(who.id || who.nodeName+'('+i+')');

            console.log(who.style._values);

            // return false;

            val= who.style.fontFamily || getComputedStyle(who, '')[css];
            if(val){
                if(verbose) values.push([hoo, val]);
                else if(values.indexOf(val)== -1) values.push(val);
                // before IE9 you need to shim Array.indexOf (shown below)
            }
        }
    }

    // console.log(values);

    // return values;

}

function collectInternalLinks($) {
    var relativeLinks = $("a[href^='/']");
    console.log("Found " + relativeLinks.length + " relative links on page");
    relativeLinks.each(function() {
        pagesToVisit.push(baseUrl + $(this).attr('href'));
    });
}

Если вы увидите функцию моей страницы посещения, вы увидите две строки кода ниже:

var { window } = new JSDOM(body);
var helveticaFound = searchForHelvetica(window, 'font-family');

Как вы можете видеть во 2-й строке, я передаю объект window в функцию searchForHelvetic.

В моей функции searchForHelvetic, если я console.log(nodes[i]);, я не получаю html-элемент, и, следовательно, остальная часть сценария работает не совсем так, как ожидалось. отличается jsdom window от объекта window в браузере? как мне заставить скрипт работать? И.Е. в основном использовать объект окна, чтобы пройти через все страницы на странице и выложить все шрифты, используемые на странице?

EDIT :: - Чтобы разбить проблему до микроуровня, если я console.log(who); внутри searchForHelvetica функции, я получаю следующий результат:

HTMLElement {}
HTMLDivElement {}
HTMLDivElement {}
HTMLDivElement {}
HTMLAnchorElement {}
HTMLImageElement {}
HTMLDivElement {}
HTMLFormElement {}
HTMLDivElement {}
HTMLLabelElement {}
HTMLInputElement {}
HTMLButtonElement {}
HTMLButtonElement {}
HTMLSpanElement {}

и т.д ..

Но если бы я сделал то же самое в веб-браузере, результат был бы другим, например.

nodes = window.document.body.getElementsByTagName('*');
console.log(node[1]) // <div id="mobile-menu-box" class="hide">...</div>

Как получить аналогичный результат в node.js?

...