[開源 .NET 跨平台 Crawler 數據采集 爬蟲框架: DotnetSpider] [四] JSON數據解析


[DotnetSpider 系列目錄]

場景模擬

接上一篇, JD SKU對應的店鋪信息是異步加載的,因此無法使用上一篇的爬蟲直接解決。這時我們需要重新完全采集所有的SKU數據嗎?補爬的話歷史數據就用不了了。因此,去京東頁面上找看是否有提供相關的接口。

查找API請求接口

  1. 安裝 Fiddler, 並打開

  2. 在谷歌瀏覽器中訪問: http://list.jd.com/list.html?cat=1315,1343,9719

  3. 在Fiddler查找一條條的訪問記錄,找到我們想要的接口

    image

編寫爬蟲

  1. 分析返回的數據結果,我們可以先寫出數據對象的定義(觀察Expression的值已經是JsonPath查詢表達式了,同時Type必須設置為Type = SelectorType.JsonPath)。另外需要注意的是,這次的爬蟲是更新型爬蟲,就是說采集到的數據補充回原表,那么就一定要設置主鍵是什么,即在數據類上添加主鍵的定義

            [EntityTable("test", "jd_sku", EntityTable.Monday, Primary = "Sku", UpdateColumns = new[] { "ShopId" })]
            [EntitySelector(Expression = "$.[*]", Type = SelectorType.JsonPath)]
            class ProductUpdater : SpiderEntity
            {
                [PropertyDefine(Expression = "$.pid", Type = SelectorType.JsonPath, Length = 25)]
                public string Sku { get; set; }
    
                [PropertyDefine(Expression = "$.shopId", Type = SelectorType.JsonPath)]
                public int ShopId { get; set; }
            }

     

  2. 由於返回的數據中還有一個json()這樣的pagging,所以需要先做一個截取操作,框架提供了PageHandler接口,並且我們實現了許多常用的Handler,用於HTML的解析前的一些處理操作。PrepareStartUrls 接口是用來從數據源來獲取起始URL,而不需要把URL直接寫在代碼里。完整的代碼如下

        public class JdShopDetailSpider : EntitySpider
        {
            public JdShopDetailSpider() : base("JdShopDetailSpider", new Site())
            {
            }
    
            protected override void MyInit(params string[] arguments)
            {
                Identity = Identity ?? Guid.NewGuid().ToString();
                Downloader.AddAfterDownloadCompleteHandler(new SubContentHandler
                {
                    StartPart = "json(",
                    EndPart = ");",
                    StartOffset = 5,
                    EndOffset = 0
                });
    
                AddStartUrlBuilder(new DbStartUrlBuilder(Database.MySql,
                    "Database='mysql';Data Source=localhost;User ID=root;Password=;Port=3306;SslMode=None;",
                    $"SELECT * FROM test.jd_sku_{DateTimeUtils.MondayOfCurrentWeek.ToString("yyyy_MM_dd")} WHERE ShopName is null or ShopId is null or ShopId = 0 order by sku", new[] { "sku" },
                    "http://chat1.jd.com/api/checkChat?my=list&pidList={0}&callback=json"));
                AddPipeline(new MySqlEntityPipeline("Database='mysql';Data Source=localhost;User ID=root;Password=;Port=3306;SslMode=None;"));
                AddEntityType(typeof(ProductUpdater));
            }
    
            [EntityTable("test", "jd_sku", EntityTable.Monday, Primary = "Sku", UpdateColumns = new[] { "ShopId" })]
            [EntitySelector(Expression = "$.[*]", Type = SelectorType.JsonPath)]
            class ProductUpdater : SpiderEntity
            {
                [PropertyDefine(Expression = "$.pid", Type = SelectorType.JsonPath, Length = 25)]
                public string Sku { get; set; }
    
                [PropertyDefine(Expression = "$.shopId", Type = SelectorType.JsonPath)]
                public int ShopId { get; set; }
            }
        }

     

代碼地址

https://github.com/zlzforever/DotnetSpider 望各位大佬加星 😃

 

參與開發或有疑問

博文寫得比較早, 框架修改有時會來不及更新博文中的代碼, 請查看DotnetSpider.Sample項目中的樣例爬蟲

QQ群: 477731655

郵箱: zlzforever@163.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM