[英]How do you set the namespace of an XML element using Google Apps Script's XmlService?
[英]How to parse an HTML string in Google Apps Script without using XmlService?
我想使用帶有 Google Apps 腳本的 Google 電子表格創建一個抓取工具。 我知道這是可能的,我看過一些關於它的教程和主題。
主要思想是使用:
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 parse table from messed html以及在 Google Apps 腳本中解析 html 的最佳方法是什么,可以使用稱為xml.parse()
的棄用方法,該方法確實接受允許解析 HTML 的第二個參數。 但是,正如我所提到的,它已被棄用,而且我在任何地方都找不到有關它的任何文檔。 xml.parse()
似乎解析字符串,但由於缺乏文檔,我無法處理這些元素。 而且它也不是最安全的長期解決方案,因為它可以隨時停用。
所以,我想知道如何在 Google Apps Script 中解析這個 HTML?
我也試過:
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,但我找不到任何。
我的最終目標是從一組頁面中獲取一些信息,例如價格、鏈接、產品名稱等。我已經使用一系列正則表達式設法做到了這一點:
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 並輕松訪問其元素。 它實際上不是一個附加項。 但一個簡單的谷歌應用程序腳本..
我為你的問題做了啦啦隊。 它在 GAS 上作為 Cheerio 工作,它是類似 jQuery 的 api。 你可以這樣做。
const content = UrlFetchApp.fetch('https://example.co/').getContentText();
const $ = Cheerio.load(content);
Logger.log($('p .blah').first().text()); // blah blah blah ...
這個之前已經討論過了。 請參閱此處: 在 google 應用程序腳本中解析 html 的最佳方法是什么
與XML服務不同, XMLService對格式錯誤的 html 的容忍度並不高。 賈斯汀·比克內爾 (Justin Bicknell) 的答案中的技巧可以完成這項工作。 即使XML服務已被棄用,它仍然可以繼續工作。
我在 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;
}
我找到了一個非常巧妙的替代方案來使用 Google App Script 進行抓取。 它被稱為PhantomJS Cloud 。 可以使用urlFetchApp訪問 API。 這允許在頁面上執行 Jquery 代碼,這使生活變得更加簡單。
你能用javascript來解析html嗎? 如果您的 Google Apps 腳本將 html 作為字符串檢索,然后將其返回給 javascript 函數,那么您似乎可以在 Google Apps 腳本之外很好地解析它。 您可以將要抓取的任何標簽發送到專用的 Google Apps 功能來保存內容。
您可能可以使用 jQuery更輕松地完成此操作。
也許不是最干凈的方法,但簡單的字符串處理也可以在沒有 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."
我今天只是通過按摩 html 獲得了一些好運:
// close unclosed tags
html = html.replace(/(<(?=link|meta|br|input)[^>]*)(?<!\/)>/ig, '$1/>')
// force script / style content into cdata
html = html.replace(/(<(script|style)[^>]*>)/ig, '$1<![CDATA[').replace(/(<\/(script|style)[^>]*>)/ig, ']]>$1')
// change & to &
html = html.replace(/&(?!amp;)/g, '&')
// now it works! (tested with original url)
let document = XmlService.parse(html)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.