我正在尝试解析我的大学提供的课程表,以便将信息导入某种日历。可以在此处查看时间表示例:
http ://www.asw-berufsakademie.de/fileadmin/download/download/Sked%20Stundenplan/WIA13-7.%20Block.html
在我看来,自动生成的 HTML 内容是一团糟,很难掌握。例如,表格主要是用rowspans 和colspans 构建的(代码中单元格的位置与其在浏览器中的实际视觉位置相比似乎部分是任意的)。
我已经尝试过的:
- 要求大学行政办公室单独提供一个更简单、更易于阅读的文件。当然这是不可能的,毕竟这意味着一分钟的额外努力。
- 研究用于生成 HTML 的原始工具。它被称为“sked Stundenplan 软件”。我找不到任何提示或工具来“逆转”生成过程。
- 在寻找现有解决方案时,我发现了一些不适用于我的日程安排的工具(例如http://code.google.com/p/skd-schedule-parser/ )。在研究了这些工具的代码后,我得出结论,它们一定是为其他/过时版本的 sked 设计的。
- 使用 PHP 解析 HTML(主要使用 DOMDocument)。这有时有效,但太不可靠了……要考虑的例外情况似乎是不确定的。
现在,我认为传统的 HTML 解析不会让我走得太远,至少在可接受的开发时间内不会。我正在寻找的是从复杂的 HTML 表中获取信息的其他方法,例如 YQL,或者可以使用 col-/rowspans 规范化此类表的实用程序。因为我没有任何具体的想法,所以我主要是在寻求另一种方法的一些提示或提示。
是否还有其他更合适的方法来解析此类表格,或者我是否坚持使用传统的 HTML 解析?
编辑:
代表一个请求,我将粘贴一个原始代码示例......
本星期:
此代码的结果:http:
//pastebin.com/BJduUVtU
编辑 2:
由于一些解析讨论,我还将添加我的 PHP 代码。这是我第一次使用 PHP,所以它不是很复杂。它应该更深入地了解我在理论上解析表格方面走了多远。实际工作发生在函数parseSkedTable()中,请专注于这一点。另外,我想指出评论中出现的“双门课程”一词,它描述了同时发生的两门不同的课程(课程会在这样的时刻被分开)。这些课程的一个例子可以在第二周找到:
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));
JS解析器使用 我的位置信息,实现rambo coder的想法