汽車之家店鋪數據抓取 DotnetSpider實戰[一]

来源:https://www.cnblogs.com/FunnyBoy/archive/2018/02/19/8453338.html
-Advertisement-
Play Games

一、背景 春節也不能閑著,一直想學一下爬蟲怎麼玩,網上搜了一大堆,大多都是Python的,大家也比較活躍,文章也比較多,找了一圈,發現園子裡面有個大神開發了一個DotNetSpider的開源庫,很值得慶幸的,該庫也支持.Net Core,於是乘著春節的空檔研究一下整個開源項目,順便實戰一下。目前互聯 ...


一、背景

春節也不能閑著,一直想學一下爬蟲怎麼玩,網上搜了一大堆,大多都是Python的,大家也比較活躍,文章也比較多,找了一圈,發現園子裡面有個大神開發了一個DotNetSpider的開源庫,很值得慶幸的,該庫也支持.Net Core,於是乘著春節的空檔研究一下整個開源項目,順便實戰一下。目前互聯網汽車行業十分火熱,淘車,人人車,易車,汽車之家,所以我選取了汽車之家,芒果汽車這個店鋪,對數據進行抓取。

二、開發環境

VS2017+.Net Core2.x+DotNetSpider+Win10

三、開發

3.1新建.Net Core項目

新建一個.Net Core 控制台應用

3.2通過Nuget添加DotNetSpider類庫

搜索DotnetSpider,添加這兩個庫就行了

 

 3.3分析需要抓取的網頁地址

打開該網頁https://store.mall.autohome.com.cn/83106681.html,紅框區域就是我們要抓取的信息。

我們通過Chrome的開發工具的Network抓取到這些信息的介面,在裡面可以很清楚的知道HTTP請求中所有的數據,包括Header,Post參數等等,其實我們把就是模擬一個HTTP請求,加上對HTML的一個解析就可以將數據解析出來。

參數page就是頁碼,我們只需要修改page的值就可以獲取指定頁碼的數據了。

返回結果就是列表頁的HTML。

 3.4創建存儲實體類AutoHomeShopListEntity

        class AutoHomeShopListEntity : SpiderEntity 
        {
            public string DetailUrl { get; set; }
            public string CarImg { get; set; }
            public string Price { get; set; }
            public string DelPrice { get; set; }
            public string Title { get; set; }
            public string Tip { get; set; }
            public string BuyNum { get; set; }

            public override string ToString()
            {
                return $"{Title}|{Price}|{DelPrice}|{BuyNum}";
            }
        }

3.5創建AutoHomeProcessor

用於對於獲取到的HTML進行解析並且保存

        private class AutoHomeProcessor : BasePageProcessor
        {
            protected override void Handle(Page page)
            {
                List<AutoHomeShopListEntity> list = new List<AutoHomeShopListEntity>();
                var modelHtmlList = page.Selectable.XPath(".//div[@class='list']/ul[@class='fn-clear']/li[@class='carbox']").Nodes();
                foreach (var modelHtml in modelHtmlList)
                {
                    AutoHomeShopListEntity entity = new AutoHomeShopListEntity();
                    entity.DetailUrl = modelHtml.XPath(".//a/@href").GetValue();
                    entity.CarImg = modelHtml.XPath(".//a/div[@class='carbox-carimg']/img/@src").GetValue();
                    var price = modelHtml.XPath(".//a/div[@class='carbox-info']").GetValue(DotnetSpider.Core.Selector.ValueOption.InnerText).Trim().Replace(" ", string.Empty).Replace("\n", string.Empty).Replace("\t", string.Empty).TrimStart('¥').Split("¥");
                    if (price.Length > 1)
                    {
                        entity.Price = price[0];
                        entity.DelPrice = price[1];
                    }
                    else
                    {
                        entity.Price = price[0];
                        entity.DelPrice = price[0];
                    }
                    entity.Title = modelHtml.XPath(".//a/div[@class='carbox-title']").GetValue();
                    entity.Tip = modelHtml.XPath(".//a/div[@class='carbox-tip']").GetValue();
                    entity.BuyNum = modelHtml.XPath(".//a/div[@class='carbox-number']/span").GetValue();
                    list.Add(entity);
                }
                page.AddResultItem("CarList", list);
            }

        }

3.6創建AutoHomePipe

用於輸出抓取到的結果。

        private class AutoHomePipe : BasePipeline
        {

            public override void Process(IEnumerable<ResultItems> resultItems, ISpider spider)
            {
                foreach (var resultItem in resultItems)
                {
                    Console.WriteLine((resultItem.Results["CarList"] as List<AutoHomeShopListEntity>).Count);
                    foreach (var item in (resultItem.Results["CarList"] as List<AutoHomeShopListEntity>))
                    {
                        Console.WriteLine(item);
                    }
                }
            }
        }

 

3.7創建Site

主要就是將HTTP的Header部信息放進去

            var site = new Site
            {
                CycleRetryTimes = 1,
                SleepTime = 200,
                Headers = new Dictionary<string, string>()
                {
                    { "Accept","text/html, */*; q=0.01" },
                    { "Referer", "https://store.mall.autohome.com.cn/83106681.html"},
                    { "Cache-Control","no-cache" },
                    { "Connection","keep-alive" },
                    { "Content-Type","application/x-www-form-urlencoded; charset=UTF-8" },
                    { "User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.167 Safari/537.36"}
                    


                }

            };

3.8構造Request

因為我們所抓取到的介面必須用POST,如果是GET請求則這一部可以省略,參數就放在PostBody就行。

            List<Request> resList = new List<Request>();
            for (int i = 1; i <= 33; i++)
            {
                Request res = new Request();
                res.PostBody = $"id=7&j=%7B%22createMan%22%3A%2218273159100%22%2C%22createTime%22%3A1518433690000%2C%22row%22%3A5%2C%22siteUserActivityListId%22%3A8553%2C%22siteUserPageRowModuleId%22%3A84959%2C%22topids%22%3A%22%22%2C%22wherePhase%22%3A%221%22%2C%22wherePreferential%22%3A%220%22%2C%22whereUsertype%22%3A%220%22%7D&page={i}&shopid=83106681";
                res.Url = "https://store.mall.autohome.com.cn/shop/ajaxsitemodlecontext.jtml";
                res.Method = System.Net.Http.HttpMethod.Post;

                resList.Add(res);
            }

3.9構造爬蟲並且執行

            var spider = Spider.Create(site, new QueueDuplicateRemovedScheduler(), new AutoHomeProcessor())
                .AddStartRequests(resList.ToArray())
                .AddPipeline(new AutoHomePipe());
            spider.ThreadNum = 1;
            spider.Run();

3.10執行結果

四、下次預告

接下來我會將對商品的詳情頁數據(包括車型參數配置之類的)進行抓取,介面已經抓取到了,還在思考如果更加便捷獲取到商品id,因為目前來看商品id是存儲在頁面的js全局變數中,抓取起來比較費勁。

 

五、總結

.Net 相對於別的語言感覺並不是那麼活躍,DotnetSpider雖然時間不長,但是希望園子裡面大伙都用起來,讓他不斷的發展,讓我們的.Net能夠更好的發展。

第一次寫博客,時間比較倉促,還有很多不足的地方,歡迎拍磚。

祝大家新年快樂

2018年2月19日


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、單例模式 a、單例模式分為四種:文件,類,基於__new__方法實現單例模式,基於metaclass方式實現 b、類實現如下: c、基於__new__方法實現單例模式 d、基於metaclass方式實現單例模式 ...
  • 一、冒泡排序 a、冒泡排序 優化 如果冒泡排序中執行一趟而沒有交換,則列表已經是有序狀態,可以直接結演算法 二、選擇排序 a、一趟遍歷記錄最小的數,放到第一個位置; b、在一趟遍歷記錄剩餘列表中最小的數,繼續放置 三、插入排序 a、列表被分為有序區和無序區兩個部分,最初有序區只有一個元素 b、每次從無 ...
  • 本系列上一篇文章中我們就說到了,這一次我們要說 pop3 收信了。雖然我覺得應該先說完 mime 格式,不過估計大家已經不耐煩了 -- 怎麼老在說發送啊?我們要看收取! 好吧,來啦,來啦!收取郵件現在常用的有 pop3 和 imap 協議,不過從傳統來說 pop3 受眾要廣得多。有了前面的基礎,要實 ...
  • 使用opencv-python一段時間了,因為之前沒有大量接觸過c++下的opencv,在網上看c++的一些程式想改成python遇到了不少坑,正好在這裡總結一下。 1.opencv 中x,y,height, width,rows,cols 的關係(轉自http://blog.csdn.net/ik ...
  • abs(x) 求一個數的絕對值。 all(iterable) 如果迭代器中的所有值都為“真”則返回 True, 否則返回 False 註意: 如果迭代器為空,返回 True any(iterable) 如果迭代器中的任意一個值為“真”則返回 True, 否則返回 False 註意: 如果迭代器為空, ...
  • 格式化代碼: ^I 轉到定義:⌘D 註釋/反註釋: ⌘/ 生成:⌘B 重新生成:^⌘B 調試運行:⌘↩ 不調試運行:⌥⌘↩ 添加/刪除斷點:⌘\ 查看所有斷點:⌥⌘↩ 放大:⌘+ 縮小:⌘- 正常大小:⌘0 全屏/取消全屏:^⌘F 頁內搜索:⌘F 文件/項目內搜索:⇧⌘F 上一步操作游標:⌃⌘← 下 ...
  • 記錄了從查找Windows Live Writer上VSPasste插件丟失RTF格式信息問題的原因,到最終解決問題的整個經歷。 ...
  • 微軟在06月27日發佈了Visual Studio 2015 Update 3 。在MSDN中微軟也提供下載,而且MSDN的Visual Studio 2015 Update 3與官方免費下載的文件是一致的,只是文件名不一樣,除TFS除外。官方下載:https://www.visualstudio. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...