Как разбирать строку HTML в Google Apps Script без использования XmlService?
Я хочу создать скребок с помощью Google Spreadsheets с помощью Google Apps Script. Я знаю, что это возможно, и я видел некоторые учебники и темы об этом.
Основная идея заключается в использовании:
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 Script таблица синтаксического анализа из messed html и Каков наилучший способ разобрать html в google apps script, можно использовать устаревший метод под названием xml.parse()
, который принимает второй параметр, который позволяет анализировать HTML. Однако, как я уже упоминал, он устарел, и я нигде не могу найти документацию. xml.parse()
, кажется, анализирует строку, но у меня возникли проблемы с работой с элементами из-за отсутствия документации. И это также не самое безопасное долгосрочное решение, потому что оно может быть дезактивировано в ближайшее время.
Итак, я хочу знать, как разобрать этот HTML-код в Google Apps Script?
Я также пробовал:
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 Script..
Ответы
Ответ 1
Я сделал это в 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;
}
Ответ 2
Это обсуждалось ранее. См. Здесь: Каков наилучший способ разобрать html в приложениях Google script
В отличие от службы XML, XMLService не очень прощает неверный HTML-код. Трюк в ответе Джастина Бикнелла делает эту работу. Несмотря на то, что служба XML устарела, она по-прежнему продолжает работать.
Ответ 3
Я сделал приветствие для вашей проблемы. он работает на 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
Не могли бы вы использовать javascript для анализа html? Если ваши Google Apps Script извлекли html в виде строки, а затем вернули его в функцию javascript, похоже, вы могли бы разобрать его просто отлично за пределами Google Apps script. Любые теги, которые вы хотите очистить, можете отправить в специальную функцию Google Apps, которая сохранит содержимое.
Возможно, вы могли бы выполнить это более легко с jQuery.
Ответ 5
Имейте в виду, что некоторые веб-сайты не могут разрешать автоматическую очистку их содержимого, поэтому, пожалуйста, ознакомьтесь с их условиями или услугами перед использованием приложений Script, чтобы извлечь контент.
XmlService
работает только с действительными документами XML, а большинство HTML (особенно HTML5) недопустимо для XML. Предыдущая версия XmlService
, просто называемая Xml
, допускала синтаксический анализ "lenient", что позволяло бы также анализировать HTML. Эта услуга была закатом в 2013 году, но на данный момент все еще функционирует. Справочные документы больше не доступны, но этот старый учебник показывает его использование.
Другой альтернативой является использование службы Kimono, которая обрабатывает фрагменты и парсинг частей и предоставляет простой API, который вы можете вызвать через UrlFetchApp
для получения структурированных данных.
Ответ 6
Я нашел очень опрятную альтернативу царапинам с помощью приложения Google Script. Он называется PhantomJS Cloud. Для доступа к API можно использовать urlFetchApp. Это позволяет выполнять код JQuery на страницах, что делает жизнь намного проще.
Ответ 7
может быть, не самый чистый подход, но простая обработка строк тоже делает работу без 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."