2014-06-05 23 views
1

我目前有一個使用HTML Agility包進行C#網絡刮取,最終結果是表示一行表中數據的字符串數組列表。我對F#非常陌生,遇到一些問題,理解如何正確解析它。我也是用這個F#包裝:https://fsnotebook.net/notebook/fssnip-kr/HtmlAgilityPack_FSharp選擇HTML節點seq的內部文本

我的C#代碼:

var body = document.DocumentNode.Descendants().FirstOrDefault(n => n.Name == "body"); 
var table = body.Descendants("table").FirstOrDefault(t => t.Attributes.Contains("cellpadding") && t.Attributes["cellpadding"].Value == "1"); 
var rows = 
    table.Descendants("tr") 
     .Where(r => r.Attributes.Contains("bgcolor") && r.Attributes["bgcolor"].Value == "#ffffff"); 
List<string[]> athleteDatas = 
    rows.Select(t => t.Descendants("td").Select(d => d.InnerText).ToArray()).ToList(); 

我的F#代碼。到目前爲止,我有一系列td元素,我需要選擇每個序列的內部元素作爲字符串數組,然後將其放回到序列/列表中。

let resultsBody resultsPage = 
    resultsPage 
    |> createDoc 
    |> descendants "table" 
    |> Seq.filter (hasAttr "cellpadding" "1") 
    |> Seq.head 
    |> descendants "tr" 
    |> Seq.filter (hasAttr "bgcolor" "#ffffff") 
    |> Seq.map(descendants "td") 
    |> Seq.toArray 

回答

2

如果我理解正確,缺少的部分被包含在原始代碼.Select(...)內,所以你需要修改map類似:

|> Seq.map (descendants "td" >> Seq.map innerText >> Array.ofSeq) 

或者,如果你有一些困難點 - 免費:

|> Seq.map (fun line -> 
    line 
    |> descendants "td" 
    |> Seq.map innerText 
    |> Array.ofSeq) 
3

您可以通過使用XPath來簡化此操作。這會返回一個seq<string>。如果您需要列表或陣列,請將最後一行輸入Seq.toList/Seq.toArray

open HtmlAgilityPack 

let html = """ 
<html> 
    <body> 
     <table cellpadding="1"> 
      <tbody> 
       <tr bgcolor="#ffffff"> 
        <td> 
         Some text. 
        </td> 
       </tr> 
      </tbody> 
     </table> 
    </body> 
</html>" 
""" 

let doc = HtmlDocument() 
doc.LoadHtml(html) 
doc.DocumentNode.SelectNodes("//body/table[@cellpadding='1']//tr[@bgcolor='#ffffff']/td") 
|> Seq.map (fun n -> n.InnerText) 
+0

謝謝。這實際上更有意義,但是我在發佈這個地方後發現了一個錯誤,在那裏我需要做bgcolor不是特定顏色的地方。我對XPath並不熟悉。 – CGross

+1

只需將'@ bgcolor = '更改爲'@bgcolor!= '。 [MSDN上的XPath示例](http://msdn.microsoft.com/zh-cn/library/ms256086(v = vs.110).aspx)是一個很好的介紹。 – Daniel