it-swarm.com.ru

Как проанализировать строку HTML в скрипте Google Apps без использования XmlService?

Я хочу создать скребок с помощью таблиц Google со скриптом Google Apps. Я знаю, что это возможно, и я видел некоторые учебники и темы об этом.

Основная идея заключается в использовании:

  var html = UrlFetchApp.fetch('http://en.wikipedia.org/wiki/Document_Object_Model').getContentText();
  var doc = XmlService.parse(html);

А затем получить и работать с элементами. Однако метод

XmlService.parse()

Не работает для какой-то страницы. Например, если я попробую:

function test(){
    var html = UrlFetchApp.fetch("https://www.nespresso.com/br/pt/product/maquina-de-cafe-espresso-pixie-clips-preto-lima-neon-c60-220v").getContentText();
    var parse = XmlService.parse(html);
}

Я получаю следующую ошибку:

Error on line 225: The entity name must immediately follow the '&' in the entity reference. (line 3, file "")

Я пытался использовать string.replace() для устранения символов, которые, по-видимому, вызывают ошибку, но это не работает. Все виды других ошибок появляются. Следующий код, например:

function test(){
    var html = UrlFetchApp.fetch("https://www.nespresso.com/br/pt/product/maquina-de-cafe-espresso-pixie-clips-preto-lima-neon-c60-220v").getContentText();
    var regExp = new RegExp("&", "gi");
    html = html.replace(regExp,"");

    var parse = XmlService.parse(html);
}

Дает мне следующую ошибку:

Error on line 358: The content of elements must consist of well-formed character data or markup. (line 6, file "")

Я считаю, что это проблема с методом XmlService.parse().

Я прочитал в этой теме:

таблица синтаксического анализа скрипта Google App из испорченного html и как лучше всего анализировать html в скрипте приложений Google что можно использовать устаревший метод xml.parse(), который принимает второй параметр, который позволяет анализировать HTML. Однако, как я уже упоминал, это устарело, и я нигде не могу найти никакой документации по нему. xml.parse(), кажется, анализирует строку, но у меня возникают проблемы при работе с элементами из-за отсутствия документации. И это также не самое безопасное долгосрочное решение, потому что оно может быть деактивировано в ближайшее время.

Итак, я хочу знать, как мне разобрать этот HTML в скрипте Google Apps?

Я также попробовал:

function test(){

    var html = UrlFetchApp.fetch("https://www.nespresso.com/br/pt/product/maquina-de-cafe-espresso-pixie-clips-preto-lima-neon-c60-220v").getContentText();
    var htmlOutput = HtmlService.createHtmlOutput(html).getContent();

    var parse = XmlService.parse(htmlOutput);
}

Но это не работает, я получаю эту ошибку:

Неверно сформированный контент HTML:

Я думал об использовании библиотеки с открытым исходным кодом для анализа HTML, но я не смог найти ни одной.

Моя конечная цель состоит в том, чтобы получить некоторую информацию из набора страниц, таких как цена, ссылка, название продуктов и т.д. Мне удалось сделать это с помощью серии RegEx:

var ss = SpreadsheetApp.getActiveSpreadsheet();
  var linksSheet = ss.getSheetByName("Links");
  var resultadosSheet = ss.getSheetByName("Resultados");

function scrapyLoco(){

  var links = linksSheet.getRange(1, 1, linksSheet.getLastRow(), 1).getValues();
  var arrayGrandao = [];
  for (var row =  0, len = links.length; row < len; row++){
   var link = links[row];


   var arrayDeResultados = pegarAsCoisas(link[0]);
   Logger.log(arrayDeResultados);
   arrayGrandao.Push(arrayDeResultados);
  }   


  resultadosSheet.getRange(2, 1, arrayGrandao.length, arrayGrandao[0].length).setValues(arrayGrandao);

}


function pegarAsCoisas(linkDoProduto) {
  var resultadoArray = [];

  var html = UrlFetchApp.fetch(linkDoProduto).getContentText();
  var regExp = new RegExp("<h1([^]*)h1>", "gi");
  var h1Html = regExp.exec(html);
  var h1Parse = XmlService.parse(h1Html[0]);
  var h1Output = h1Parse.getRootElement().getText();
  h1Output = h1Output.replace(/(\r\n|\n|\r|(^( )*))/gm,"");

  regExp = new RegExp("Ref.: ([^(])*", "gi");
  var codeHtml = regExp.exec(html);
  var codeOutput = codeHtml[0].replace("Ref.: ","").replace(" ","");

  regExp = new RegExp("margin-top: 5px; margin-bottom: 5px; padding: 5px; background-color: #699D15; color: #fff; text-align: center;([^]*)/div>", "gi");
  var descriptionHtml = regExp.exec(html);
  var regExp = new RegExp("<p([^]*)p>", "gi");
  var descriptionHtml = regExp.exec(descriptionHtml);
  var regExp = new RegExp("^[^.]*", "gi");
  var descriptionHtml = regExp.exec(descriptionHtml);
  var descriptionOutput = descriptionHtml[0].replace("<p>","");
  descriptionOutput = descriptionOutput+".";

  regExp = new RegExp("ecom(.+?)Main.png", "gi");
  var imageHtml = regExp.exec(html);
  var comecoDaURL = "https://www.nespresso.com/";
  var imageOutput = comecoDaURL+imageHtml[0];

  var regExp = new RegExp("nes_l-float nes_big-price nes_big-price-with-out([^]*)p>", "gi");
  var precoHtml = regExp.exec(html);
  var regExp = new RegExp("[0-9]*,", "gi");
  precoHtml = regExp.exec(precoHtml);
  var precoOutput = "BRL "+precoHtml[0].replace(",","");

  resultadoArray = [codeOutput,h1Output,descriptionOutput,"Home & Garden > Kitchen & Dining > Kitchen Appliances > Coffee Makers & Espresso Machines",
                    "Máquina",linkDoProduto,imageOutput,"new","in stock",precoOutput,"","","","Nespresso",codeOutput];

  return resultadoArray;
}

Но это очень много времени для программирования, его очень трудно изменить динамически и не очень надежно.

Мне нужен способ, чтобы разобрать этот HTML и легко получить доступ к его элементам .. На самом деле это не надстройка. но простой скрипт приложения Google ..

12
user3347814

Я сделал это в Vanilla JS. Не настоящий HTML разбор. Просто попробуйте получить некоторый контент из строки (url):

function getLKKBTC() {
  var url = 'https://www.lykke.com/exchange';
  var html = UrlFetchApp.fetch(url).getContentText();
  var searchstring = '<td class="ask_BTCLKK">';
  var index = html.search(searchstring);
  if (index >= 0) {
    var pos = index + searchstring.length
    var rate = html.substring(pos, pos + 6);
    rate = parseFloat(rate)
    rate = 1/rate
    return parseFloat(rate);
  }
  throw "Failed to fetch/parse data from " + url;
}
8
Fabian Thommen

Это обсуждалось ранее. Смотрите здесь: Как лучше всего разбирать HTML в скрипте приложений Google

В отличие от службы XML, XMLService не очень простит неправильно сформированный html. Уловка в ответе Джастина Бикнелла делает работу. Хотя служба XML устарела, она все еще продолжает работать. 

5
Sujay Phadke

Я сделал приветствие для вашей проблемы. он работает на GAS как cheerio, который похож на jQuery api. Вы можете сделать это так.

const content = UrlFetchApp.fetch('https://example.co/').getContentText();
const $ = Cheerio.load(content);
Logger.log($('p .blah').fist().text()); // blah blah blah ...

Смотрите также https://github.com/asciian/cheeriogs

4
asciian

Имейте в виду, что некоторые веб-сайты могут не разрешать автоматическую очистку своего контента, поэтому, пожалуйста, ознакомьтесь с их условиями или услугами, прежде чем использовать Apps Script для извлечения контента.

XmlService работает только с действительными документами XML, и большинство HTML (особенно HTML5) не являются допустимыми XML. Предыдущая версия XmlService, просто называемая Xml, допускала «мягкий» синтаксический анализ, который позволял бы ему также анализировать HTML. Этот сервис был закатом в 2013 году, но пока еще работает. Справочные документы больше не доступны, но это старое руководство показывает его использование.

Другой альтернативой является использование службы, такой как Kimono , которая обрабатывает части для анализа и разбора и предоставляет простой API, который можно вызвать через UrlFetchApp для получения структурированных данных.

2
Eric Koleda

Не могли бы вы использовать JavaScript для разбора HTML? Если ваш скрипт Google Apps извлек html в виде строки, а затем вернул его в функцию javascript, кажется, что вы можете просто разобрать его вне скрипта Google Apps. Любые теги, которые вы хотите очистить, вы можете отправить в специальную функцию Служб Google, которая сохранит контент.

Возможно, вы могли бы сделать это проще с помощью jQuery .

1
Eric Dauenhauer

Я нашел очень аккуратную альтернативу скрести с помощью Google App Script. Это называется PhantomJS Cloud . Можно использовать urlFetchApp для доступа к API. Это позволяет выполнять код Jquery на страницах, что значительно упрощает жизнь.

0
user3347814

может быть, не самый чистый подход, но простая обработка строк тоже делает работу без xmlservice:

var url = 'https://somewebsite.com/?q=00:11:22:33:44:55';
var html = UrlFetchApp.fetch(url).getContentText();
// we want only the link text displayed from here:
//<td><a href="/company/ubiquiti-networks-inc">Ubiquiti Networks Inc.</a></td>
var string1 = html.split('<td><a href="/company/')[1]; // all after '<td><a href="/company/'
var string2 = string1.split('</a></td>')[0];           // all before '</a></td>'
var string3 = string2.split('>')[1];                   // all after '>'
Logger.log('link text: '+string3);                     // string3 => "Ubiquiti Networks Inc."
0
vchrizz