[DotnetSpider 系列目录]

上一篇介绍的基本的使用方式,自由度很高,但是编写的代码相对就多了。而我所在的行业其实大部分都是定题爬虫, 只需要采集指定的页面并结构化数据。为了提高开发效率, 我实现了利用实体配置的方式来实现爬虫

创建 Console 项目

利用NUGET添加包

DotnetSpider2.Extension

定义配置式数据对象

  • 数据对象必须继承 SpiderEntity
  • EntityTableAttribute中可以定义数据名称、表名及表名后缀、索引、主键或者需要更新的字段
  • EntitySelector 定义从页面数据中抽取数据对象的规则
  • TargetUrlsSelector定义符合规则(正则)的目标链接, 用于加入到队列中

定义一个原始的数据对象类

  1. public class Product : SpiderEntity
  2. {
  3. }
使用Chrome打开京东商品页 http://list.jd.com/list.html?cat=9987,653,655&page=2&JL=6_0_0&ms=5#J_main
  1. 使用快捷键F12打开开发者工具
  2. 选中一个商品,并观察Html结构

可以看到每个商品都在class为gl-i-wrap j-sku-item的DIV下面,因此添加EntitySelector到数据对象Product的类名上面。( XPath的写法不是唯一的,不熟悉的可以去W3CSCHOLL学习一下, 框架也支持使用Css甚至正则来选择出正确的Html片段)。

   

  1. [EntitySelector(Expression = "//li[@class='gl-item']/div[contains(@class,'j-sku-item')]")]
  2. public class Product : SpiderEntity
  3. {
  4. }
  1. 添加数据库及索引信息

    1. [EntityTable("test", "sku", EntityTable.Monday, Indexs = new[] { "Category" }, Uniques = new[] { "Category,Sku", "Sku" })]
    2. [EntitySelector(Expression = "//li[@class='gl-item']/div[contains(@class,'j-sku-item')]")]
    3. public class Product : SpiderEntity
    4. {
    5. }
  2. 假设你需要采集SKU信息,观察HTML结构,计算出相对的XPath, 为什么是相对XPath?因为EntitySelector已经把HTML截成片段了,内部的Html元素查询都是相对于EntitySelector查询出来的元素。最后再加上数据库中列的信息

    1. [EntityTable("test", "sku", EntityTable.Monday, Indexs = new[] { "Category" }, Uniques = new[] { "Category,Sku", "Sku" })]
    2. [EntitySelector(Expression = "//li[@class='gl-item']/div[contains(@class,'j-sku-item')]")]
    3. public class Product : SpiderEntity
    4. {
    5. [PropertyDefine(Expression = "./@data-sku")]
    6. public string Sku { get; set; }
    7. }
  3. 爬虫内部,链接是通过Request对象来存储信息的,构造Request对象时可以添加额外的属性值,这时候允许数据对象从Request的额外属性值中查询数据

    1. [EntityTable("test", "sku", EntityTable.Monday, Indexs = new[] { "Category" }, Uniques = new[] { "Category,Sku", "Sku" })]
    2. [EntitySelector(Expression = "//li[@class='gl-item']/div[contains(@class,'j-sku-item')]")]
    3. public class Product : SpiderEntity
    4. {
    5. [PropertyDefine(Expression = "./@data-sku")]
    6. public string Sku { get; set; }
    7.  
    8. [PropertyDefine(Expression = "name", Type = SelectorType.Enviroment)]
    9. public string Category { get; set; }
    10. }
配置爬虫(继承EntitySpider)
  1. public class JdSkuSampleSpider : EntitySpider
  2. {
  3. public JdSkuSampleSpider() : base("JdSkuSample", new Site
  4. {
  5. //HttpProxyPool = new HttpProxyPool(new KuaidailiProxySupplier("快代理API"))
  6. })
  7. {
  8. }
  9.  
  10. protected override void MyInit(params string[] arguments)
  11. {
  12. Identity = Identity ?? "JD SKU SAMPLE";
  13.  
  14. ThreadNum = ;
  15. // dowload html by http client
  16. Downloader = new HttpClientDownloader();
  17.  
  18. // storage data to mysql, default is mysql entity pipeline, so you can comment this line. Don't miss sslmode.
  19. AddPipeline(new MySqlEntityPipeline("Database='mysql';Data Source=localhost;User ID=root;Password=;Port=3306;SslMode=None;"));
  20. AddStartUrl("http://list.jd.com/list.html?cat=9987,653,655&page=2&JL=6_0_0&ms=5#J_main", new Dictionary<string, object> { { "name", "手机" }, { "cat3", "" } });
  21. AddEntityType<Product>();
  22. }
  23. }
  1. 其中AddStartUrl第二个参数Dictionary<string, object>就是用于Enviroment查询的数据

  2. TargetUrlsSelector,可以配置数据链接的合法性验证,以及目标URL的获取。如下表示目标URL的获取区域是由XPATH选择,并且要符合正则表达式 &page=[0-9]+&

    1. [EntityTable("test", "jd_sku", EntityTable.Monday, Indexs = new[] { "Category" }, Uniques = new[] { "Category,Sku", "Sku" })]
    2. [EntitySelector(Expression = "//li[@class='gl-item']/div[contains(@class,'j-sku-item')]")]
    3. [TargetUrlsSelector(XPaths = new[] { "//span[@class=\"p-num\"]" }, Patterns = new[] { @"&page=[0-9]+&" })]
    4. public class Product : SpiderEntity
    5. {
    6. [PropertyDefine(Expression = "./@data-sku")]
    7. public string Sku { get; set; }
    8.  
    9. [PropertyDefine(Expression = "name", Type = SelectorType.Enviroment)]
    10. public string Category { get; set; }
    11. }

  1. 添加一个MySql的数据管道,只需要配置好连接字符串即可

    1. context.AddPipeline(new MySqlEntityPipeline("Database='test';Data Source=localhost;User ID=root;Password=1qazZAQ!;Port=3306"));
完整代码
  1. public class JdSkuSampleSpider : EntitySpider
  2. {
  3. public JdSkuSampleSpider() : base("JdSkuSample", new Site
  4. {
  5. //HttpProxyPool = new HttpProxyPool(new KuaidailiProxySupplier("快代理API"))
  6. })
  7. {
  8. }
  9.  
  10. protected override void MyInit(params string[] arguments)
  11. {
  12. Identity = Identity ?? "JD SKU SAMPLE";
  13.  
  14. ThreadNum = ;
  15. // dowload html by http client
  16. Downloader = new HttpClientDownloader();
  17.  
  18. // storage data to mysql, default is mysql entity pipeline, so you can comment this line. Don't miss sslmode.
  19. AddPipeline(new MySqlEntityPipeline("Database='mysql';Data Source=localhost;User ID=root;Password=;Port=3306;SslMode=None;"));
  20. AddStartUrl("http://list.jd.com/list.html?cat=9987,653,655&page=2&JL=6_0_0&ms=5#J_main", new Dictionary<string, object> { { "name", "手机" }, { "cat3", "" } });
  21. AddEntityType<Product>();
  22. }
  23. }
  24.  
  25. [EntityTable("test", "jd_sku", EntityTable.Monday, Indexs = new[] { "Category" }, Uniques = new[] { "Category,Sku", "Sku" })]
  26. [EntitySelector(Expression = "//li[@class='gl-item']/div[contains(@class,'j-sku-item')]")]
  27. [TargetUrlsSelector(XPaths = new[] { "//span[@class=\"p-num\"]" }, Patterns = new[] { @"&page=[0-9]+&" })]
  28. public class Product : SpiderEntity
  29. {
  30. [PropertyDefine(Expression = "./@data-sku", Length = )]
  31. public string Sku { get; set; }
  32.  
  33. [PropertyDefine(Expression = "name", Type = SelectorType.Enviroment, Length = )]
  34. public string Category { get; set; }
  35.  
  36. [PropertyDefine(Expression = "cat3", Type = SelectorType.Enviroment)]
  37. public int CategoryId { get; set; }
  38.  
  39. [PropertyDefine(Expression = "./div[1]/a/@href")]
  40. public string Url { get; set; }
  41.  
  42. [PropertyDefine(Expression = "./div[5]/strong/a")]
  43. public long CommentsCount { get; set; }
  44.  
  45. [PropertyDefine(Expression = ".//div[@class='p-shop']/@data-shop_name", Length = )]
  46. public string ShopName { get; set; }
  47.  
  48. [PropertyDefine(Expression = ".//div[@class='p-name']/a/em", Length = )]
  49. public string Name { get; set; }
  50.  
  51. [PropertyDefine(Expression = "./@venderid", Length = )]
  52. public string VenderId { get; set; }
  53.  
  54. [PropertyDefine(Expression = "./@jdzy_shop_id", Length = )]
  55. public string JdzyShopId { get; set; }
  56.  
  57. [PropertyDefine(Expression = "Monday", Type = SelectorType.Enviroment)]
  58. public DateTime RunId { get; set; }
  59. }
运行爬虫
  1. public class Program
  2. {
  3. public static void Main(string[] args)
  4. {
  5. JdSkuSampleSpider spider = new JdSkuSampleSpider();
  6. spider.Run();
  7. }
  8. }

不到57行代码完成一个爬虫,是不是异常的简单?

代码地址

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

参与开发或有疑问

博文写得比较早, 框架修改有时会来不及更新博文中的代码, 请查看DotnetSpider.Sample项目中的样例爬虫

QQ群: 477731655

邮箱: zlzforever@163.com

[开源 .NET 跨平台 数据采集 爬虫框架: DotnetSpider] [三] 配置式爬虫的更多相关文章

  1. [开源 .NET 跨平台 Crawler 数据采集 爬虫框架: DotnetSpider] [三] 配置式爬虫

    [DotnetSpider 系列目录] 一.初衷与架构设计 二.基本使用 三.配置式爬虫 四.JSON数据解析与配置系统 五.如何做全站采集 上一篇介绍的基本的使用方式,自由度很高,但是编写的代码相对 ...

  2. [开源 .NET 跨平台 数据采集 爬虫框架: DotnetSpider] [一] 初衷与架构设计

    [DotnetSpider 系列目录] 一.初衷与架构设计 二.基本使用 三.配置式爬虫 四.JSON数据解析与配置系统 为什么要造轮子 同学们可以去各大招聘网站查看一下爬虫工程师的要求,大多是招JA ...

  3. [开源 .NET 跨平台 Crawler 数据采集 爬虫框架: DotnetSpider] [一] 初衷与架构设计

    [DotnetSpider 系列目录] 一.初衷与架构设计 二.基本使用 三.配置式爬虫 四.JSON数据解析与配置系统 五.如何做全站采集 为什么要造轮子 同学们可以去各大招聘网站查看一下爬虫工程师 ...

  4. [开源 .NET 跨平台 Crawler 数据采集 爬虫框架: DotnetSpider] [五] 如何做全站采集?

    [DotnetSpider 系列目录] 一.初衷与架构设计 二.基本使用 三.配置式爬虫 四.JSON数据解析与配置系统 五.如何做全站采集 如何做全站采集? 很多同学加群都在问, 如何使用Dotne ...

  5. [开源 .NET 跨平台 数据采集 爬虫框架: DotnetSpider] [二] 基本使用

    [DotnetSpider 系列目录] 一.初衷与架构设计 二.基本使用 三.配置式爬虫 四.JSON数据解析与配置系统 使用环境 Visual Studio 2015 or later .NET 4 ...

  6. [开源 .NET 跨平台 数据采集 爬虫框架: DotnetSpider] [四] JSON数据解析

    [DotnetSpider 系列目录] 一.初衷与架构设计 二.基本使用 三.配置式爬虫 四.JSON数据解析与配置系统 场景模拟 假设由于漏存JD SKU对应的店铺信息.这时我们需要重新完全采集所有 ...

  7. [开源 .NET 跨平台 Crawler 数据采集 爬虫框架: DotnetSpider] [四] JSON数据解析

    [DotnetSpider 系列目录] 一.初衷与架构设计 二.基本使用 三.配置式爬虫 四.JSON数据解析与配置系统 五.如何做全站采集 场景模拟 接上一篇, JD SKU对应的店铺信息是异步加载 ...

  8. [开源 .NET 跨平台 Crawler 数据采集 爬虫框架: DotnetSpider] [二] 基本使用

    [DotnetSpider 系列目录] 一.初衷与架构设计 二.基本使用 三.配置式爬虫 四.JSON数据解析与配置系统 五.如何做全站采集 使用环境 Visual Studio 2017 .NET ...

  9. 爬虫框架: DotnetSpider

    [开源 .NET 跨平台 数据采集 爬虫框架: DotnetSpider] [一] 初衷与架构设计 一 ,为什么要造轮子 有兴趣的同学可以去各大招聘网站看一下爬虫工程师的要求,大多是JAVA,PYTH ...

随机推荐

  1. [PCB制作] 1、记录一个简单的电路板的制作过程——四线二项步进电机驱动模块(L6219)

    前言 现在,很多人手上都有一两个电子设备,但是却很少有人清楚其中比较关键的部分(PCB电路板)是如何制作出来的.我虽然懂点硬件,但是之前设计的简单系统都是自己在万能板上用导线自己焊接的(如下图左),复 ...

  2. Ubuntu环境搭建系列—Chrome/JDK/Android篇

    其实每次重装Ubuntu系统的时候都要进行一次基本到环境配置,而且每次总会忘记一些环境配置到东西,所以就写下这个博文,方便自己以后重装系统的时候回顾,同时也给大家做为重装系统后基本环境搭建的参考. 因 ...

  3. Linux下安装Apache并以mod_wsgi方式部署django站点

    源码编译方式安装Apache 首先下载Apache源码压缩包,地址为http://mirror.bit.edu.cn/apache/httpd/ 继续下载apr和apr-util压缩包,地址为http ...

  4. MySQL记录

    1.unixtime和可读时间的转换 unixtime是距"1970-01-01 08:00:00"的时间秒数 unixtime -> readable select fro ...

  5. Git学习笔记(1)——安装,配置,创建库,文件添加到库

    初次接触git,为了记忆深刻,把学习的简单流程记录下来. 本文记录了Git在Ubuntu上的安装,配置,以及创建版本库和往库中添加文件的过程. 1.Git的安装:(Ubuntu-Linux非常友好的安 ...

  6. IOS Animation-Sprite Kit(一)基础

    介绍 Sprite Kit是IOS7开始引入的,是一个高效率渲染的2D图形框架.它与绘制图形的Core Graphics以及用来管理GUI元素动画属性的Core Animation不同,Sprite ...

  7. 好脑袋不如烂笔头-Quartz使用总结

    Quartz是Java平台的一个开源的作业调度框架.Quartz.net是从java版本移植到.net版本的..net项目使用Quartz来执行批处理等定时任务非常方便. (1)从nuget上可以安装 ...

  8. vs2013中的“任务列表”菜单

    以前在java项目中经常用到todo. 现在vs2013也完美支持了. 首先,对于目前不确定而尚需完善的代码,在前面加 //TODO:by who --注释文字,比如: //TODO:lhl--类目I ...

  9. Yii 框架学习--01 框架入门

    Yii 是一个高性能的,适用于开发 WEB2.0 应用的 PHP 框架. Yii目前有两个主要的版本: 2.0 和 1.1.本文以YII 2.0.7为例. 环境需求 Yii2.0 框架有一些系统上的需 ...

  10. 大数据时代的IT架构设计

    大数据时代的IT架构设计(来自互联网.银行等领域的一线架构师先进经验分享) IT架构设计研究组 编著   ISBN 978-7-121-22605-2 2014年4月出版 定价:49.00元 208页 ...