http://q.hatena.ne.jp/1434818671 続き。
スクレイピングに関して、ご回答が大変参考になりました。
phpも捨てきれていませんが、a-kuma3さんのご回答でrubyを考えています。
a-kuma3さんのご回答の続きで、
1.MYSQLに書き込むこと、
2.新たに更新されたデータを書き込むこと、
を知りたいです。
問題は2.で、書き込まれたデータベースのデータとリンク先で新たに変更されたデータを追加で書き込む方法はどうしようかと。
イメージがわかないのですが、見比べる方法が必要なのでしょうか。
イメージがわかないのですが、見比べる方法が必要なのでしょうか。
なければ登録、という時はどうしても既にあるかどうかというチェックは必要になります。
もっとも厳密であろう方法はすべての項目を比較というか、一致するレコードが存在するか確認する方法です。
http://mislead.jp/1025.html
上記はPHPですがざっくりとはこんな感じかなと。ただ、値は直じゃなくプレースホルダを使います。
http://d.hatena.ne.jp/takehikom/20080623/1214170792
https://rubyist.g.hatena.ne.jp/yumimue/20071031/1193816175
rubyで詳しくだとこんな感じ?
SELECT * FROM テーブル名 WHERE カラム1=? AND カラム2=? AND ...
これで有無を判定して、なければinsertで追加。
ただ、これ1秒に何度も呼ばれる可能性のあるWebアプリとかだと重いのでどうにかして避ける事を考えます。
今回はレコード数も何万とあるわけではないし、cronでたまに回すだけだから、負荷は上がっても多分大きな問題は起きない気がします。
とはいえせっかくだし、DBには便利に使える仕組みがあるのでそれ使う方法も考えてみます。
http://q.hatena.ne.jp/1434818671#ac113090
この辺でa-kuma3さんが書いてますが「プライマリキー」というのが何度か出てきます。
これはDBに登録された1件1件の記録(レコード)を特定するための項目を差します。
質問データは、質問番号がプライマリキーなんですけど
このばあい、1434818671とか1436077068とかが質問番号で、これさえあれば人力検索での質問が特定出来ます。
つまり、全ての項目を見なくても同じ質問か分かるし、この番号が既に登録されていれば質問データが登録されている事が分かる、ということです。
ただ、更新がないとか常に最新に更新とかの場合は簡単なんですが、そうでない場合はコメントにあるように工夫が必要になったりします。
さて、今回の場合は、更新があった場合、更新前のデータはそのままに、新たに1件記録するわけですね。
で、問題は何をもって新規とか更新とかを判断するかですが、一番それっぽいのは更新日時ですね。
前提としてまったく同じ日時での更新はないと仮定します。
するとこの日時で登録あれば既に登録されているし、内容が変わったなら別の日時になる、という事になります。
ただ、それは「まったく同じ日時での更新はないと仮定」した場合です。もしこれがあると同じ日時の記録は同じ内容と判断されどれか一つだけ記録される事になります。
それを回避するには更新日時に加えて他の項目も加えます。といっても今回の場合、確実にそう保証出来るものはないというか、結局は全部比較して……みたいな話になってしまいますので、妥協点として発生日時+更新日時もしくは発生日時+都県名+更新日時でどうかな?って思います。
これらの項目をプライマリキーにしてやることで、それらが重複したものは記録で着なくなる=単純にinsertしてプライマリキーによるエラーは無視すればOKになります。
プライマリキーについては以下とかでどうでしょう。
http://northqra.com/table_3.html
http://mysql.akarukutanoshiku.com/category6/entry30.html
複数カラムにも設定出来ます。
http://www.dbonline.jp/mysql/table/index8.html
というような所でどうでしょうか。
以下予談
上記で妥協があったり、スクレイピングとかの場合、書式が変わったりエラーになったりで記録できていない事はよくあります。
恒久的な事もありますが、例外的な記述のために数日間だけごっそりない、元データは既に更新済みとか、cronで回してるとありがちです。
なので、容量に余裕があれば、取ってきたページ内容をhtmlのまま、それ様テーブルに記録しておくとかするといざと言うとき助かります。
#その時は取得日時も記録して90日とか容量にあわせ一定期間で消しておいたほうが良いです。
#それで容量食いつぶして本来の記録がエラーになるとか本末転倒なんで。
あと、最初のうちは何件登録したとか概要を標準出力に出すようにして、メールで確認しとくとか。
イメージがわかないのですが、見比べる方法が必要なのでしょうか。
なければ登録、という時はどうしても既にあるかどうかというチェックは必要になります。
もっとも厳密であろう方法はすべての項目を比較というか、一致するレコードが存在するか確認する方法です。
http://mislead.jp/1025.html
上記はPHPですがざっくりとはこんな感じかなと。ただ、値は直じゃなくプレースホルダを使います。
http://d.hatena.ne.jp/takehikom/20080623/1214170792
https://rubyist.g.hatena.ne.jp/yumimue/20071031/1193816175
rubyで詳しくだとこんな感じ?
SELECT * FROM テーブル名 WHERE カラム1=? AND カラム2=? AND ...
これで有無を判定して、なければinsertで追加。
ただ、これ1秒に何度も呼ばれる可能性のあるWebアプリとかだと重いのでどうにかして避ける事を考えます。
今回はレコード数も何万とあるわけではないし、cronでたまに回すだけだから、負荷は上がっても多分大きな問題は起きない気がします。
とはいえせっかくだし、DBには便利に使える仕組みがあるのでそれ使う方法も考えてみます。
http://q.hatena.ne.jp/1434818671#ac113090
この辺でa-kuma3さんが書いてますが「プライマリキー」というのが何度か出てきます。
これはDBに登録された1件1件の記録(レコード)を特定するための項目を差します。
質問データは、質問番号がプライマリキーなんですけど
このばあい、1434818671とか1436077068とかが質問番号で、これさえあれば人力検索での質問が特定出来ます。
つまり、全ての項目を見なくても同じ質問か分かるし、この番号が既に登録されていれば質問データが登録されている事が分かる、ということです。
ただ、更新がないとか常に最新に更新とかの場合は簡単なんですが、そうでない場合はコメントにあるように工夫が必要になったりします。
さて、今回の場合は、更新があった場合、更新前のデータはそのままに、新たに1件記録するわけですね。
で、問題は何をもって新規とか更新とかを判断するかですが、一番それっぽいのは更新日時ですね。
前提としてまったく同じ日時での更新はないと仮定します。
するとこの日時で登録あれば既に登録されているし、内容が変わったなら別の日時になる、という事になります。
ただ、それは「まったく同じ日時での更新はないと仮定」した場合です。もしこれがあると同じ日時の記録は同じ内容と判断されどれか一つだけ記録される事になります。
それを回避するには更新日時に加えて他の項目も加えます。といっても今回の場合、確実にそう保証出来るものはないというか、結局は全部比較して……みたいな話になってしまいますので、妥協点として発生日時+更新日時もしくは発生日時+都県名+更新日時でどうかな?って思います。
これらの項目をプライマリキーにしてやることで、それらが重複したものは記録で着なくなる=単純にinsertしてプライマリキーによるエラーは無視すればOKになります。
プライマリキーについては以下とかでどうでしょう。
http://northqra.com/table_3.html
http://mysql.akarukutanoshiku.com/category6/entry30.html
複数カラムにも設定出来ます。
http://www.dbonline.jp/mysql/table/index8.html
というような所でどうでしょうか。
以下予談
上記で妥協があったり、スクレイピングとかの場合、書式が変わったりエラーになったりで記録できていない事はよくあります。
恒久的な事もありますが、例外的な記述のために数日間だけごっそりない、元データは既に更新済みとか、cronで回してるとありがちです。
なので、容量に余裕があれば、取ってきたページ内容をhtmlのまま、それ様テーブルに記録しておくとかするといざと言うとき助かります。
#その時は取得日時も記録して90日とか容量にあわせ一定期間で消しておいたほうが良いです。
#それで容量食いつぶして本来の記録がエラーになるとか本末転倒なんで。
あと、最初のうちは何件登録したとか概要を標準出力に出すようにして、メールで確認しとくとか。
ちょろちょろ見てた感じだと、停電理由くらいしか更新されないのかな、という気はしますが、もしかすると地区の変更があるのかも。
という感じだったので、プライマリキーはこんな感じでしょうか。
上書きする前のデータをしばらくプールしておく、というのは大いに賛成です。
あああ 明日忘れて間に合わないといけないから今のうちに先に質問閉じておかなきゃと思ったら、ポイントさらに追加できるのを忘れていた、、
調べているのだが、どうしてはてなポイントを通常で贈れないのだろう、、
返答が遅れて申し訳なかったです。体調を崩しておりました。
引き続き勉強を続けていきたいと思っていますので、よろしくお願いします。
Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例
http://www.amazon.co.jp/gp/product/4797380357?ref_=cfb_at_prodpg
この本を購入しました。
高いだけありかなりいい本ですが、若干使い勝手は違うか、、
phpなども多そうなので、良い本があれば教えて頂きたいですね。
追加:はてなってポイントを贈呈するにはどうしたらいいんですか;;
あれIEだから悪いのかな、、ポイントも星も贈れないのだが。
質問中は終わったら贈れるものかと思っていたが、全然ダメだなぁ。
ちょろちょろ見てた感じだと、停電理由くらいしか更新されないのかな、という気はしますが、もしかすると地区の変更があるのかも。
という感じだったので、プライマリキーはこんな感じでしょうか。
上書きする前のデータをしばらくプールしておく、というのは大いに賛成です。
2015/07/13 14:36:11あああ 明日忘れて間に合わないといけないから今のうちに先に質問閉じておかなきゃと思ったら、ポイントさらに追加できるのを忘れていた、、
2015/08/04 02:45:56調べているのだが、どうしてはてなポイントを通常で贈れないのだろう、、