2016 Microsoft MVP アワードを受賞させていただきました

昨年に引き続き Visual Studio and Development Technologies の領域で MVP アワードを受賞させていただきました。

早いもので、Microsoft MVPを初受賞してから10年経ちました。

当時に比べると、IT業界も仕事内容もずいぶん変わりましたが、 Microsoft技術を通して受ける刺激や、素敵な知り合いが増える楽しさは変わらないと思っております。

引き続き情報の発信を継続できればと思います。

これからもよろしくお願いいたします。

受賞カテゴリの変遷
  1. 2006年~2010年:Solutions Architect
  2. 2010年~2011年:Visual C#
  3. 2011年~2015年:ASP.NET/IIS
  4. 2015年~現在:Visual Studio and Development Technologies
初受賞時のブログ(2006年)

aoki1210.hatenablog.jp

Abotでの「対象URL絞り込み」と「クロール毎イベント」

C#でWebサイトをクロールするライブラリの「Abot Web Crawler」の続きです。

aoki1210.hatenablog.jp

基本的な使い方は前回書いた通りですが、この記事では、URLのフィルタ方法とクロール時の基本イベントについて紹介します。

URLによる対象ページの絞り込み(条件設定)

URLを絞り込むには、Abot.DemoのGetCustomBehaviorUsingLambdaWebCrawlerが参考になります。デフォルトでは、呼び出し部分がコメントアウトされているので、呼び出すように設定すると、クロールするURLを条件に応じて絞り込むことができます。

private static IWebCrawler GetCustomBehaviorUsingLambdaWebCrawler()
{
    IWebCrawler crawler = GetDefaultWebCrawler();

    crawler.ShouldCrawlPage((pageToCrawl, crawlContext) =>
    {
        if (!pageToCrawl.Uri.AbsoluteUri.Contains("example.com/japan/"))
            return new CrawlDecision { Allow = false, Reason = "日本以外のページは不要" };

        return new CrawlDecision { Allow = true };
    });
}

クローリング毎のイベントとHTMLの取得

クロール時には、ここのURL毎にイベントを呼び出すことができます。Abotは複数のページを並行して取得することができるため、非同期のイベントとして登録します。

イベント登録
crawler.PageCrawlStartingAsync += crawler_ProcessPageCrawlStarting;
crawler.PageCrawlCompletedAsync += crawler_ProcessPageCrawlCompleted;
crawler.PageCrawlDisallowedAsync += crawler_PageCrawlDisallowed;
crawler.PageLinksCrawlDisallowedAsync += crawler_PageLinksCrawlDisallowed;
イベント毎に呼び出される処理
static void crawler_ProcessPageCrawlStarting(object sender, PageCrawlStartingArgs e)
{
    // クローリング前の処理
}

static void crawler_ProcessPageCrawlCompleted(object sender, PageCrawlCompletedArgs e)
{
    // クロールしてページを読み込んだ後の処理
    PageContent content = e.CrawledPage.Content;
    // 取得したHTMLを出力
    System.Console.WriteLine(content.Text);
}

static void crawler_PageLinksCrawlDisallowed(object sender, PageLinksCrawlDisallowedArgs e)
{
    // クロール対象ページのリンクが読み込めなかった時の処理
}

static void crawler_PageCrawlDisallowed(object sender, PageCrawlDisallowedArgs e)
{
    // クロール対象ページが読み込めなかった時の処理
}

AbotのQ&Aフォーラム

なお、質問は、GoogleGroupのフォーラムで行われています。

https://groups.google.com/forum/#!forum/abot-web-crawler

APIがバージョンごとに異なるので、最新の質問から回答を探したほうが効率的です。

C#のクローラーライブラリ「Abot」

C#でWebサイトをクロールするライブラリの「Abot Web Crawler」というものがありますので、そのメモです。

github.com

Abotとは

Abotはアリゾナ州のStevenさんが開発されているC#によるクローラー用ライブラリです。

商用・個人問わず使えるオープンソース(Apache License)で、早く、カスタマイズ可能で、軽量とのことです。

また、AbotXというサイトでは、プラグインも公開されています。 (プラグイン例:複数サイトをクロールする、Jsで実行、スケジュール実行、スピード調整等)

使い方

基本的には、Config設定を設定して、クラスライブラリを読み出すだけです。

Abotの使い方

1: Nugetを使って、Abotをインストールします。

2: using句で以下の名前空間を追加します。

using Abot.Crawler;
using Abot.Poco;

3(パターン1): コードで設定する場合

public CrawlConfiguration()
{
    MaxConcurrentThreads = 10;
    UserAgentString = "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko";
    RobotsDotTextUserAgentString = "abot";
    MaxPagesToCrawl = 1000;
    DownloadableContentTypes = "text/html";
    ConfigurationExtensions = new Dictionary<string, string>();
    MaxRobotsDotTextCrawlDelayInSeconds = 5;
    HttpRequestMaxAutoRedirects = 7;
    IsHttpRequestAutoRedirectsEnabled = true;
    MaxCrawlDepth = 100;
    HttpServicePointConnectionLimit = 200;
    HttpRequestTimeoutInSeconds = 15;
    IsSslCertificateValidationEnabled = true;
}

3(パターン2): コードではなく、App.config(Web.config)で設定する場合

  <abot>
    <crawlBehavior 
      maxConcurrentThreads="10" 
      maxPagesToCrawl="1000" 
      maxPagesToCrawlPerDomain="0" 
      maxPageSizeInBytes="0"
      userAgentString="Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko" 
      crawlTimeoutSeconds="0" 
      downloadableContentTypes="text/html, text/plain" 
      isUriRecrawlingEnabled="false" 
      isExternalPageCrawlingEnabled="false" 
      isExternalPageLinksCrawlingEnabled="false"
      httpServicePointConnectionLimit="200"  
      httpRequestTimeoutInSeconds="15" 
      httpRequestMaxAutoRedirects="7" 
      isHttpRequestAutoRedirectsEnabled="true" 
      isHttpRequestAutomaticDecompressionEnabled="false"
      isSendingCookiesEnabled="false"
      isSslCertificateValidationEnabled="false"
      isRespectUrlNamedAnchorOrHashbangEnabled="false"
      minAvailableMemoryRequiredInMb="0"
      maxMemoryUsageInMb="0"
      maxMemoryUsageCacheTimeInSeconds="0"
      maxCrawlDepth="1000"
      isForcedLinkParsingEnabled="false"
      maxRetryCount="0"
      minRetryDelayInMilliseconds="0"
      />
    <authorization
      isAlwaysLogin="false"
      loginUser=""
      loginPassword="" />     
    <politeness 
      isRespectRobotsDotTextEnabled="false"
      isRespectMetaRobotsNoFollowEnabled="false"
      isRespectHttpXRobotsTagHeaderNoFollowEnabled="false"
      isRespectAnchorRelNoFollowEnabled="false"
      isIgnoreRobotsDotTextIfRootDisallowedEnabled="false"
      robotsDotTextUserAgentString="abot"
      maxRobotsDotTextCrawlDelayInSeconds="5" 
      minCrawlDelayPerDomainMilliSeconds="0"/>
    <extensionValues>
      <add key="key1" value="value1"/>
      <add key="key2" value="value2"/>
    </extensionValues>
  </abot>  

4: クローリングの実行

//同期実行の場合
CrawlResult result = crawler.Crawl(new Uri("http://localhost:1111/")); 

//エラー制御
if (result.ErrorOccurred)
{
    Console.WriteLine("次のサイト {0} のクロールがエラーで終了しました: {1}", 
        result.RootUri.AbsoluteUri, result.ErrorException.Message);
}
else
{
    Console.WriteLine("次のサイト {0} のクロールが正常終了しました", result.RootUri.AbsoluteUri);
}

Gitから取得できるコードについて

Gitからコードをクローンすると、ライブラリに加え、サンプルソースを入手できます。

f:id:aoki1210:20160418144445p:plain

デモプロジェクトの実行

「Abot.Demo」をスタートアッププロジェクトに設定して実行すると、URLを入力するコマンドプロンプトが表示されます。 URLを入力すると、そのサイトのクロールが行われ、Binフォルダにlog4netのログが出力されます。

参照ライブラリについて

Abotが使用しているライブラリは、以下の通りです。CsQueryとNRobotsPatched は知らないライブラリでしたので、リンクを張っておきます。

Azure WebAppsのKuduでcurlコマンドを実行する

kuduでgzファイルをダウンロードしようと思って、curlコマンドを使ったのですが、エラーでした。 少し調べました。

curl -O http://<ドメイン>/files.7z

がダメでした

github.com

によれば

curl -Ss -O -L http://<ドメイン>/files.7z

であればOKとのこと。確かにOKでした。

ASP.NET 5のサンプル「Music Store」

この記事は、ASP.NET 2015 Advent Calendarの12/23分の記事です。

現在大詰めに入ってきているASP.NET5ですが、学習サンプルとして参考にできる「Music Store」の紹介です。

Music Storeについて

ASP.NETのMusic Storeの歴史は古く、2010年4月に0.8バージョンが公開されたところにさかのぼります。

Music Storeは、当時馴染みに薄かったMVCを学べる「音楽アルバムを販売するサイト」のチュートリアルで、Visual Studio 2010と、ASP.NET MVC2.0、Entity Framwork4.0を使って開発できるようになっていました。以下の様な内容が含まれていました。

  • ASP.NET MVCのテンプレート, データアノテーション, バリデーション(Webサイトでの表示機能と更新機能)
  • ショッピングカート、会員制、チェックアウト購入
  • Entity Frameworkによるデータアクセス


このサンプルプロジェクトは、CodePlexにてアップデートされ、2011年にバージョン3.0まで公開されており、
井上さんによって日本語版も公開され、ASP.NET MVCを学ぶ際の重要なリソースとなっていました。
ただ、残念ながら、2011年以降は、アップデートが止まっていました。



GitHubで公開されている最新のMusic Store

ASP.NET5の開発が行われるにあたり、サンプルとしてGitHubの以下のリポジトリで公開されるようになりました。
https://github.com/aspnet/MusicStore.git

サンプルを実行するには、Visual Studio2015とSQL ServerのLocalDBが必要です。
Visual Studioがない場合にはコマンドラインから実行することもできます。)

機能や画面の仕様などは同じですが、実装方法は最新のASP.NET MVCに対応しているので、参考にしてみてはいかがでしょうか。


最後に

はてなブログに引っ越してみたので、テスト投稿(DDD本について)

実践ドメイン駆動設計

実践ドメイン駆動設計

DDDへの誘い

デザインとは、単なる見た目や操作性のことではない。デザインとは、それがどのように動作するかということだ

DDDとは

ドメイン駆動設計というソフトウェア開発手法。 バグがないというさらに、その先に、ビジネス的な意図を明確に反映している素晴らしいソフトを作ること。

誰にでもできるのか

最初は難しいだろう。 ただ、業務を理解できるのなら、ユビキタス言語を生み出すことはできる。 ドメインエキスパートとの会話には大きなメリットがある。

ただ、以下の本のような、技術的なことも理解したほうが良い が、最低限の知識があれば、始めることができる。

Head Firstデザインパターン ―頭とからだで覚えるデザインパターンの基本

Head Firstデザインパターン ―頭とからだで覚えるデザインパターンの基本

オブジェクト指向における再利用のためのデザインパターン

オブジェクト指向における再利用のためのデザインパターン

DDDのメリット

Mac版VirtualBox5のフルスクリーンでメニューバーを非表示にする設定(ゲストOS:Windows10)

MacVirtualBox 5にWindows10を入れて使っていますが、最大化表示(フルスクリーン設定)しても、画面の上部にマウスカーソルを持って行くと、Macのメニューバーが表示されてしまいます。
ゲストOSに集中して操作するには使い勝手が少々悪いです。

メニューを非表示にする設定を調べてみたところ、以下のフォーラムに書いていました。

https://forums.virtualbox.org/viewtopic.php?f=2&t=21676 (の一番下)

この方法だと、確かにメニューは出なくなります。ただ、ゲストOSに限らず、すべてのVirutalBoxのアプリでメニューが非表示になります。
そのため、必要な設定があったりする場合は、たまに元の設定に戻さないといけないかもしれません。


簡単にまとめると以下の手順となります。
info.plistファイルを触りますので、自己責任という感じです。

  1. Finderでアプリケーションを開く
  2. VirtualBox.appを右クリックして、「パッケージの内容を表示」
  3. Contents/Resourcesまで行き、VirtualBoxVM.appを右クリックして 「パッケージの内容を表示」
  4. ContentsにInfo.plistがあるので、デスクトップにコピーする(権限があれば直接編集できるかも)
  5. テキストエディタで編集して、"LSCanProvideIMVideoDataSource"と "NSHighResolutionCapable"の間に以下の文言を追加する
    • LSUIElement 1
  6. 保存して、もとのInfo.plistに上書き保存する(管理者権限のパスワードを入力する)
  7. この設定はメモリに保存されるそうなので、一度Macをログオフして、再度ログインする

ちなみに、最大化でメニューが非表示となっても、ショートカットキーは有効です。最大化モードやスケールモードなどを切り替えたいときは、あらかじめ設定しているショーットカットキーをメモしておいて使うと良さそうです。
また、MacVirtualBoxのデフォルトホストキーは左コマンドボタンです。Windowsでは、ホストキーを右コマンドボタンにしておくことをおすすめします。そうすると左コマンドボタンが、Windowsキーになります。