2017-05-31 18 views
2

FSharp.DataのHTMLパーサーを使用して、href属性からリンクの文字列リストを抽出しようとしています。F#.Data 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")) 

:指名手配のリンクを表示しますコードのスニペット作業

乾杯、非常に最後の行に

答えて

2

は、あなたは配列の配列で終わる - 各td.pagenavのためにあなたがhrefをそれぞれ有する<a>の束を、持っています。そのため、2つのネストされたSeq.iterを持っていなければなりません。まず外側のシーケンスに対して繰り返しを行い、各繰り返しで内側のシーケンスに対して繰り返します。

シーケンスのシーケンスをフラット化するには、Seq.collectを使用します。さらに、(彼らは同等だ)Seq.toListまたはList.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 

それともあなたはそれビットクリーナーによって作ることができます私はむしろ、リスト内包としてこれを書き換えるだろう、と述べた

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 

:あなたが最初のネストされたシーケンスが発生した時点でSeq.collectを適用します。もっときれいに見える:

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

私の答えがあなたを助けたら、それを受け入れることを検討しますか? –

関連する問題