F#。数据HTML解析器从节点提取字符串

问题描述:

我试图使用FSharp.Data的HTML解析器来提取字符串链接从href属性列表。F#。数据HTML解析器从节点提取字符串

我可以打印输出到控制台的链接,但是,我正在努力让他们进入列表。

工作的打印出想要的链接的代码片段:

let results = HtmlDocument.Load(myUrl) 
let links = 
    results.Descendants("td") 
    |> Seq.filter (fun x -> x.HasClass("pagenav")) 
    |> Seq.map (fun x -> x.Elements("a")) 
    |> Seq.iter (fun x -> x |> Seq.iter (fun y -> y.AttributeValue("href") |> printf "%A")) 

如何存放这些字符串为可变链接,而不是将它们打印出来的?

干杯,

在最后一行,你最终序列的序列 - 每个td.pagenav你有一大堆的<a>,每个有href。这就是为什么你必须有两个嵌套的Seq.iter - 首先迭代外部序列,并在每次迭代中迭代内部序列。

要平铺序列序列,请使用Seq.collect。此外,一个序列转换到一个列表,使用Seq.toListList.ofSeq(他们是等价):

let a = [ [1;2;3]; [4;5;6] ] 
let b = a |> Seq.collect id |> Seq.toList 
> val b : int list = [1; 2; 3; 4; 5; 6] 

将此应用于代码:

let links = 
    results.Descendants("td") 
    |> Seq.filter (fun x -> x.HasClass("pagenav")) 
    |> Seq.map (fun x -> x.Elements("a")) 
    |> Seq.collect (fun x -> x |> Seq.map (fun y -> y.AttributeValue("href"))) 
    |> Seq.toList 

或者你可以使它有点用清洁剂在您第一次遇到一个嵌套序列点应用Seq.collect

let links = 
    results.Descendants("td") 
    |> Seq.filter (fun x -> x.HasClass("pagenav")) 
    |> Seq.collect (fun x -> x.Elements("a")) 
    |> Seq.map (fun y -> y.AttributeValue("href")) 
    |> Seq.toList 

这么说,我宁愿重写这是一个列表解析。看起来更清洁:

let links = [ for td in results.Descendants "td" do 
       if td.HasClass "pagenav" then 
        for a in td.Elements "a" -> 
        a.AttributeValue "href" 
      ] 
+0

完美答案,谢谢! – snowbane

+0

如果我的回答对你有帮助,你会考虑接受吗? –