需要从某些站点提取信息。为了解析 HTML,我使用F# Data: HTML Parser(HTML Type Provider
不幸的是,在这种情况下不适用)。
像这样实现它:
let getNextLink (document : HtmlDocument) =
document.Descendants "a"
|> Seq.choose
(fun node ->
match node.TryGetAttribute "href" with
|Some href when node.InnerText().Trim() = "ключевое слово" ->
href.Value() |> Some
|_ -> None)
|> Seq.tryHead
let getAllValues start =
let rec loop (pages : string) = seq {
let result = HtmlDocument.Load pages
yield
result.Descendants "div"
|> Seq.filter
(fun node ->
match node.TryGetAttribute "id" with
|Some id -> id.Value().StartsWith("текст для проверки")
|None -> false)
|> Seq.map
(fun node -> node.InnerText())
let next = getNextLink result
if next.IsSome then
yield! loop next.Value
}
loop start
let path = "http://адрес.html"
let values =
getAllValues path
|> Seq.concat
其余与接收数据的处理有关,与当前问题无关。对正确选择用于解析的库和实现本身感兴趣。
功能一般。但如果您追求完美,那么这里有一些提示:
"id"
,"a"
和"href"
仍然可以理解为稳定标准的一部分,那么字符串"ключевое слово"
和"текст для проверки"
绝对应该是参数。seq<seq<string>>
,然后将其与Seq.concat
. 这个操作对我来说似乎是多余的:因为你使用的是表达式seq { }
,你可以立即使用yield!
instead of 扩展其中的序列yield
。getNextLink
只会返回第一个链接,而您将丢失其余部分。可以免费安排所有链接的处理,而不仅仅是第一个链接,只需Seq.tryHead
从getNextLink
. 但我不确定在你的情况下它是否会“更好”。这是我应用这些技巧后得到的结果: