簡體   English   中英

異步抓取F#

[英]Asynchronous crawling F#

在網頁上抓取時,我需要小心,不要向同一個域發出太多請求,例如我想在請求之間放置1秒。 據我所知,這是請求之間的重要時間。 因此,為了加快速度,我想在F#中使用異步工作流,這個想法是以1秒的間隔發出請求,但在等待請求響應時避免阻塞。

let getHtmlPrimitiveAsyncTimer (uri : System.Uri) (timer:int) =
    async{

            let req =  (WebRequest.Create(uri)) :?> HttpWebRequest
            req.UserAgent<-"Mozilla"
            try 

                Thread.Sleep(timer)
                let! resp =    (req.AsyncGetResponse())
                Console.WriteLine(uri.AbsoluteUri+" got response")
                use stream = resp.GetResponseStream()
                use reader = new StreamReader(stream)
                let html = reader.ReadToEnd()
                return html
            with 
            | _ as ex -> return "Bad Link"
                 }

然后我做了類似的事情:

let uri1 = System.Uri "http://rue89.com"
let timer = 1000
let jobs = [|for i in 1..10 -> getHtmlPrimitiveAsyncTimer uri1 timer|]

jobs
|> Array.mapi(fun i job -> Console.WriteLine("Starting job "+string i)
                               Async.StartAsTask(job).Result)

這好嗎? 我非常不確定兩件事: - Thread.Sleep是否適用於延遲請求? - 使用StartTask有問題嗎?

我是初學者(你可能已經注意到了)在F#中(實際編碼一般),並且所有涉及Threads的東西都讓我害怕:)

謝謝 !!

我想你想要做的是 - 創建10個工作,編號為'n',每個從現在起'n'秒開始 - 並行運行

大概喜歡

let makeAsync uri n = async {
    // create the request
    do! Async.Sleep(n * 1000)
    // AsyncGetResponse etc
    }

let a = [| for i in 1..10 -> makeAsync uri i |]
let results = a |> Async.Parallel |> Async.RunSynchronously

請注意,當然它們都不會完全啟動,例如,如果您有一台4核機器,4將很快開始運行,但隨后快速執行Async.Sleep,此時接下來的4將會運行直到他們睡覺,等等。 然后在一秒鍾內第一個異步喚醒並發布一個請求,另一個秒后第二個異步喚醒,...所以這應該工作。 1s只是近似的,因為他們每個人的起始時間彼此錯開一點......你可能想稍微緩沖一下,例如1100毫秒或者其他東西,如果你需要的截止點確實是一個第二(網絡延遲,還有什么可能留下一些可能控制你的程序之外)。

Thread.Sleep是次優的,對於少量請求它可以正常工作,但是你正在燒掉一個線程,並且線程很昂貴而且它不會擴展到很多。

您不需要StartAsTask除非您希望與.NET任務進行互操作,或者稍后通過.Result對結果進行阻塞集合。 如果你只是希望這些都運行然后阻塞來收集數組中的所有結果, Async.Parallel將為你做這個fork-join並行性就好了。 如果他們只打算打印結果,你可以通過Async.Start ,這會將結果丟棄在地板上。

(另一種策略是使用代理作為限制。將所有http請求發布到單個代理,其中代理在邏輯上是單線程並且處於循環中,執行Async.Sleep 1 Async.Sleep ,然后處理下一個請求這是一個制作通用油門的好方法......可能對我而言值得博客,想到它。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM