我目前使用HTML Agility包进行C#web scrape,最终结果是表示一行表中数据的字符串数组列表。我对F#很新,遇到一些问题,了解如何正确解析它。我也使用这个F#包装器:https://fsnotebook.net/notebook/fssnip-kr/HtmlAgilityPack_FSharp
我的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
答案 0 :(得分: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)
答案 1 :(得分:2)
如果我理解正确,丢失的部分包含在原始代码的.Select(...)
内,因此您需要同样修改map
:
|> Seq.map (descendants "td" >> Seq.map innerText >> Array.ofSeq)
或者如果你在无点上有一些困难:
|> Seq.map (fun line ->
line
|> descendants "td"
|> Seq.map innerText
|> Array.ofSeq)