<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用.Net Core做個爬蟲

          共 2767字,需瀏覽 6分鐘

           ·

          2020-12-23 22:40

            最近接手一個新項目,爬亞馬遜分類、商品數(shù)據(jù)。記得大學的時候,自己瞎玩,寫過一個爬有緣網(wǎng)數(shù)據(jù)的程序,那個時候沒有考慮那么多,寫的還是單線程,因為網(wǎng)站沒有反爬,就不停的一直請求,記得放到實驗室電腦上一天,跑了30w+的數(shù)據(jù)。然后當前晚上有緣網(wǎng)網(wǎng)站顯示維護中。。。。

          ?畢竟小打小鬧,沒有真正的寫過爬蟲。就翻別人博客了解了下爬蟲所用到的技術、技巧、套路。然后就翻到這個老哥寫的博客, 雖然語言是有點囂張,但是我還是比較認同的 哈哈哈哈。

          ?

          ?下面從爬蟲涉及的幾任務調度、數(shù)據(jù)去重、數(shù)據(jù)解析、并發(fā)控制、斷點續(xù)爬、代理來聊聊項目遇到的坑。

          一、數(shù)據(jù)解析

          數(shù)據(jù)解析就是提取網(wǎng)頁上的有效數(shù)據(jù)。.Net下有個HtmlAgilityPack組件,可以很好地解析HMTL。想都沒想 就直接用了它(這就為后面挖了一個大坑)。剛開始單線程測試的時候,一切正常,但是當我開了50個線程的時候,內(nèi)存在90s內(nèi)飆升到了3G,而且持續(xù)爬升。

          用.Net Memory工具分析發(fā)現(xiàn) 內(nèi)存被大對象沾滿了,所以每次GC的時候內(nèi)存并沒有被回收,有5w多HtmlNode,每個對象大小都超過 85000byte。

          ?因為亞馬遜的圖片不是通過鏈接外鏈的,而是通過base64編碼的,所以導致下載的網(wǎng)頁Html超過1M,而85000byte就算大對象了。導致每爬取一個商品詳情頁,都會加載到HtmlNode中變成一個大對象,由于GC不壓縮大對象,而C對大對象的回收只有在回收2代的時候才觸發(fā)。所以只能改變策略,通過正則、切分字符串來處理。

          二、任務調度、并行爬取

          目的是爬取亞馬遜的分類和分類下的商品,我做了個3個任務,

          1、找到分類入口,爬取分類Id、標題、url 、分類等級存儲到數(shù)據(jù)庫。

          2、根據(jù)1任務爬取的分類Id,獲取分類下商品列表。爬取列表上商品部分信息,包括商品的Id、名稱、縮略圖。

          3、根據(jù)2任務爬取的商品Id,獲取商品詳情頁,爬取商品詳情頁的其他信息。

          一個分類下有幾百頁商品列表,而每個列表一般有22個商品。所以1任務爬取完一次,2任務要爬取幾百次(當然不會將分類下的所有頁碼都爬完,設定只爬20頁) ,3任務要爬 20 x 22次。這樣分任務的好處就是 3個任務中,不論哪個任務掛了,其他2個任務是不受影響的,可以繼續(xù)跑。

          比如2任務掛掉了,1任務不受它影響,雖然3任務的需要2任務的數(shù)據(jù),但是3任務的速度是比2任務慢了22倍還多(獲取詳情的時候 還需要在請求其他頁面)所以任務線程相同的情況下 2任務的會有很多剩余商品 3還沒有來得及跑。

          調度采用了QuartZ 使用Cron配置定時任務。使用Parallel并行爬取,線程數(shù)量可以配只需要將方法和方法所需要的參數(shù)集合放到ForEach

          ?

          合理配置每個任務的線程數(shù)量,我設置爬取分類線程數(shù)1,商品列表的線程是2,商品詳情爬取線程為50。爬取的速度不同線程數(shù)量就不同,而且并不是線程越高越好,這個值是不斷的調試采集相同時間的數(shù)據(jù)分析得出來的。

          三、代理

          現(xiàn)在有很多代理商,普遍分為兩種:

            第一種通過接口返回代理IP和這個代理的可用時間,在這個時間段內(nèi),這個代理是可用的。注意:這種代理方式需要有個代理池,因為爬蟲一般都是多線程,如果在代理IP可用時間段內(nèi),多個線程一直使用同一個代理IP,很大可能會被封。所以保險的做法就是一個線程一個代理,降低每個代理的請求次數(shù)。

            第二種代理直接給你一個固定的IP,這個代理IP沒有時間限制,代理商那邊會幫你自動幫你換不同的IP請求目標地址。

          .Net Core中使用代理很簡單,因為我使用的是HttpClientFactory,所以在添加服務的時候配置 HttpClientHandler的代理就可以,需要實現(xiàn)一個IWebProxy類,返回對應的代理IP和端口號就可以了。

          ?剛開始使用的是第一種代理,為了實現(xiàn)一個線程一個代理,我創(chuàng)建了一個代理池,在程序啟動的時候,每個線程都會從代理商那獲取到一個代理IP,然后放到代理池中,每次獲取代理的時候,通過代理池中隨機挑選一個代理IP,在挑選前會判斷當前代理池中的代理數(shù)量,如果小于線程數(shù)據(jù),就會去獲取填充到代理池中。

          后面發(fā)現(xiàn)國內(nèi)的代理商的IP訪問國外網(wǎng)址太慢了,就換了國外代理,國外代理使用的是第二種方案。但是這個代理商不是自動幫你更換IP,而是需要每次傳遞一個隨機數(shù) SessionId,隨機數(shù)不同,代理商訪問目標網(wǎng)站的IP就不同,而且要傳用戶名和密碼。

          ?開始 我是這么做的:

          ?發(fā)現(xiàn)這種只有在第一次創(chuàng)建HttpClient的時候才會去走配置ConfigurePrimaryHttpMessageHandler方法,之后創(chuàng)建HttpClient都不會走。就導致一直在使用同一個IP請求。

          所以沒辦法,只能放棄使用HttpClientFactory,自己手動創(chuàng)建HttpClient ,然后釋放。但這種又隨之帶來一個問題HttpClient雖然釋放了,但是端口還是被占用著,目前還沒有好的解決辦法。

          ?四、斷點續(xù)爬、數(shù)據(jù)去重

          我這個業(yè)務中這兩個功能就很好實現(xiàn),每次爬取完成商品頁碼,就存儲下一頁的頁碼和當前爬取的頁碼數(shù)。配置一個參數(shù)是否是斷點續(xù)爬,如果是斷點續(xù)爬,就從上次記錄的頁碼爬取商品。

          數(shù)據(jù)去重,因為直接可以拿到亞馬遜的商品Id和分類Id,所以去重就變的很簡單,任務啟動的時候,會將已經(jīng)爬取過的商品Id和分類Id放到緩存中,爬取的時候對比數(shù)據(jù)。

          ?

          項目在服務器上跑了2個晚上,表現(xiàn)還是可以的,數(shù)據(jù)都正確采集到了117w數(shù)據(jù)(包含未爬取詳情的商品),最后的最后。。。。項目被砍了,因為亞馬遜的商品詳情頁數(shù)據(jù)太大,導致爬了12個小時用了40G流量,1G=6美元 ,一個月就要40x2x6x30=14400美元。忙碌了兩周,也算從零寫了一個小小的爬蟲,還算有所得。

          出處:https://www.cnblogs.com/MicroHeart/p/14115853.html







          回復?【關閉】
          回復?【實戰(zhàn)】獲取20套實戰(zhàn)源碼
          回復?【被刪】
          回復?【訪客】
          回復?【小程序】學獲取15套【入門+實戰(zhàn)+賺錢】小程序源碼
          回復?【python】學微獲取全套0基礎Python知識手冊
          回復?【2019】獲取2019 .NET 開發(fā)者峰會資料PPT
          回復?【加群】加入dotnet微信交流群

          再見,VIP,臥槽又來一個看片神器!


          推薦這10個優(yōu)秀的.NET Core開源項目!



          瀏覽 56
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩AV中文字幕在线 | 成人影音先锋 | 成人MV在线 | 国产成人a亚洲精品 | 亚洲天堂成人视频 |