サイトマップの作成からサイトマップの送信を自動化する方法

2014年06月14日 20時58分

201406142058HPEW00.png

はじめに

sitecopyを使ってコンテンツをミラーリングする方法では、コンテンツをリモートサイトにミラーリングする方法を解説しました。 今回は、ミラーリングしたコンテンツのサイトマップの作成と作成したサイトマップをGooleのウエブマスターツールに送信するまでの作業を自動化する方法を解説します。

前提条件

作業の前提条件は、下記のとおりです。

ソフトウエアバージョン
OSWindows 7 Ultimate 32bit
CygwinSetup Version 2.831

なお、自動化にはcurlコマンドが必要です。また、ウエブマスターツールのアカウントおよび、robots.txtは事前に設定しておいて下さい。

サイトマップの作成自動化

自動化では、下記の処理を行います。

#処理処理内容
1サイトマップ作成sitecopyでコンテンツをミラーリングした後、ミラーリングしたデータを記録したXMLファイルをパースして、サイトマップをローカルに作成します。
2サイトマップ送信ローカルに作成したサイトマップを、LFTPコマンドを使って、リモート側にアップロードします。
3サイトマップの再送信アップロードしたサイトマップをウエブマスターツールに再送信します。
  1. CPANパッケージのインストール

    HTMLファイルのパーサーとして、TagParserを使用するため、cpanm(Perl Module Manager)をインストールします。

    $ cpan
    $ cpan App::cpanminus
    
    201406142058HPEW01.png
    201406142058HPEW02.png
    インストールログ(cpan)
    Sorry, we have to rerun the configuration dialog for CPAN.pm due to
    some missing parameters. Configuration will be written to
     <</home/punio/.cpan/CPAN/MyConfig.pm>>
    
    
    CPAN.pm requires configuration, but most of it can be done automatically.
    If you answer 'no' below, you will enter an interactive dialog for each
    configuration option instead.
    
    Would you like to configure as much as possible automatically? [yes]
    
    Autoconfigured everything but 'urllist'.
    
    Now you need to choose your CPAN mirror sites.  You can let me
    pick mirrors for you, you can select them from a list or you
    can enter them by hand.
    
    Would you like me to automatically choose some CPAN mirror
    sites for you? (This means connecting to the Internet) [yes]
    Trying to fetch a mirror list from the Internet
    Fetching with LWP:
    http://www.perl.org/CPAN/MIRRORED.BY
    
    Looking for CPAN mirrors near you (please be patient)
    .............................. done!
    
    New urllist
      http://ftp.kaist.ac.kr/pub/CPAN/
      http://cpan.pesat.net.id/
      http://ftp.neowiz.com/CPAN/
    
    Autoconfiguration complete.
    
    commit: wrote '/home/punio/.cpan/CPAN/MyConfig.pm'
    
    You can re-run configuration any time with 'o conf init' in the CPAN shell
    
    cpan shell -- CPAN exploration and modules installation (v1.960001)
    Enter 'h' for help.
    
    201406142058HPEW03.png
    201406142058HPEW05.png
    201406142058HPEW05.png

    インストールログ(cpanminus)
    CPAN: Storable loaded ok (v2.27)
    CPAN: LWP::UserAgent loaded ok (v6.04)
    CPAN: Time::HiRes loaded ok (v1.972101)
    Fetching with LWP:
    http://ftp.kaist.ac.kr/pub/CPAN/authors/01mailrc.txt.gz
    CPAN: YAML loaded ok (v0.80)
    Going to read '/home/punio/.cpan/sources/authors/01mailrc.txt.gz'
    CPAN: Compress::Zlib loaded ok (v2.033)
    ............................................................................DONE
    Fetching with LWP:
    http://ftp.kaist.ac.kr/pub/CPAN/modules/02packages.details.txt.gz
    Going to read '/home/punio/.cpan/sources/modules/02packages.details.txt.gz'
      Database was generated on Thu, 12 Jun 2014 16:29:02 GMT
    ..............
      New CPAN.pm version (v2.05) available.
      [Currently running version is v1.960001]
      You might want to try
        install CPAN
        reload cpan
      to both upgrade CPAN.pm and run the new version without leaving
      the current session.
    
    
    ..............................................................DONE
    Fetching with LWP:
    http://ftp.kaist.ac.kr/pub/CPAN/modules/03modlist.data.gz
    Going to read '/home/punio/.cpan/sources/modules/03modlist.data.gz'
    DONE
    Going to write /home/punio/.cpan/Metadata
    Running install for module 'App::cpanminus'
    Running make for M/MI/MIYAGAWA/App-cpanminus-1.7004.tar.gz
    Fetching with LWP:
    http://ftp.kaist.ac.kr/pub/CPAN/authors/id/M/MI/MIYAGAWA/App-cpanminus-1.7004.tar.gz
    CPAN: Digest::SHA loaded ok (v5.71)
    Fetching with LWP:
    http://ftp.kaist.ac.kr/pub/CPAN/authors/id/M/MI/MIYAGAWA/CHECKSUMS
    Checksum for /home/punio/.cpan/sources/authors/id/M/MI/MIYAGAWA/App-cpanminus-1.7004.tar.gz ok
    CPAN: File::Temp loaded ok (v0.22)
    CPAN: Parse::CPAN::Meta loaded ok (v1.4401)
    CPAN: CPAN::Meta loaded ok (v2.110440)
    CPAN: Module::CoreList loaded ok (v2.49_02)
    
      CPAN.pm: Going to build M/MI/MIYAGAWA/App-cpanminus-1.7004.tar.gz
    
    Checking if your kit is complete...
    Looks good
    Writing Makefile for App::cpanminus
    Writing MYMETA.yml
    cp lib/App/cpanminus/fatscript.pm blib/lib/App/cpanminus/fatscript.pm
    cp lib/App/cpanminus.pm blib/lib/App/cpanminus.pm
    cp bin/cpanm blib/script/cpanm
    /usr/bin/perl.exe -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/cpanm
    Manifying blib/man1/cpanm.1
    Manifying blib/man3/App.cpanminus.fatscript.3pm
    Manifying blib/man3/App.cpanminus.3pm
      MIYAGAWA/App-cpanminus-1.7004.tar.gz
      /bin/make -- OK
    Running make test
    PERL_DL_NONLAZY=1 /usr/bin/perl.exe "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
    t/happy_cpantesters.t .. 1/1 # App::cpanminus/1.7004
    t/happy_cpantesters.t .. ok
    All tests successful.
    Files=1, Tests=1,  1 wallclock secs ( 0.30 usr  0.89 sys +  0.00 cusr  0.15 csys =  1.34 CPU)
    Result: PASS
      MIYAGAWA/App-cpanminus-1.7004.tar.gz
      /bin/make test -- OK
    Running make install
    Installing /usr/lib/perl5/site_perl/5.14/App/cpanminus.pm
    Installing /usr/lib/perl5/site_perl/5.14/App/cpanminus/fatscript.pm
    Installing /usr/share/man/man1/cpanm.1
    Installing /usr/share/man/man3/App.cpanminus.3pm
    Installing /usr/share/man/man3/App.cpanminus.fatscript.3pm
    Installing /usr/local/bin/cpanm
    Appending installation info to /usr/lib/perl5/5.14/i686-cygwin-threads-64int/perllocal.pod
      MIYAGAWA/App-cpanminus-1.7004.tar.gz
      /bin/make install  -- OK
    
  2. TagParserのインストール
    $ cpanm HTML::TagParser
    
    201406142058HPEW06.png
    インストールログ(TagParser)
    --> Working on HTML::TagParser
    Fetching http://www.cpan.org/authors/id/K/KA/KAWASAKI/HTML-TagParser-0.20.tar.gz ... OK
    Configuring HTML-TagParser-0.20 ... OK
    Building and testing HTML-TagParser-0.20 ... OK
    Successfully installed HTML-TagParser-0.20
    1 distribution installed
    
  3. LFTPのインストール

    apt-cygコマンドを使用して、LFTPコマンドをインストールします。

    $ apt-cyg install lftp
    
    インストールログ(TagParser)
    Working directory is /cache
    Mirror is http://ftp.iij.ad.jp/pub/cygwin/, Architecture is x86
    --2014-06-13 19:46:02--  http://ftp.iij.ad.jp/pub/cygwin//x86/setup.bz2
    Resolving ftp.iij.ad.jp (ftp.iij.ad.jp)... 202.232.140.170
    Connecting to ftp.iij.ad.jp (ftp.iij.ad.jp)|202.232.140.170|:80... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 435859 (426K) [application/x-bzip2]
    Saving to: `setup.bz2'
    
    100%[======================================>] 435,859     1.67M/s   in 0.2s
    
    2014-06-13 19:46:03 (1.67 MB/s) - `setup.bz2' saved [435859/435859]
    
    Updated setup.ini
    
    Installing lftp
    Found package lftp
    --2014-06-13 19:46:03--  http://ftp.iij.ad.jp/pub/cygwin//x86/release/lftp/lftp-4.4.16-1.tar.xz
    Resolving ftp.iij.ad.jp (ftp.iij.ad.jp)... 202.232.140.170
    Connecting to ftp.iij.ad.jp (ftp.iij.ad.jp)|202.232.140.170|:80... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 555404 (542K) [application/x-xz]
    Saving to: `lftp-4.4.16-1.tar.xz'
    
    100%[======================================>] 555,404     2.67M/s   in 0.2s
    
    2014-06-13 19:46:03 (2.67 MB/s) - `lftp-4.4.16-1.tar.xz' saved [555404/555404]
    
    Unpacking...
    Package lftp requires the following packages, installing:
    bash libgcc1 libiconv2 libintl8 libncursesw10 libopenssl100 libreadline7 libstdc++6 perl zlib0 cygwin
    Package bash is already installed, skipping
    Package libgcc1 is already installed, skipping
    Package libiconv2 is already installed, skipping
    Package libintl8 is already installed, skipping
    Package libncursesw10 is already installed, skipping
    Package libopenssl100 is already installed, skipping
    Package libreadline7 is already installed, skipping
    Package libstdc++6 is already installed, skipping
    Package perl is already installed, skipping
    Package zlib0 is already installed, skipping
    Package cygwin is already installed, skipping
    Running postinstall scripts
    Package lftp installed
    
    201406142058HPEW07.png
    201406142058HPEW08.png
  4. 自動化コマンドの作成

    sitecopyを実行すると、ミラーリングしたデータが~/.sitecopyフォルダ下にXMLファイルで保存されますので、このXMLファイルをXMLParserで解析し、HTMLファイルの一覧を取得した後、HTMLファイル中に含まれるIMGタグをTagParserで解析してサイトマップ(XMLファイル)を作成します。

    サイトマップを作成した後、リモートサイトのアップロードし、ウエブマスターツールに再送信しています。

    #!/usr/bin/perl
    use feature ':5.10';
    use encoding "utf8";
    
    use XML::Simple;
    use HTML::TagParser;
    use Data::Dumper;
    use URI::Escape;
    use File::Basename;
    use URI;
    
    local $FREQ_DEF = "daily";
    local $FREQ_IMG = "monthly";
    
    my $HOME = $ENV{'HOME'};
    my $COPY = "$HOME/.sitecopy";
    my $CONF = "$HOME/config.xml";
    my $argv, $c = 0;
    
    foreach $argv (@ARGV) {
      if ($argv =~ /^-./) {
        given($argv) {
          when('-c') { $c = 1; next; }
          default    { print "$argv: パラメタエラー\n"; exit; }
        }
      } else {
        if ($c == 1) { $CONF = $argv; $c = 0; last; }
      }
    }
    if (! -f $CONF) { print $CONF . "が見つかりません\n"; exit; }
    
    my $xml = new XML::Simple();
    my $ref = $xml->XMLin($CONF);
    my @def = @{$ref->{site}};
    my $obj;
    
    local $PUT_IMAGE = $ref->{image};
    local $USE_GZIP  = $ref->{gzip};
    local $MAP_NAME  = $ref->{mapname};
    local $MAP_UPLOAD= $ref->{upload};
    local $MAP_SEND  = $ref->{send};
    
    foreach $obj (@def) {
      local $XML    = $COPY . "/" . $obj->{xml};
      local $URL    = $obj->{url};
      local $HOST   = $obj->{host};
      local $USER   = $obj->{user};
      local $PASS   = $obj->{passwd};
      local $LOCAL  = $obj->{local};
      local $REMOTE = $obj->{remote};
      local $DEST   = $obj->{dest};
    
      $LOCAL =~ s/~/$HOME/;
      $DEST  =~ s/~/$HOME/;
      if (! -f $XML)   { print "ERROR: " . $XML   . "が見つかりません\n"; exit; }
      if (! -d $LOCAL) { print "ERROR: " . $LOCAL . "が見つかりません\n"; exit; }
      if (! -d $DEST)  { print "ERROR: " . $DEST  . "が見つかりません\n"; exit; }
    
      # XMLファイルからHTMLファイルのリストを取得する
      local @HTML = &get_html($XML);
     
      # サイトマップを作成する
      local $map = &mak_sitemap(*HTML); print "$map\n";
      local $name = basename($map);
    
      my $LINE;
      # lftpを使用してサイトマップをアップロード
      if ($MAP_UPLOAD == 1) {
        open(IN, "lftp -u $USER,$PASS $HOST -e \"put $map -o $REMOTE/$name;exit\" | ");
        while($LINE = <IN>) { print $LINE; } close(IN);
      }
      # Googleにサイトマップを送信する
      if ($MAP_SEND == 1) {
        my $url = uri_escape("$URL/$name");
        open(IN, "curl -X GET http://www.google.com/webmasters/tools/ping?sitemap=$url |");
        while($LINE = <IN>) { print $LINE; } close(IN);
      }
    }
    #
    # XMLファイルからHTMLファイルのリストを取得する
    #
    sub get_html
    {
      my $xml = new XML::Simple();
      my $ref = $xml->XMLin($_[0]);
      my @obj = @{$ref->{"items"}->{"item"}};
      my @tmp;
      my $f;
      my $i = 0;
      foreach $f (@obj) {
        my $name = $f->{filename};
        my @type = ("html","htm");
        my $find;
        foreach $find (@type) {
          if ($name =~ /\.$find$/) {
            $tmp[$i++] = uri_unescape($name);
          }
        }
      }
      return( reverse(@tmp) );
    }
    #
    # サイトマップを作成する
    #
    sub mak_sitemap
    {
    local *HTML = $_[0];
      my  $file = $DEST . "/$MAP_NAME";
      my  $gzip = "$file.gz";
      my  $html;
    
      open(OUT, "> $file"); binmode(OUT, ":utf8");
    
    print OUT <<EOF;
    <?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
            xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
    <url>
      <loc>$URL/</loc>
      <priority>1.0</priority>
      <changefreq>$FREQ_DEF</changefreq>
    </url>
    EOF
    
      # XMLファイルの定義
      foreach $html (@HTML) {
    
        # HTMLファイルのプライオリティを取得
        my $pri = &get_priority($html);
    
        # HTMLファイル中の画像ファイルの取得
        my @img = ();
        if ($PUT_IMAGE == 1) {
          @img = &get_imglist($html);
        }
    print OUT <<EOF;
    <url>
      <loc>$URL/$html</loc>
      <priority>$pri</priority>
      <changefreq>$FREQ_DEF</changefreq>
    EOF
        if ($#img >= 0) { # 1個以上の画像がある場合
          my $i;
          foreach $i (@img) {
    print OUT <<EOF;
      <image:image>
        <image:loc>$URL$i</image:loc>
      </image:image>
    EOF
          }
        }
    print OUT <<EOF;
    </url>
    EOF
      }
    print OUT "</urlset>\n";
    close(OUT);
    
      if ($USE_GZIP == 1) {
        system("gzip -c $file > $gzip");
        $file = $gzip;
      }
      return( $file );
    }
    sub get_priority
    {
      my $prio = 1.0;
      my $step = 0.1;
    
      my $file = $_[0];
      my $dir  = dirname($file);
      my $pri  = 1;
    
      if ($dir ne ".") {
        my @d = split(/\//,$dir);
        $pri = $#d + 2;
      }
      $prio -= $step * $pri;
      return( $prio );
    }
    sub get_imglist
    {
      my @list = ();
      my $file = $_[0];
      my $base = dirname($file);
      my $html = HTML::TagParser->new( "$LOCAL/$file" );
      my @elem = $html->getElementsByTagName("img");
      my $tmp;
      my $i = 0;
      foreach $tmp (@elem) {
        my $img = $tmp->attributes->{src};
        if ($img !~ /^http/) { # httpから始まる外部の画像リンクは除外する
          my $href = dirname($img);
          my $name = basename($img);
          my $hoge = URI->new_abs(".", "$base/$href/");
          $list[$i++] = "$hoge$name";
        }
      }
      return( @list );
    }
    

mksitemapの使用方法

  1. 起動オプション
    オプション概要
    -c設定ファイルをしています。デフォルトは、~/config.xmlです。
  2. 設定ファイル

    下記のタグを使用して、設定ファイルを作成します。

    タグ概要
    sitemap設定情報の開始タグです。
    mapname出力するサイトマップファイル名を指定します。
    gzip出力したサイトマップファイルをGZIPで圧縮するがを0または、1で指定します。
    imageHTMLファイル中に含まれるイメージファイルをサイトマップ中に含めるか否かを0または、1で指定します。
    upload作成したサイトマップをリモートサーバにアップロードするか否かを0または、1で指定します。
    sendリモートサーバにアップロードされたサイトマップを、ウエブマスターツールに送信するか否かを0または、1で指定します。
    siteサイトことの設定情報の開始タグです。
    xmlsitecopyが出力したXMLファイル名を指定します。
    hostサイトマップをアップロードするリモートサーバ名を指定します。
    userリモートサーバのログインユーザ名を指定します。
    passwdリモートサーバのログインパスワードを指定します。
    localsitecopyでミラーリングしたルートフォルダを指定します。
    remoteサイトマップをアップロードするリモートサーバのフォルダを指定します。
    dest作成したサイトマップの保存フォルダを指定します。
    urlホームページのURLを指定します。
    <sitemap>
      <mapname>sitemap.xml</mapname>
      <gzip>0</gzip>
      <image>1</image>
      <upload>1</upload>
      <send>1</send>
      <site>
        <xml>example</xml>
        <host>example.org</host>
        <user>username</user>
        <passwd>passwd</passwd>
        <local>~/doc/html</local>
        <remote>/</remote>
        <dest>/tmp</dest>
        <url>http://examle.org</url>
      </site>
    </sitemap>
    
  3. 使用例

    デフォルトの設定ファイル(~/config.xml)の場合、引数無しで起動します。

    $ mksitemap
    

    設定ファイルを指定する場合、-cオプションで設定ファイルを指定します。

    $ mksitemap -c /tmp/config.xml
    

    sitecopyでミラーリングした後、本コマンドを実行するとサイトマップを作成し、ウエブマスターツールにサイトマップが送信されます。

    201406142058HPEW09.png
  4. ミラーリングとサイトマップの自動化

    sitecopyを実行した後、mksitemapを実行するとコンテンツの更新とサイトマップを自動で更新できるようになります。

    $ sitecopy -au
    $ mksitemap