2011-03-26 57 views
1

是否有一種模式可以使用XPath從HTML頁面提取結構化數據?我試圖從頁面上的一個或多個HTML表格提取數據。 XPath可以很容易地找到表格,但是我一直在努力。使用xpath提取結構化數據的策略

我目前做如下:

  • 迭代表(可能有不止一個)
  • 迭代該表
  • 迭代中的行該行內的細胞
  • (然後可能把他們放在一個數組中,並解析內容)

我的代碼是這樣的:

var tables = mydoc.evaluate("//table", mydoc, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); 

table = tables.iterateNext(); 
while (table) 
{ 
    var rows = mydoc.evaluate("tbody/tr", table, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); 
    row = rows.iterateNext(); 
    while (row) 
    { 
    var tds = mydoc.evaluate("td", row, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null) 
    td = tds.iterateNext() 
    while(td) 
    { 
     // TODO: store content in an array to process later 
     print('*' + td.textContent); 
     td = tds.iterateNext(); 
    } 
    row = rows.iterateNext(); 
    } 

    table = iterator.iterateNext(); 
} 

這似乎有點討厭,因爲所有的XPath示例似乎都在一步完成它們的處理。似乎很少有非常重要的例子,其中選擇和組合了兩種類型的數據(例如,表中的標籤和值)。我可以使用下面的選擇,但我結束了兩個列表,沒有結構:

//table/tbody/tr/td[@class='label'] 
//table/tbody/tr/td/a[@class='value'] 

(我知道我使用XPath的HTML解析爲它並沒有真正打算,但它似乎工作迄今。)

+0

在XPath 1.0中,只有節點集數據類型不是原子類型。它是一個集合:無序唯一節點,而不是「結構化」數據類型。你想要什麼涉及某種分組:對於每個'// table/tbody/tr',然後提取'td [@ class ='label']'和'td/a [@ class ='value']'。 – 2011-03-26 23:10:42

+0

好問題,+1。查看我的答案,獲取選擇所需節點的單個XPath表達式。 – 2011-03-27 18:08:19

回答

2

似乎有其中兩種類型的數據(例如 標籤和值在表中)是 選擇和組合幾個非平凡 例子。我可以使用 以下選擇,但我最終 兩份名單沒有結構:

//table/tbody/tr/td[@class='label'] 
//table/tbody/tr/td/a[@class='value'] 

使用

//table/tbody/tr/td[@class='label'] 
| 
    //table/tbody/tr/td/a[@class='value'] 

這種單一的XPath表達式選擇所有想要的節點(我知道所有XPath引擎以文檔順序返回選定的節點)。 |(聯合)運算符生成其參數的集合。

如果(X)HTML文檔具有規則的結構,你可以在返回的結果期待每一個選擇td元素(標籤)應遵循其相應的a元素(值)

0

如果是在主HTML頁面,你可以只是做:

for(var tables=document.getElementsByTagName("table"),i=0;i<tables.length;++i) 
    for(var rows=tables[i].getElementsByTagName("tr"),j=0;j<rows.length;++j) 
    for(var cells=rows[j].getElementsByTagName("td"),k=0;k<cells.length;++k) 
     print("*"+cells[i].textContent); 

的getElementsByTagName不/不/返回數組 - 它返回一個類似ORDERED_NODE_ITERATOR_TYPE現場節點列表。