在进行数据采集模块开发以前咱们先来看看制做好管理界面效果图:css
数据采集管理和监控界面:html
数据源配置界面:web
根据需求分析列出所须要作的事以下表:正则表达式
数据采集sql |
|
序号数据库 |
任务说明缓存 |
1工具 |
建立WebCrawler模块网站 |
2ui |
定义一个名为 CrawlerArticle 的内容类型来存放采集来的文章。在该内容类型中同时包含如下字段,便于前台以为展示方式。 SourceName:数据源名称 SourceUrl: 数据源地址 OpenStyle:打开方式(当前窗口或者新窗口) ArticleTime:文稿数据(数据源自己建立的时间不是在在本平台中写入的时间) Visits:访问量原网站该文章的访问量 |
3 |
建立用于存放数据源 地址、采集规则。以及采集任务执行策略的表,并提供管理界面。 数据源(CrawlerSourcePart)结构以下: SourceName:数据源名称 SourceHost:数据源网站域名(即网站的根地址如:http://www.baidu.com/ SourceUrl:数据源地址,指具体冲网站的那一个页面采集数据 LastCrawlerUrl:最后一次访问的Url Enabled:当前数据源是否启用. 采集策略配置(CrawlerSettingsPart)以下: Interval 执行间隔时间 Thumbnail 缩略图比例(采集到的内容中的图片将按照该比例处理成文章缩略图) Ignore 忽略少年前的数据 采集规则配置(CrawlerRulePart)以下: SourceID 数据源ID与CrawlerSourcePart关联 Behavior 采集行为,指采集的是标题,仍是日期,仍是访问量等,本项目中只须要用到采集数据表格的容器,以及详细内容,标题、日期等。 Expression 对应与采集行为的正则表达式. 数据源默认图片配置表(DefaultImagePart)以下: SourceID 关联数据源ID ImageUrl 图片路径数据采集在采集到没有图片的文稿时候会从数据源默认图片中选择图片做为列表中显示的文稿缩略图以下图:’
|
4 |
编写任务调度器,以及具体采集执行的代码。 |
在开始开发数据采集Module以前咱们先来看看,Orchard Module的项目结构。在使用Orchard 命令行工具建立Module之后,在解决方案中会多出一个新的项目,项目结构以下图:
Assets:资源文件,用来存放模块用到的JS、样式、图片等静态资源文件夹,该资源文件夹下面必须包含一个web.config用于标识该文件夹是静态资源的文件夹,Orchard才会到这个文件夹查找css样式 JS脚本等。该代码以下:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <staticContent> <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" /> </staticContent> <handlers accessPolicy="Script,Read"> <!-- iis7 - for any request to a file exists on disk, return it via native http module. accessPolicy 'Script' is to allow for a managed 404 page. --> <add name="StaticFile" path="*" verb="*" modules="StaticFileModule" preCondition="integratedMode" resourceType="File" requireAccess="Read" /> </handlers> </system.webServer> </configuration>
另外一般该文件夹只会在模版中用到。
Controllers:控制器文件夹,用于存放MVC模块的控制器。
Drivers:驱动器,用于为ContentPart提供显示和编辑的视图。Orchard使用了一个叫Shape的概念,相似于MVC中的视图。
Handlers:提供ContentPart变化的事件监听。有以下事件:
OnInitializing:ContentPart初始时 促发该事件
OnRemoved:ContentPart删除时候触发该事件
能够利用这些事件来作相应的业务逻辑处理,例如能够用 OnInitializing事件来为ContentPart提供默认值。能够用OnRemoved事件来在ContentPart删除时候进行数据清理、缓存移除等操做。Handlers还包含其余的事件,能够参考官方资料.
Models:实体类即数据库实体类,存放ContentPart的各个属性Models分为ContentPart(用于Drivers肯定显示和编辑的样式)以及ContentPartRecord(用于Nhibrerate的数据映射)。ContentPartRecord的各个属性并需用 virtual关键字来修饰。
ViewModels:视图实体类
Services:模块服务类局放于该文件夹,提供业务逻辑,以及数据库操做。
Views:视图文件夹。存放cshtml页面。
Orchard建立Module能够经过命令行来建立
首先进入Orchard的部署目录中找到Orchard.exe(在bin目录中) 用命令行打开。以下图:
打开Orchard命令行之后输入:
Orchard> codegen module WebCrawler
注:若是执行错误,则须要先启用 Codegen模块
执行以上指令之后Orchard将会在Module文件夹中建立名为 WebCrawler的一个项目。从新源代码解决方案Orchard.sln便可在解决方案的看到该项目。以下图:
Module建立好之后接下来建立 Migrations 类,该类用于安装或升级Module时候进行ContentType定义、ContentPart定义、以及数据表的建立等。执行如下Orchard命令行来建立该类。
Orchard > codegen datamigration WebCrawler
首次建立好 Migrations类之后该类中会有一个Create方法,若是之后须要对Module升级只需建立一个 UpdateFrom1的方法,而且返回 2,再次升级则再建立一个方法UpdateFrom2 返回3 依次类推。
public int Create()//首次建立 { return 1; } public int UpdateFrom1()//第一次升级 { return 2; } public int UpdateFrom2()//第二次升级 { return 3; } public int UpdateFrom3()//第三次升级 { return n; } public int UpdateFromN()//第N次升级 { return n+1; }
Orchard会自动检查当前模块是否须要升级,升级Module会调用最新的UpdateFrom方法。并在Orchard_Framework_DataMigrationRecord表中记录相应的版本信息。以下图:
接下来在Migrations类中定义WebCrawler Module所须要的ContentPart以及要建立的数据库表。
定义用于存储经过数据采集而来的文稿的内容类型。该内容类型首先是须要有标题、有主体、还能够有评论。须要进行版本管理、须要有进行列表显示,须要能够被建立。同时该类型还有一些其余的附加属性。这个类型由TitlePart、BodyPart、TagsPart、CommentsPart(评论)等ContentPart组成。定义该类型的代码以下:
ContentDefinitionManager.AlterTypeDefinition("CrawlerArticle", cfg => cfg .Creatable()//容许建立 .Listable()//运行显示列表 .Draftable()//容许版本管理 .Securable() .WithPart("TitlePart")//附加TitlePart .WithPart("BodyPart")//附加BodyPart .WithPart("TagsPart")//附加TagsPart .WithPart("CrawlerArticle")//附加他自身的Part没类型都有一个与类型同名的Part .WithPart("CommentsPart")//附加CommentsPart .WithSetting("Description", "")//对类型进行备注说明 );
定义CrawlerArticlePart内容部件并为其添加扩展字段。代码以下:
ContentDefinitionManager.AlterPartDefinition("CrawlerArticle", part => part .WithField("SourceName", cfg => cfg .WithDisplayName("文稿来源") .OfType("TextField") .WithSetting("TextField.Required", "True")) .WithField("SourceUrl", cfg => cfg .WithDisplayName("源地址") .OfType("TextField").WithSetting("TextField.Required", "True")) .WithField("Thumbnail", cfg => cfg .WithDisplayName("缩略图") .OfType("TextField") .WithSetting("TextField.Required", "False")) .WithField("OpenStyle", cfg => cfg .WithDisplayName("打开方式") .OfType("EnumerationField") .WithSetting("EnumerationFieldSettings.Required", "True") .WithSetting("EnumerationFieldSettings.Options", "当前窗口\r\n新窗口")) .WithField("ArticleTime", cfg => cfg .WithDisplayName("文稿日期") .OfType("TextField") .WithSetting("EnumerationFieldSettings.Required", "False")) );
上面定义了名为CrawlerArticle的内容类型,并定义如下字段:
SourceName:用于存放该文稿的来源名称。
SourceUrl: 文稿的原始地址。
OpenStyle:打开方式,这是一个枚举字段用于决定点击该文稿时候,是在当前窗口打开仍是新窗口打开。有两个枚举值“当前窗口”和“新窗口”。
ArticleTime:文稿时间。
内容部件扩展字段的定义存放在[Settings_ContentPartFieldDefinitionRecord]表中。定义好这些文稿类型以及内容部件,而且Orchard安装了该模块之后在后台管理系统如下结果:
首先在Module中多出来名为 WebCrawler的模块,在这里能够进行启用和停用。
接下来定义数据采集所须要用到的数据表。数据采集须要用到数据源表(ClawlerSource)、采集规则表(ClawlerRule)、数据采集全局设置表(ClawlerSetting)、数据源默认图片表(DefaultImage)。下面以建立数据源集合表为例加以说明:
建立数据源集合表
SchemaBuilder.CreateTable("CrawlerSourcePartRecord", table => table
.ContentPartRecord()
.Column("SourceName", DbType.String)
.Column("SourceUrl", DbType.String)
.Column("LastCrawlUrl", DbType.String)
.Column("Enabled", DbType.Byte)
.Column("MenuID", DbType.String)
);
当Orchard执行该代码之后数据库中就会多一个名为WebClawler_ClawlerSourcePartRecord的表。
定义数据源内容类型
ContentDefinitionManager.AlterTypeDefinition("CrawlerSource", cfg => cfg
.WithPart(typeof(CrawlerSourcePart).Name)
.WithPart("IdentityPart")
.WithPart("CommonPart")
.WithSetting("Description", "数据源")
);
定义数据采集全局设置内容类型
ContentDefinitionManager.AlterTypeDefinition("CrawlerSetting", cfg => cfg
.WithPart(typeof(CrawlerSettingPart).Name)
.WithPart("IdentityPart")
.WithPart("CommonPart")
.WithSetting("Description", "数据采集全局配置")
);
定义采集规则内容类型
ContentDefinitionManager.AlterTypeDefinition("CrawlerRule", cfg => cfg
.WithPart(typeof(CrawlerRulePart).Name)
.WithPart("IdentityPart")
.WithPart("CommonPart")
.WithSetting("Description", "数据采集采集规则")
);
定义默认图片内容类型
ContentDefinitionManager.AlterTypeDefinition("DefaultImage", cfg => cfg
.WithPart(typeof(DefaultImagePart).Name)
.WithPart(typeof(IdentityPart).Name)
.WithPart(typeof(CommonPart).Name)
.WithSetting("Description", "数据源默认图片")
);
定义对应的Part
ContentDefinitionManager.AlterPartDefinition("CrawlerSourcePart", builder => builder
.Attachable()
.WithDescription("数据源定义")
);
ContentDefinitionManager.AlterPartDefinition("CrawlerSettingPart", builder => builder
.Attachable()
.WithDescription("数据采集全局配置信息")
);
ContentDefinitionManager.AlterPartDefinition("CrawlerRulePart", builder => builder
.Attachable()
.WithDescription("采集规则定义")
);