3.使用Orchard扩展数据采集模块

在进行数据采集模块开发之前我们先来看看制作好管理界面效果图:

数据采集管理和监控界面:

数据源配置界面:

根据需求分析列出所需要做的事如下表:

 

数据采集

序号

任务说明

1

创建WebCrawler模块

2

定义一个名为 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

编写任务调度器,以及具体采集执行的代码。

3.1 Module项目结构介绍

在开始开发数据采集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页面。

3.2 开始创建Module

Orchard创建Module可以通过命令行来创建

首先进入Orchard的部署目录中找到Orchard.exe(在bin目录中) 用命令行打开。如下图:

打开Orchard命令行以后输入:

 Orchard> codegen module WebCrawler
注:如果执行错误,则需要先启用 Codegen模块

 

执行以上指令以后Orchard将会在Module文件夹中创建名为 WebCrawler的一个项目。重新源代码解决方案Orchard.sln即可在解决方案的看到该项目。如下图:

3.3创建Migrations类

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组成。定义该类型的代码如下:

定义 CrawlerArticle内容类型:

  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的表。

 

创建数据采集管理所需的ContentPart

定义数据源内容类型

    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("采集规则定义")

            );

 

posted @ 2016-04-18 10:02  Fisherq.Boy  阅读(849)  评论(4编辑  收藏  举报