web-dev-qa-db-ja.com

Google AppsスクリプトでHTMLを解析する最良の方法は何ですか

_var page = UrlFetchApp.fetch(contestURL);
var doc = XmlService.parse(page);
_

上記のコードを使用すると解析エラーが発生しますが、XmlServiceクラスを非推奨のXmlクラスに置き換え、寛大なフラグを設定すると、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ツリーに解析するきれいな方法はありますか?.

18
copperhead

私はこれとまったく同じ問題に遭遇しました。最初は非推奨の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スクリプトから完全に削除されている場合、このソリューションは機能しない可能性があります。

30
Justin Bicknell

Googleアプリでhtmlを解析する最良の方法は、XmlService.parseまたはXml.parseを使用しないことです。 XmlService.parseは、特定のWebサイトからの不正なhtmlコードではうまく機能しません。

ここでは、XmlService.parseまたはXml.parseを使用せずにWebサイトを簡単に解析する方法の基本的な例を示します。この例では、「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
    }
}

- AppsスクリプトプロジェクトにHTMLファイルを追加します。スクリプトエディターを開き、[ファイル]> [新規]> [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ファイルを保存し、スプレッドシートに戻ります。スプレッドシートを再読み込みします。[解析メニュー]-[解析]をクリックします。次に、サイドバーの[ここをクリックしてリストを取得]をクリックします。 =

4
Yves R

Xml.parse()には寛大な解析をオンにするオプションがあり、HTMLの解析時に役立ちます。ただし、Xmlサービスは非推奨であり、新しいXmlServiceにはこの機能がありません。

3
Eric Koleda

正規表現を使用します。

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
2
Ivan de Leon

OPが正確に何を要求したかはわかりませんが、いくつかのhtml解析オプションを探しているときにこの質問を見つけました。他の人にも役立つかもしれません。

TEXT解析にライブラリを使用するのは簡単 があります。 html(xml)コードから1つの情報のみを取得する場合に便利です。

Visualization of parsing text principle 上図のように機能します

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;
}

本来は、htmlがxml形式に準拠していない場合は機能しない、すでに試した方法を実行しない限り、方法はありません。

1
Zig Mandel