var page = UrlFetchApp.fetch(contestURL);
var doc = XmlService.parse(page);
上面的代码在使用时给出了解析错误,但是如果我用不推荐使用的Xml类替换XmlService类并设置了lenient标志,它会正确地解析html。
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>
标记未关闭。
是否有一种将html解析为DOM树的简洁方法。
答案 0 :(得分:30)
我遇到了同样的问题。我能够通过首先使用已弃用的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脚本中完全删除,则此解决方案可能无效。
答案 1 :(得分:7)
在 2021 年,我所知道的在 .gs
端解析 HTML 的最佳方法是...
const contentText = UrlFetchApp.fetch('https://www.somesite.com/').getContentText();
const $ = Cheerio.load(contentText);
$('.some-class').first().text();
就是这样——这可能是我们最接近在 GAS 中进行类似 jQuery 的 DOM 选择的方法。 .first()
很重要,否则您可能会提取出比预期更多的内容(将其视为使用 querySelector()
而不是 querySelectorAll()
)。
答案 2 :(得分:4)
我发现在Google应用中解析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-点击菜单工具&gt;脚本编辑器...使用代码编辑器窗口打开一个新选项卡,并将以下代码复制到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脚本项目中。打开脚本编辑器,然后选择文件&gt;新&gt; Html文件,并将其命名为'test'。然后将以下代码复制到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文件,然后返回电子表格。重新加载您的电子表格。单击“Parse Menu” - “Parse”。然后点击侧栏中的“点击此处获取列表”。
答案 3 :(得分:3)
Xml.parse()
可以选择启用宽松解析,这有助于解析HTML。请注意,Xml
服务已弃用,较新的XmlService
不具备此功能。
答案 4 :(得分: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
答案 5 :(得分:1)
除非你做了你已经尝试过的,如果html不符合xml格式的话,那就没有办法了。
答案 6 :(得分:0)
我知道这并不是OP的要求,但是当我寻找一些html解析选项时我发现了这个问题-因此对其他人也可能有用。
有一个easy to use the library for TEXT parsing。如果您只想从html(xml)代码中获取一条信息,这将非常有用。
function getData() {
var url = "https://chrome.google.com/webstore/detail/signaturesatori-central-s/fejomcfhljndadjlojamaklegghjnjfn?hl=en";
var fromText = '<span class="e-f-ih" title="';
var toText = '">';
var content = UrlFetchApp.fetch(url).getContentText();
var scraped = Parser
.data(content)
.from(fromText)
.to(toText)
.build();
Logger.log(scraped);
return scraped;
}