クックパッドの話題のレシピをtwitterにPOSTするBOTを作った

うちの家庭でなくてはならないクックパッドのレシピですが、ふと思い立ってクックパッドの話題のレシピをtwitterにPOSTするcookpad_recipeというBOTを作りました。よければfollowしてやって下さい。本家からクレーム入ったり、小遣いを減らされてサーバ代が払えなくならない限り続けます。
作成の経緯は、pythonの勉強をしている際にどんぴしゃな情報があったので発作的に作って、レンタルサーバにアップしちゃったというのが本当のところです。

BOTの説明

  • クックパッドのメインページにある”話題のレシピ”からレシピタイトルとURLを取得します。
  • レシピごとにtwitterにPOSTします。
  • POSTは一日一回で、今のところ17時に実施します(夕飯の献立を考える頃合いを狙ってます?)

pythonの環境

  • レンタルサーバのユーザ領域にvirtual-pythonをインストール
  • python-twitterが必要(依存関係でsimplejsonも)
  • HTML解析にBeautifulSoupが必要

モジュールはeasy_installがあればすんなり入ります。で、作ったBOTのコードがこちら

import urllib2

from twitter import Api as TwitterApi
from BeautifulSoup import BeautifulSoup

TWITTER_USERNAME = 'twitterのscreen_name'
TWITTER_PASSWORD = 'password'

COOKPAD_URL = 'http://cookpad.com/'
soup = BeautifulSoup(urllib2.urlopen(COOKPAD_URL))

def fetch_data():
        for node in soup.findAll('div', {'id': 'wadai-recipe-inner'}):
                for tag in node('a', {'class': 'recipe-title'}):
                        yield tag['title'], tag['href']

def main():
        api = TwitterApi(TWITTER_USERNAME, TWITTER_PASSWORD)
        for recipe_title, recipe_url in fetch_data():
                post = u"%s %s" % (recipe_title, recipe_url)
                api.PostUpdate(post)

if __name__ == '__main__':
        main()

コードはこちらの方とそっくりになってしまいましたが、オリジナルコードがすばらしいということで(汗。
それにしてもBeautifulSoupはとっても面白くて、適当なサイトを見つけてはスクレイピングの練習をしています。インタラクティブシェルで結果が即反映するので楽しいですよ。

尚、virtual-pythonなどpython環境については後日もう少し書きたいと思います。

[2008年12月23日追記]
クックパッドのトップページに若干の修正あったようで、それに合うようにコードを若干修正しました。

import urllib2

from twitter import Api as TwitterApi
from BeautifulSoup import BeautifulSoup

TWITTER_USERNAME = 'twitterのscreen_name'
TWITTER_PASSWORD = 'password'

COOKPAD_URL = 'http://cookpad.com'
soup = BeautifulSoup(urllib2.urlopen(COOKPAD_URL))

def fetch_data():
        for node in soup.findAll('div', {'id': 'wadai-recipe-inner'}):
                for tag in node('a', {'class': 'recipe-title'}):
                        yield tag['title'], tag['href']

def main():
        api = TwitterApi(TWITTER_USERNAME, TWITTER_PASSWORD)
        for recipe_title, recipe_url in fetch_data():
                post = u"%s %s%s" % (recipe_title, COOKPAD_URL, recipe_url)
                api.PostUpdate(post)

if __name__ == '__main__':
        main()

[追記ここまで]
[2009年3月22日追記]
レシピの配信方法を、17時に一括から都度配信にしました。そこらへんについては後述します(つもり)
[追記ここまで]


CORESERVERのShell

このblogはCORESERVERで動かしているのですが、一番最初にsshログインして操作しようとした時、

~> ls
-rbash: /bin/ls: restricted: cannot specify `/' in command names

というメッセージが出て訳がわからず焦りました。とりあえずメッセージ内容をgoogle先生に聞いたところ、CORESERVERのShellはデフォルトでrbashという制限付きbashとなっているとのこと。従ってchshコマンドを使用し、デフォルトShellをbashに変更しました。

~> chsh
Changing login shell for hogehoge.
Password: 
Enter the new value, or press return for the default.
        Login Shell [/bin/rbash]: /bin/bash
Shell changed.

これで普通に ls とか cd コマンドが使用出来るようになりました。ふう〜。


kickstartを使ったインストールの自動化

さて、前回の続きですが、RedHat系Linuxではkickstartという仕組みを利用してOSインストールの自動化を行うことが出来ます。kickstartの詳しい内容につきましてはこちらにある公式ドキュメントをご参照願います。下記参考サイトにも挙げてあります。

参考にしたサイト

前回同様大変参考になりました。

kickstartファイルの作り方

kickstartファイルは公式マニュアルを参照して作成したり、Web上にあるなんらかのサンプルを利用することも出来ますが、今回はPXEサーバにあるanaconda-ks.cfgを流用します。
RedHat系Linuxをインストールすると /root にanaconda-ks.cfg というファイルが作成されます。前回使用したPXEサーバのanaconda-ks.cfgは次のようになっています。

# Kickstart file automatically generated by anaconda.

install
cdrom
lang ja_JP.UTF-8
keyboard jp106
network --device eth0 --bootproto static --ip 192.168.11.5 --netmask 255.255.255.0 --gateway 192.168.11.1 --nameserver 192.168.11.1 --hostname hoge.centos.com
rootpw --iscrypted *****************************
firewall --enabled --port=22:tcp
authconfig --enableshadow --enablemd5
selinux --enforcing
timezone Asia/Tokyo
bootloader --location=mbr --driveorder=sda
# The following is the partition information you requested
# Note that any partitions you deleted are not expressed
# here so unless you clear all partitions first, this is
# not guaranteed to work
#clearpart --all --drives=sda
#part /boot --fstype ext3 --size=100 --ondisk=sda
#part pv.2 --size=0 --grow --ondisk=sda
#volgroup VolGroup00 --pesize=32768 pv.2
#logvol / --fstype ext3 --name=LogVol00 --vgname=VolGroup00 --size=1024 --grow
#logvol swap --fstype swap --name=LogVol01 --vgname=VolGroup00 --size=512 --grow --maxsize=1024

%packages
@japanese-support
@core
@base
@printing
@development-tools
device-mapper-multipath
imake
-sysreport

anaconda-ks.cfgの修正

まず、anaconda-ks.cfgを /var/ftp にコピーし、kickstart-centos.cfgという名前に変更します。所有者、パーミッションは環境に合わせ変更して下さい。

# cp /root/anaconda-ks.cfg /var/ftp/kickstart-centos.cfg

次にkickstart-centos.cfgを今回セッティングするサーバ用に数ヶ所修正します。私は主に次の3箇所を修正します。
まずインストールメディアの指定を変更します。2行目の「cdrom」を下記のように変更します。

url --url ftp://192.168.11.5//centos

今回は前回のPXEサーバのネットワーク環境をそのまま流用しますので、FTPでインストールメディアを提供します。

次に5行目のネットワークの設定を行います。これはセッティングするサーバに与えるIPアドレス等、各々の環境に合わせて設定します。
次に6行目のrootパスワード(rootpw)を設定します。rootpwで設定するパスワードは平文でも記述出来ますが、暗号化したパスワードを記述することも可能です。暗号化したパスワードはiscryptedオプションを付与することによって有効になります。
パスワードの暗号化ですが、anaconda-ks.cfgを参照しているサーバと同じパスワードを使用するならば、同じもので構いませんが、違うパスワードを使用したい場合はパスワードを暗号化する必要があります。パスワードの作成はこちらのサイトを参考にさせて頂きました。

# openssl passwd -1
Password:
Verifying - Password:
$1$V.6Zs850$zNvg6orrkhnJ00Nmt5xQd0

“$1$”で始まる文字列が暗号化されたパスワードになります。作成されたパスワードをコピー・ペーストして下さい。

kickstartファイルの設置

このようにして作成したkickstartファイルは、前回使用した /tftpboot/pxelinux.cfg/defaultファイルに指定します。前回作成したdefaultファイルを下記の様に修正します。


default centos

label centos
kernel vmlinuz
append load initrd=initrd.img ksdevice=eth0 ks=ftp://192.168.11.5/kickstart-centos.cfg devfs=nomount

ここまで出来れば、あとは前回同様にPXEサーバの必要なサービスの起動、DVDイメージのマウントを行い、クライアントPCを起動させて下さい。うまくいけばインストールがスタートし、RESTARTのメッセージが表示されるところまで自動的に進むと思います。
また、kickstartでは、%postという指定でインストール後にユーザー追加などのコマンドを記述することが出来ます。今回は取り急ぎセットアップしただけですが、時間があればもう少し調べてみたいと思います。


CentOSをネットワークインストールする

ある事情により、自宅のiTunesサーバ(兼ファイルサーバ)として使用していたノートPCを人に譲ることになり、他のノートPCを代替サーバに仕立てようとCentOSのインストールを試みたのですが、DVD-ROMドライブが壊れているようでインストールが出来ない〜><。
そこで以前より気になっていたPXEを利用したネットワークインストールに挑戦してみました。

参考にしたサイト

上記サイトを主に参考にさせて頂きました。大変助かりました。この場を借りてお礼申し上げます。

PXEサーバの構築

ノートPCにネットワーク経由でCentOSをインストールする為には、ノートPCをPXEBOOTさせ、且つ取得させるOSイメージをセットするサーバが必要になります。既存サーバに後述する必要な環境をセッティングすることもアリなのですが、自宅にサーバが無いので、今回はMacBookのVMwareFusion上にあるCentOS5.1をサーバとして使用します。

イメージファイルのダウンロード

まず、CentOSのDVDイメージファイルをサイトからダウンロードします。今回はバージョン5.1を使います。
イメージファイルは今回構築するPXEサーバ上でダウンロードしてもかまいませんが、私はMacBookにBitTorrent
クライアントがあったので、BitTorrent経由でダウンロード、その後samba経由でPXEサーバに移動させました。 
DVDイメージは /home/hoge/images に移動します。このファイルは後で使用します。

vsftpdのインストールと設定

PXEブートしたクライアントが取得するイメージファイルの提供方法は、VFS、HTTP、FTP等があるようです。
今回参考にさせていただいたサイトでも、HTTP、FTPのいづれかを使用していました。今回はvsftpd(FTP)を使用してイメージファイルを配布しようと思います。vsftpdはyumでインストールします。

# yum -y install vsftpd

vsftpdを起動します。vsftpdはデフォルトでanonymousログインが許可されています。

# /etc/rc.d/init.d/vsftpd start

tftp-serverのインストールと設定

tftpと後述するdhcpはクライントPCをPXEBOOTさせる為に必要。tftpがインストールされていない場合はyumでインストールします。

# yum -y install tftp-server

インストール後にconfigファイルを設定します。disableのyesをnoに変更します。

# vi /etc/xinetd.d/tftp

service tftp
{

中略

        disable                 = no  #yesをnoに変更

中略

}

次に、tftp-serverのインストール時に作成された /tftpboot にcentosというフォルダを作成し、PXE用ブートローダをコピーします。このフォルダにはあと2つのファイルをコピーします(後述)。

# mkdir /tftpboot/centos
# cp /usr/lib/syslinux/pxelinux.0 /tftpboot/centos/

次に、/tftpboot/centos/にpxelinux.cfgという名前でフォルダを作成し、defaultというファイル名で起動用設定ファイルを記述します。

# mkdir /tftpboot/centos/pxelinux.cfg

# vi /tftpboot/centos/pxelinux.cfg/default

default centos

label centos
kernel vmlinuz
append load initrd=initrd.img devfs=nomount

DVDイメージのマウント

予めダウンロードしたDVDイメージファイルを、クライアントがFTP接続した際のディレクトリ(/var/ftp)内にフォルダを作成し、マウントさせます。マウントポイントは /var/ftp/centos になります。

# mkdir /var/ftp/centos
# mount -t iso9660 -o loop /home/hoge/images/CentOS-5.1-i386-bin-DVD.iso /var/ftp/centos

イメージファイルをマウントさせた後、その中にある起動イメージファイルを /tftpboot/centos にコピーします。

# cp /var/ftp/centos/images/pxeboot/initrd.img /tftpboot/centos/
# cp /var/ftp/centos/images/pxeboot/vmlinuz /tftpboot/centos/

ここで先程のtftpを起動させます。

# /etc/rc.d/init.d/xinetd start

dhcpのインストールと設定

あと一息です!dhcpはクライアントPCにIPアドレスを与え、クライアントPCにPXEサーバの場所を教えます。dhcpが入っていない場合はyumでインストールします。

# yum -y install dhcp

dhcpのconfigファイルを設定します。/etc/dhcpd.confに下記のような記述をします。私の環境では設定値は下表のようになりました。


Network(192.168.11.0/24) 192.168.11.0 subnet
Subnetmask 255.255.255.0 netmask
DefaultGateway 192.168.11.1 option routers
DNSServer 192.168.11.1 option domain-name-servers
DHCPで割当可能範囲 192.168.11.70 〜 192.168.11.80
PXEサーバのIPアドレス 192.168.11.5 next-server※

ddns-update-style interim;
ignore client-updates;

subnet 192.168.11.0 netmask 255.255.255.0 {

# --- default gateway
        option routers                  192.168.11.1;
        option subnet-mask              255.255.255.0;

        option domain-name              "Centos.hogehoge.com";
        option domain-name-servers      192.168.11.1;
        range dynamic-bootp 192.168.11.70 192.168.11.80;
#      next-server 192.168.11.5;
        filename "/centos/pxelinux.0";
}

filenameの箇所はtftpbootにあるpxelinux.0の場所になります。またnext-serverはPXEサーバのIPアドレスを指定してあるのですが、記述しなくてもクライアントはPXEサーバを見つけてくれました。もしうまく行かない場合は記述してみて下さい。

記述が終了したら、dhcpを起動させるのですが、ルータのDHCP機能を使用している場合はいったんDHCP機能を切ります。複数のDHCPを共存させながらPXEBOOTさせる方法もあると思うのですが、追々調べていきます。
いったんルータのDHCP機能を切った後、dhcpを起動させます。
又、PXEサーバにFirewallサービスが動作している場合はこれも休止させます(必要なPORTを空けて使用するのでも勿論構いません)。

PXEブートの実施

あとはLANケーブルをつないだクライアントPCの電源投入し、BIOS設定でネットワーク起動を有効、起動の順序を変更して再度起動させます。
問題がなければ、テキストインストール画面が出現します。いくつかの設定後、インストール方法の選択でFTPを選択して、FTPサーバのIPアドレスとイメージファイルの場所を入力します。
インストール完了後は、クライアント側はBIOS設定をリセットすること、PXEサーバ側はumount等をして下さい。

まとめ

これで、DVD-ROMドライブが壊れたPCにCentOSをインストールすることが出来ました。今回はVMware上にPXEサーバを作成した為、このVMサーバがあれば、いつでも起動させてネットワークインストール環境が手に入ります。ただインストーラーを呼び出してからのセッティングはメディアを使ったインストールと変わらず面倒なので、今度はkickstartを利用したインストールの自動化をやってみたいと思います。続く。


はじめの一歩

思い立ってから、blogを書く環境が一通り揃うまで、ちょっとばかりの時間が経ってしまったけど、ようやくはじめの一歩が踏み出せそうです。頻度は自分でも見当がつかないけど、やってみます!

PAGE TOP