[开源 .NET 跨平台 Crawler 数据采集 爬虫框架: DotnetSpider] [四] JSON数据解析
[DotnetSpider 系列目录]
场景模拟
接上一篇, JD SKU对应的店铺信息是异步加载的,因此无法使用上一篇的爬虫直接解决。这时我们需要重新完全采集所有的SKU数据吗?补爬的话历史数据就用不了了。因此,去京东页面上找看是否有提供相关的接口。
查找API请求接口
-
安装 Fiddler, 并打开
-
在Fiddler查找一条条的访问记录,找到我们想要的接口
编写爬虫
-
分析返回的数据结果,我们可以先写出数据对象的定义(观察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; } }
-
由于返回的数据中还有一个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
posted on 2016-08-03 08:36 Lewis.Zou 阅读(6527) 评论(12) 编辑 收藏 举报