2013-10-18 27 views
14
var page = UrlFetchApp.fetch(contestURL); 
var doc = XmlService.parse(page); 

使用時,上面的代碼給出瞭解析錯誤的最好方式,但是如果我更換使用舊版XML類的XmlService類,與寬鬆的標誌設置,它解析正確的HTML。什麼是解析HTML在谷歌的Apps腳本

var page = UrlFetchApp.fetch(contestURL); 
var doc = Xml.parse(page, true); 

該問題主要是由於html的javascript部分中沒有CDATA引起的,解析器抱怨出現以下錯誤。

The entity name must immediately follow the '&' in the entity reference. 

即使我刪除所有<script>(.*?)</script>使用正則表達式,它仍然抱怨,因爲<br>標籤未關閉。 是否有將DOM解析爲DOM樹的乾淨方式。

+0

請參閱http://stackoverflow.com/a/1732454/362634 ... –

+0

您可能會抓取頁面並使用解析器去除unwants標記,然後啓動另一個解析,這可能是可能的。我知道XmlService運行良好,但是有點bug。 – hwnd

回答

1

本地沒有辦法,除非你做了你已經嘗試過,如果HTML不符合XML格式,將無法正常工作。

3

Xml.parse()有一個選項來打開lenient解析,這有助於解析HTML。請注意,Xml服務已棄用,但較新的XmlService不具備此功能。

25

我遇到了這個完全相同的問題。我可以先使用過時Xml.parse繞過它,因爲它仍然有效,然後選擇身體的XmlElement,然後在其XML字符串傳遞到新XmlService.parse方法:

var page = UrlFetchApp.fetch(contestURL); 
var doc = Xml.parse(page, true); 
var bodyHtml = doc.html.body.toXmlString(); 
doc = XmlService.parse(bodyHtml); 
var root = doc.getRootElement(); 

注意:此方法可能無法正常工作如果舊的Xml.parse已完全從Google腳本中刪除。

+5

感謝您的這個訣竅:)它仍然有效,截至2016年1月。 –

+0

完整的結構化'html'文檔如何驗證並且XmlService.parse只是扼殺它們呢? –

+2

doc.html.body對我來說是一個數組,因爲某些原因,每個元素看起來都不一樣 –

2

使用正則表達式:

var page = UrlFetchApp.fetch(contestURL); 
var regExp = new RegExp("(pattern)", "gi"); 
var value = regExp.exec(page.getContentText())[1]; // [1] is the match group when using parenthesis in the pattern 
+0

最後一行返回'''null'''給我。 –

+0

它通常是一個非常糟糕的想法(tm)使用regexen來解析html/xml:https://blog.codinghorror.com/parsing-html-the-cthulhu-way/ – gorgonzola

2

我發現,在谷歌應用程序解析HTML最好的方法是避免使用XmlService.parse或Xml.parse。 XmlService.parse不適用於某些網站的錯誤html代碼。

這裏是一個關於如何輕鬆解析任何網站而不使用XmlService.parse或Xml.parse的基本示例。在這個例子中,我從「wikipedia.org/wiki/President_of_the_United_States」 中檢索一個常規javascript document.getElementsByTagName()的總統名單,並將這些值粘貼到我的Google電子表格中。

1-創建一個新的Google表格;

2 - 點擊菜單工具>腳本編輯器...打開使用代碼編輯器窗口的新選項卡,將以下代碼複製到你的Code.gs:

function onOpen() { 
var ui = SpreadsheetApp.getUi(); 
    ui.createMenu("Parse Menu") 
     .addItem("Parse", "parserMenuItem") 
     .addToUi(); 

} 


function parserMenuItem() { 
    var sideBar = HtmlService.createHtmlOutputFromFile("test"); 
    SpreadsheetApp.getUi().showSidebar(sideBar); 
} 


function getUrlData(url) { 
var doc = UrlFetchApp.fetch(url).getContentText() 
return doc        
} 

function writeToSpreadSheet(data) { 
var ss = SpreadsheetApp.getActiveSpreadsheet(); 
var sheet = ss.getSheets()[0]; 
var row=1 

    for (var i = 0; i < data.length; i++) { 
    var x = data[i]; 
    var range = sheet.getRange(row, 1) 
    range.setValue(x); 
    var row = row+1 
    } 
} 

3-將HTML文件添加到您的Apps腳本項目。打開腳本編輯器,選擇File> New> HTML文件,並將其命名爲「test'.Then以下代碼複製到你的test.html

<!DOCTYPE html> 
<html> 
<head>  
</head> 
<body> 
<input id= "mButon" type="button" value="Click here to get list" 
onclick="parse()"> 
<div hidden id="mOutput"></div> 
</body> 
<script> 

window.onload = onOpen; 

function onOpen() { 
var url = "https://en.wikipedia.org/wiki/President_of_the_United_States" 
google.script.run.withSuccessHandler(writeHtmlOutput).getUrlData(url) 
document.getElementById("mButon").style.visibility = "visible"; 
} 

function writeHtmlOutput(x) { 
document.getElementById('mOutput').innerHTML = x; 
} 

function parse() { 

var list = document.getElementsByTagName("area"); 
var data = []; 

    for (var i = 0; i < list.length; i++) { 
    var x = list[i]; 
    data.push(x.getAttribute("title")) 
    } 

google.script.run.writeToSpreadSheet(data); 
} 
</script> 
</html> 

4-保存您的GS和HTML文件,返回到您的電子表格。重新加載您的電子表格。點擊「解析菜單」 - 「解析」。然後點擊邊欄中的「點擊此處獲取列表」。