2011-08-04 1 views
0

Webページをクロールしてすべてのリンクを取得し、最後に返されるlist<string>に追加しようとしています。Webcrawler - リンクを取得する

マイコード:

let getUrls s : seq<string> = 
    let doc = new HtmlDocument() in 
       doc.LoadHtml s 

    doc.DocumentNode.SelectNodes "//a[@href]" 
    |> Seq.map(fun z -> (string z.Attributes.["href"])) 

let crawler uri : seq<string> = 
    let rec crawl url = 
     let web = new WebClient() 
     let data = web.DownloadString url 
     getUrls data |> Seq.map crawl (* <-- ERROR HERE *) 

    crawl uri 

問題はクロール機能(getUrlsのseq.map ...)の最後の行で、それは単にエラーをスローしていることである:

Type mismatch. Expecting a string -> 'a but given a string -> seq<'a> The resulting type would be infinite when unifying ''a' and 'seq<'a>'

+4

Seq.collect! :) –

+1

@Mauricio:答えとして投稿する必要があります。 ; - ] – ildjarn

+1

BTW:インスピレーションのため、F#スニペットにいくつかのWebクローリングスニペットがあります。たとえば、http://www.fssnip.net/3Kを参照してください。 –

答えて

2

crawlunitを返しているが、期待されている:私はこのような何かを考えます返信するseq<string>

let crawler uri = 
    let rec crawl url = 
    seq { 
     let web = new WebClient() 
     let data = web.DownloadString url 
     for url in getUrls data do 
     yield url 
     yield! crawl url 
    } 
    crawl uri 

が問題を指摘しなければならないcrawlに型注釈を追加:私はあなたのような何かをしたいと思います。リンクをフェッチするために

0

let crawler (uri : seq<string>) = 
    let rec crawl url = 
     let data = Seq.empty 
     getUrls data 
     |> Seq.toList 
     |> function 
      | h :: t -> 
       crawl h 
       t |> List.iter crawl 
      | _->() 

    crawl uri 
0

:救助へ

open System.Net 
    open System.IO 
    open System.Text.RegularExpressions 

    type Url(x:string)= 
    member this.tostring = sprintf "%A" x 
    member this.request = System.Net.WebRequest.Create(x) 
    member this.response = this.request.GetResponse() 
    member this.stream = this.response.GetResponseStream() 
    member this.reader = new System.IO.StreamReader(this.stream) 
    member this.html  = this.reader.ReadToEnd() 

    let linkex    = "href=\s*\"[^\"h]*(http://[^&\"]*)\"" 

    let getLinks (txt:string) = [ 
           for m in Regex.Matches(txt,linkex) 
           -> m.Groups.Item(1).Value 
           ] 

    let collectLinks (url:Url) = url.html 
           |> getLinks 
関連する問題