トップ   編集 凍結解除 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索   ヘルプ   最終更新のRSS

ブログ検索システム

Last-modified: 2012-06-09 (土) 02:03:24
Top / ブログ検索システム

※ 以下は限定公開のドキュメントが多いです。ご不便おかけします。

RSSを使ったブログ・Wikiの解析

ブログ検索システム

URLデータベース設計

  • MySQL のデータベース mkouki を使います。
    mysql -u root -p
    (パスワード)
    use mkouki;

RSSテーブル

RSSのアドレスのIDRSSのアドレス
rss_idrss_url
  • テーブルを作る
    CREATE TABLE mysearch_rss( rss_id int auto_increment, 
     rss_url text character set utf8, index(rss_id) );
    show tables;
  • データを追加
    INSERT INTO mysearch_rss (rss_url)
    VALUE('http://shower.human.waseda.ac.jp/~m-kouki/blog/atom.xml');
    INSERT INTO mysearch_rss (rss_url)
    VALUE('http://shower.human.waseda.ac.jp/~m-kouki/pukiwiki/index.php?cmd=rss&ver=1.0');
    select * from mysearch_rss limit 30;
    • ここでは、手動でブログとwikiのRSSのアドレスを入れました。オートインクリメントで、rss_id は自動的に番号がつきます。

エントリーテーブル

エントリーのIDエントリーのタイトルエントリーのアドレスエントリーの属性エントリーがインデクシング済みかどうか
entry_identry_titleentry_urlentry_typeentry_indexing
  • エントリーの属性は、とりあえず「記事0、書類1、プログラム2」と決めます。
  • インデクシングがまだなら0、済みなら1、とりあえず今回のシステムでは全文検索をするので、以下は全て0を代入します。
  • テーブルを作る
    CREATE TABLE mysearch_entry( entry_id int auto_increment,
     entry_title text character set utf8,
     entry_url text character set utf8,
     entry_type int, entry_indexing int, index(entry_id) );
  • RSSでは取得できない、トップページ以下のURLを、とりあえず手動で追加します。 → コマンド
    select entry_id, entry_title, entry_type from mysearch_entry limit 30;

クローリング

URLデータ更新

  • RSSのURLを参考に、各エントリーのタイトルとURLを取得して、テーブル mysearch_entry に格納します。
  • プログラムの格納場所は、shower の mysearch/ とします。
  • entry_url カラムの設定を「重複禁止」にしておけば、重複のチェックは不要のようです。

本文データ更新

  • エントリーのURLを参考に、本文(とりあえずソースコード全て)を取得して、テキストファイルとして保存します。
    • テキストファイル置き場を作って
      mkdir /home/m-kouki/mysearch/filelog
    • CrawlEntry.java を実行
      chmod 755 /home/m-kouki/mysearch/filelog/*

検索

検索窓

  • ここ のHTMLを参照。
  • 検索窓に入力したクエリは mysearch.cgi が受け取り、プログラムからmysearch.sh を呼び出します。
    • プログラムの格納場所は、shower の public_html/cgi-bin/ とします。
    • パーミッションの設定に注意してください。
    • perl から シェルスクリプトを呼び出す危険性
      • 検索窓の入力内容を、そのままシェルに引数で渡すのは危険です。ここではperlプログラムがクエリファイルを書き出し、Javaプログラムが同名ファイルを読み込むようにしています(大規模な検索システムでは使えない方法です)。
  • CGIではなく、Java サーブレットで実装する方法もあります(tomcat導入メモ)。試してみてください。

キーワードマッチング

  • ここまでの実行が終わったら、処理は再び mysearch.cgi に戻り、SearchResult.html を読み込んで、ブラウザに表示します。

課題

  • スペースで区切った複数のクエリに対して、AND検索ができるようにしましょう。
  • テキスト解析技術を使って、独自のサービスを提供してみましょう。

HTMLパース

  • HTMP Parser を参考に、パーサをインストールします。
    • ここ の Downloads -> Older の htmlparser1_6_20060610.zip をダウンロードしました。解凍するときに avast! が警告するファイルは、全てその場で削除しました。
    • lib フォルダ内の htmlparser.jar のみ使用します(クラスパスを通しておきます)。
      CLASSPATH=$CLASSPATH:/home/m-kouki/mysearch/htmlparser.jar
      export CLASSPATH
  • SimpleParser3.java (東京電機大 山田先生)を試してみます。
    • タイトルを取得するには
      java SimpleParser3 http://shower.human.waseda.ac.jp/~m-kouki/ TITLE
    • 本文を取得するには
      java SimpleParser3 http://shower.human.waseda.ac.jp/~m-kouki/
      • 76行目 System.out.println("text: \"" + text.getText() + "\""); だけを出力するようにすればOK。

URL追跡

  • lynx を使って、トップページから順番に、URLを辿って全てのコンテンツを取得してみます。
    • RSS のない、トップページ 以下のページや 各資料 のアドレスを取得することが目的です。
    • 「m-kouki」が含まれているアドレスのみを取得対象とします。

lynx

  • lynx でウェブページにアクセスするには、
    lynx -dump http://shower.human.waseda.ac.jp/~m-kouki/
      .
      .
      k-lab_wiki [23] 兇wiki
        _________________________________________________________________
      Copyright(C) [24]MIYAZAWA Kouki All Rights Reserved.
    
    繚
      1. http://shower.human.waseda.ac.jp/~m-kouki/blog/
      2. http://shower.human.waseda.ac.jp/~m-kouki/pukiwiki/index.php?FrontPage
      3. http://shower.human.waseda.ac.jp/~m-kouki/reference/index.html
      4. http://shower.human.waseda.ac.jp/~m-kouki/kensyu/index.html
      5. http://shower.human.waseda.ac.jp/~m-kouki/collaboration/index.html
      .
      .
  • 指定したウェブサイトの文字コードが、lynx の設定ファイルの文字コード と異なる場合、本文が文字化けします。
    • とりあえず今回は、最後のリンク情報が取得できればいいので、lynx の設定ファイルは変更しません。
  • Basic認証付きのページにアクセスするには、
    lynx -dump -auth=(ID):(パスワード) (URL)
  • lynx に xml ファイルのアドレス(RSSなど)を指定すると、正しくURLを取得することができません。以下では、取得した URL を再度 lynx にかけ、出力が得られるかどうかで、URL が正しいかどうかを判定しています。

java から呼び出す

  • javafaq 外部コマンド呼出し を参考にして、
    • CrawlLynxTest1.java
      import java.io.*;
      
      public class CrawlLynxTest1 {
          public static void main(String[] args) {
              try {
                  Process process = Runtime.getRuntime().exec
                   ("lynx -dump http://shower.human.waseda.ac.jp/~m-kouki/");
                  InputStream is = process.getInputStream();
                  BufferedReader br = new BufferedReader(new InputStreamReader(is));
                  String line;
                  while ((line = br.readLine()) != null) {
                      System.out.println(line);
                  }
                  is.close();
                  br.close();
              } catch (Exception err) {
                  System.out.println(err);
              }
          }
      }

実装

  • lynx で指定したページのリンクを取得 → 取得したURLが存在するかどうかを確認 → HTML パーサでリンク先のタイトルを取得 → リンク先のファイルの拡張子から属性を判定 → データベースに格納 の流れを再帰的に繰り返します。
  • トップページのURLを引数として、各エントリーのタイトル(ファイル名)とURLを取得して、テーブル mysearch_entry に格納します。
    • クラスパスを通して、CrawlLynx.java を実行
      CLASSPATH=$CLASSPATH:/home/m-kouki/mysearch/
             mysql-connector-java-5.1.6/mysql-connector-java-5.1.6-bin.jar
      export CLASSPATH
      java CrawlLynx m-kouki http://shower.human.waseda.ac.jp/~m-kouki/ 10
      • 引数の意味 : http://shower.human.waseda.ac.jp/~m-kouki/ から検索開始、m-kouki の含まれるアドレスのみ、第10階層までクロール
      • CrawlRSS.java の実行後に行ってください。CrawlRSS.java ですでに取得済みの、ブログとwikiの記事は、重複URLとなり格納されません。
      • タイトルの取得には、SimpleParser3.java を外部クラスから実行できるようにした、SimpleParser3_2.java を使用しています。
      • エントリーの属性は、「書類(txt)1、プログラム(java, m, perl)2、PDF 3、 WORD文書 4、動画(wmv) 5、パワーポイント 6、圧縮ファイル(zip, lzh) 7、その他 0」と決めます。
    • プログラムの格納場所は、shower の mysearch/ とします。

改良すべき点

  • lynx の代わりに HTML Parser で A タグのテキストと URL を解析すれば、リンク先のファイルが HTML でなくても正確なタイトルを取得できそうです。
  • 時間がかかりすぎる。一度検索したリンクは検索しないなど、ループを防ぐ工夫が要るかも。

リンク切れを削除

  • mysearch_entry テーブルの entry_url カラムを順番に取得して、リンク先が生きているかを確認(lynx が null もしくは Not Found を返さないことを確認) します。
  • ついでに、上の追跡検索でヒットしてしまう、検索対象にしたくないページ(wikiのバックアップやBlogのインデックス等)を削除します。
  • DeleteLinks.java を実行
    • 上のプログラム中で読み込む deletelinks_url.txt と deletelinks_title.txt は、削除したい URL や タイトルの一部を列挙したファイルです。

インデックスをつける

HTML以外のファイルを取得する

  • CrawlEntry.java の改良案です(CrawlEntry2.java)。
  • 以下は HTMLパーサでは「WARNING: URL ~~ does not contain text」エラーが出ます。そのため、これまでの手法では内容をログファイルにできないため、検索することができません。

PDFファイルを取得

  • PDFビューア
    • エントリーの属性が「3」だったときは、wget でダウンロード → Xpdf でPDFファイルをテキストファイルに変換

PPTとWORDファイルを取得

ZIPファイルを取得

検索

検索窓でファイルの属性を指定する

表記ゆれ対処

  • 大文字・小文字など。

定期クロール

  • RSS検索
    cd /home/m-kouki/mysearch/
    CLASSPATH=$CLASSPATH:informa.jar
    CLASSPATH=$CLASSPATH:lib/commons-logging.jar
    CLASSPATH=$CLASSPATH:lib/jdom.jar
    CLASSPATH=$CLASSPATH:htmlparser.jar
    CLASSPATH=$CLASSPATH:mysql-connector-java-5.1.6/mysql-connector-java-5.1.6-bin.jar
    export CLASSPATH
    java CrawlRSS
  • 追跡検索
    java CrawlLynx m-kouki http://shower.human.waseda.ac.jp/~m-kouki/ 3
    java CrawlLynx m-kouki http://shower.human.waseda.ac.jp/~m-kouki/blog/archives.html 2
  • 削除とファイルログ保存
    java DeleteLinks
    rm /home/m-kouki/mysearch/filelog/*
    java CrawlEntry2
    rm *.pdf*
    chmod 755 /home/m-kouki/mysearch/filelog/*

cronで自動化

  • 参考
  • cron コマンドに関して [#c2aab7e5]
  • ユーザ m-kouki のスケジュールを変更するには
    $ crontab -u m-kouki -e
    • エディタで、
      # m h  dom mon dow   command
      * * 14 6 6 date > date.txt
      などとして、Ctrl+O → 「File Name to Write: 」はそのままで、Enter → Ctrl+X で終了する。