Webcrawler - выборка ссылок - PullRequest
       2

Webcrawler - выборка ссылок

0 голосов
/ 05 августа 2011

Я пытаюсь просканировать веб-страницу, получить все ссылки и добавить их в list<string>, который будет возвращен в конце из функции.

Мой код:

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 ...) она просто выдает ошибку:

Несоответствие типов. Ожидается строка -> 'a, но задана строка -> seq <'a> Результирующий тип будет бесконечным при объединении' 'a' и 'seq <' a> '

Ответы [ 3 ]

2 голосов
/ 05 августа 2011

crawl возвращает unit, но ожидается, что вернется 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 голосов
/ 19 января 2012

Чтобы получить ссылки:

    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
0 голосов
/ 05 августа 2011

я думаю что-то вроде этого:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...