情報をある種のカレンダーにインポートするために、大学から提供された授業スケジュールを解析しようとしています。スケジュールの例は、 http ://www.asw-berufsakademie.de/fileadmin/download/download/Sked%20Stundenplan/WIA13-7.%20Block.html で確認できます。
私の意見では、自動生成された HTML コンテンツはごちゃごちゃしていて、把握するのが非常に困難です。たとえば、テーブルは主に rowspan と colspan で構築されます (コード内のセルの位置は、ブラウザーでの実際の視覚的な位置と比較すると、部分的に恣意的に見えます)。
私がすでに試したこと:
- 大学の事務局に、よりシンプルで読みやすいファイルを別に提供するよう依頼する。もちろん、これは不可能です。結局のところ、1 分間の追加作業が必要になるからです。
- HTML の生成に使用された元のツールの調査。それは「sked Stundenplan ソフトウェア」と呼ばれます。生成プロセスを「逆」にするためのヒントやツールは見つかりませんでした。
- 既存のソリューションを探していますが、その時点で、私のスケジュールでは機能しないツール ( http://code.google.com/p/skd-schedule-parser/など) を見つけました。これらのツールのコードを調べた結果、これらのツールは sked の他のバージョンまたは古いバージョン用に設計されたに違いないと結論付けました。
- HTML を PHP で解析します (主に DOMDocument を使用)。それは時々うまくいきましたが、信頼性が低すぎました...考慮すべき例外は無期限のようです.
今のところ、従来の HTML 構文解析では、少なくとも許容できる開発時間では、うまくいかないと思います。私が探しているのは、YQL のような複雑な HTML テーブルから情報を取得する他の方法、またはそのようなテーブルを列/行スパンで正規化できるユーティリティです。具体的なことは何も考えていないので、主に別のアプローチのヒントやヒントを求めています。
そのようなテーブルを解析するための他のより適切な方法はありますか、それとも従来の HTML 解析にこだわっていますか?
編集:
リクエストに代わって、生のコードの例を貼り付けます...
今週:
このコードの結果:
http://pastebin.com/BJduUVtU
編集 2:
解析に関する議論があったため、PHP コードも追加します。PHPは初めてなので、あまり洗練されていません。むしろ、理論的にテーブルを解析することで私がどこまで来たかについての洞察を与えるべきです. 実際の作業は関数parseSkedTable()で行われます。この関数に集中してください。また、コメントに表示される「ダブルコース」という用語を指摘したいと思います。これは、2 つの異なるコースが同時に行われていることを表します (そのような瞬間にクラスが分割されます)。これらのコースの例は、第 2 週にここにあります:
http://www.asw-berufsakademie.de/fileadmin/download/download/Sked%20Stundenplan/WIB14-4.%20Block.html
次のようになります。
その週の対応するHTML コードは、http: //pastebin.com/gLTWz5KUからもアクセスできます。
そして今、PHPコード(最初の言語でコメントを表現するのにすでに苦労していたので、コメントを翻訳するのに苦労しました...それでも役立つことを願っています):
http://pastebin.com/Nzi8m2v8
アップデート
これまでのところ、構文解析の問題に対するいくつかの解決策があり、それぞれ JavaScript を使用しています。JavaScript (ブラウザでレンダリングされたデータを使用できるため、ここでは特に強力です) が HTML から信頼できる情報を取得する唯一の効率的な方法のように思われるため、私は現在、ある種のヘッドレス ブラウザまたはレンダリング エンジンを実装する方法を探しています。 x10hosting.com の無料サーバーで。残念ながら、softaculousが提供する以外のソフトウェアをインストールすることも、PHP のexec()コマンドを使用することも許可されていません。
どんなアイデアでも大歓迎です!
完全を期すために、現在まで存在する両方のソリューションを投稿します。
Pierre DuboisによるjQueryパーサー:
(関数 ($) { $(document).ready(function() {
var _pe = window.pe || { fn : {} }; var tblNumber = 0; // Just a incremental number to identify the schedule item with the table // For each table $('table').each(function () { $('#output').append('Parsing the table number: ' + tblNumber + '<br>'); // console.log('Parsing the table number: ' + tblNumber); tblNumber += 1; var currentTable = this; // Parser the complex table _pe.fn.parsertable.parse($(currentTable)); // Retrieve the parsed data var parsedData = $(currentTable).data().tblparser; // // Information about the column structure, nice that is consistent // // Day: Cell index position (0 based) // Mo: 3 // Di: 7 // Mi: 11 // Do: 15 // Fr: 19 // Sa: 23 // Title Location at Row index position "0" // "i" represent the middle column position for (var i = 3; i < 24; i += 4) { var currentDay; // Get the day currentDay = $(parsedData.row[0].cell[i].elem).text(); $('#output').append(' Day: ' + currentDay + '<br>'); // console.log('Day: ' + currentDay); // Get all the events for that day, excluding the first row and the last row for (var j = 1; j < parsedData.col[i].cell.length - 2; j += 1) { // First column if (parsedData.col[i - 1].cell[j - 1].uid !== parsedData.col[i - 1].cell[j].uid ) { // Get the content of that cell and remove ending space var event = $(parsedData.col[i - 1].cell[j].elem).text().trim(); if (event.length > 0) { $('#output').append(' + Event: ' + event + '<br>'); // console.log('Event: ' + event); } } // Second Column if (parsedData.col[i].cell[j - 1].uid !== parsedData.col[i].cell[j].uid && parsedData.col[i - 1].cell[j].uid !== parsedData.col[i].cell[j].uid) { // Get the content of that cell and remove ending space var event = $(parsedData.col[i].cell[j].elem).text().trim(); if (event.length > 0) { $('#output').append(' + Event: ' + event + '<br>'); // console.log('Event: ' + event); } } // Third Column if (parsedData.col[i + 1].cell[j - 1].uid !== parsedData.col[i + 1].cell[j].uid && parsedData.col[i].cell[j].uid !== parsedData.col[i + 1].cell[j].uid) { // Get the content of that cell and remove ending space var event = $(parsedData.col[i + 1].cell[j].elem).text().trim(); if (event.length > 0) { $('#output').append(' + Event: ' + event + '<br>'); // console.log('Event: ' + event); } } } } }); });
}(jQuery));
rambo coderのアイデアを実現する、私による位置情報を使用したJSパーサー