GRCの使いづらさにうんざりしてきたので、SERPOSCOPEに乗り換えました。使い方と使ってみた感想をお伝えします。
2022年6月のGoogleの仕様変更により、私のスキルではSERPOSCOPEを運用することができない状況です。詳しくは目次から「またGoogleの仕様変更でエラー発生」のセクションをご覧下さい。ちなみに、次の記事にあるように今はWineというツールでMacでGRCを動かす方法に移行しています。
もくじ
- 1 GRCの起動が面倒で半年以上順位チェックしなかった
- 2 GRCの料金はえげつない
- 3 GRCはチームで共有できない
- 4 オープンソースのSEPORSCOPEに惹かれる
- 5 YahooもBingも要らんだろ
- 6 GRCの囲い込み作戦にうんざり
- 7 共用サーバーではなくVPSが必要と気づく
- 8 WordPressを運用しているVPSに相乗りはリスクかも
- 9 シンプルで最安値のWebArena IndigoでVPS起動
- 10 ターミナルからSSHでログイン
- 11 Nginxのインストールと設定
- 12 SELinuxの設定を変更
- 13 Javaのインストール
- 14 SERPOSCOPEの配置と起動
- 15 WEBブラウザからアクセス
- 16 GRCとは違う!「GROUP」という概念
- 17 キーワードは一括登録できるけどちょっとトリッキー
- 18 毎日特定の時間に自動的に一括チェックできる
- 19 絶対に起こるチェック処理でのエラー
- 20 ANTI CAPTCHAでこのエラーは解消
- 21 ERROR_NETWORKはやっかいかも
- 22 Googleの仕様変更で処理が落ちてもすぐに対応
- 23 最新版へのUPGRADE方法
- 24 データ量が多くなりそう
- 25 スマホで手軽に確認できる
- 26 謎の502エラーで手動でやり直しするハメに
- 27 ANTI CAPTCHAとのデータ連携でタスクが落ちた?
- 28 ある日404エラー発生。Javaプロセスが落ちた?
- 29 Anti Captchaのワーカーが足りなくてエラーが発生
- 30 またGoogleの仕様変更でエラー発生
- 31 まとめ
- 32 さいごに
GRCの起動が面倒で半年以上順位チェックしなかった
GRCでチェックするには基本的にパソコンを起動する必要があります。キーワード数が多くなると数時間それにかかり、その間パソコンをシャットダウンできません。
パソコンを起動したくない日だってありますよね。GRCのためにパソコンを起動するなんて、なんだかコンピューターの奴隷になった気分になります。本来は人間が主人でコンピューターが奴隷であるべきです。
さらに、GRCはWindows専用です。以下で書いたように私はMacを使っているので、Prallels Desktopという特殊なソフトを使ってMac上にWindowsを起動しGRCを動かさなくてはいけません。非常に面倒くさいです。また、GRCだけのために Windowsを動かしているので、チェック中はとても負荷が大きくなり、Macのファンがうるさくなります。
そういう気持ちだったので、しだいにGRCでチェックの起動をするのをサボるようになり、半年以上も経ってしまいました。
GRCの料金はえげつない
私は100以上のURLで1000以上のキーワードをチェックしていたので、GRCの「エキスパート」というプランになり、月に1,485円になります。私の携帯代くらいかかってるんですよね。
GRCはチームで共有できない
高い金額を払ってもGRCは基本的に一人しか見ることができません。手元のパソコンにインストールするソフトだからです。
私はサイト運営の仕事をチーム化しようとしています。検索順位についてもチームで管理できた方が良いに決まっています。
もちろんサーバー側のWindowsにGRCをインストールすれば、チームでリモートから使うことができるかもしれません。でもちょっと調べた感じだとWindowsが手軽に使えるサーバー業者って無いし、あっても料金が高いです。
オープンソースのSEPORSCOPEに惹かれる
移行先を考えていましたが、一度知人から噂を聞いていたSERPOSCOPを思い出しました。たしかサーバーで動くオープンソースのソフトウェアです。ということは基本的には無料で使えます。パソコン上で使えば無料で使えますし、サーバーで使っても月数百円で使えそうです。そして、URLもキーワードも数に上限がありません。
RankTrackerなどMacで使える有料ソフトもありましたが、サーバーで動き基本は無料のSERPOSCOPEの方が魅力的だと感じました。
YahooもBingも要らんだろ
しかし、SERPOSCOPEはGoogleにしか対応していません。GRCではGoogleに加えて、YahooとBingの検索結果もチェックします。
しかし、実際の運用ではGoogleだけでいいなと考えていました。
YahooはGoogleのアルゴリズムを採用しているのでほぼ同じだし、Bingは検索市場でのシェアがわずかなのでほとんどアクセスは無いので無視して問題ありません。
そもそも指標というものは少なくてシンプルな方がわかりやすくてモチベーションが上がります。なのでGoogleだけで十分です。
スポンサーリンク
GRCの囲い込み作戦にうんざり
GRCからの移行を考え始めて、これまでのデータはSERPOSCOPEに全て移行できるのだろうかと考えました。
GRCに蓄積した全データを1ファイルに出力する機能があります。そのファイルを「引越しデータファイル」と呼びます。パソコンを買い換える際のために使うためのもののようです。全データを出力する機能はこれしかありません。このデータを出力してみたところ、拡張しが「.dat」というものでした。テキストエディターなどで開くことはできません。
CSVやXMLなどの形式であれば、エディターで開いて、なんとかSERPOSCOPEのデータ形式に変換することも可能でしょう。
しかし、この「引っ越しデータファイル」はまるで他のツールへの移行を邪魔するかのようにdatを採用しています。蓄積されるデータが多くなればなるほど移行が大変になります。
これは囲い込みと思われてもしかたないと思います。普段から「読者のために」と思ってこのブログを運営している私は、「ユーザのために」とは逆行しているGRCの姿勢に違和感を感じ、SERPOSCOPEへの移行の意志を強くしました。最悪、今までのデータはなくなってもいいやと考えました。
共用サーバーではなくVPSが必要と気づく
WordPressなどが使えるロリポップなどの共用サーバーでSERPOSCOPEが使えるのかなと思っていました。そうすると月に330円とかで使えます。私の場合、以下で書いたようにすでにロリポップを使っていたので、そこに相乗りすれば無料で使えるということです。
しかし、SERPOSCOPEはPHPではなくJavaで動いていることがわかりました。ということはJavaが動く共用サーバーを探さなければいけません。すると、1stRentalServerというサービスをみつけましたが、料金は月775円からとそこまで安くありません。
そうなるとOSから自由にソフトウェアをインストールできるVPSが必要ということになります。
WordPressを運用しているVPSに相乗りはリスクかも
VPSといえば、当サイトもWordPressを利用し、Conoha VPSというVPSで運用しています。そのVPSにJavaをインストールすれば追加料金ゼロでSERPOSCOPEを使えるじゃん。
しかし、よく考えるとこのアイディアには2つのリスクがあることに気づきました。Conoha VPSではWordPress専用のイメージを使っていて、私がゼロから設定したわけではありません。なので、JavaをインストールしてSERPOSCOPEの設定をした場合、どのようなことがあるかわかりません。サイトが落ちてしまったら大変です。
もう1つのリスクとしては、仮に適切にSERPOSCOPEを設定できて運用できたとしても、Googleからペナルティを受けた場合、サイトの評価に影響する可能性がゼロではない、ということです。 SERPOSCOPEは順位チェクのためにGoogleに対して毎日大量のアクセスを不自然なほどすることになります。すると、IPアドレスをブラックリストに入れられる可能性はあります。WordPressもそのIPアドレスなのですから、サイトのGoogleからの評価に影響しないとは言い切れません。
したがって、SERPOSCOPE専用のVPSが必要になります。専用のVPSに載せておけば、もしブラックリストに入れられれば、また新しいVPSを作ればいいのです。
シンプルで最安値のWebArena IndigoでVPS起動
既に利用経験があるConoha VPSで、新しいVPSを立ち上げてもいいのですが、もっと安いVPSはないかと探しました。サイトを運営するわけではないのでスペックは低くても構いません。なので、とにかく安いのを探しました。Conoha VPSは一番安いタイプで月682円です。
すると、WebArena Indigoが月349円ということがわかりました。
Conoha VPSはWordPressが簡単に設定できたり、複数ドメインを1つのVPSで簡単に運用できたりと色々と気が利いているのに対して、IndigoはOSをインストールしてくれるだけです。その分安いのだと思います。
そもそもConohaにもJavaがセットアップされたイメージは無いので、やることはIndigoの場合と同じです。なので安いIndigoを選ばない手はありません。こうしてWebArena Indigoを使うことに決定しました。
ここからは以下の記事にある手順でWebArena IndigoでVPSを起動した前提で、SERPOSCOPEを設定して使用する手順をご説明します。
ターミナルからSSHでログイン
Macならターミナル.app、WindowsならTeraTermなどのコンソールからVPSにsshでアクセスして設定作業を行います。Indigoの管理画面からダウンロードした秘密鍵があるディレクトリに移動し、以下のようにしてsshでアクセスします。-iで秘密鍵を指定します。「**.**.**.**」は先ほどメモしたIPアドレスです。
1 |
$ ssh -i private_key.txt centos@**.**.**.** |
この時、以下のようなエラーが発生し、ログインできない場合があります。
1 2 3 4 5 6 7 8 |
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Permissions 0644 for 'private_key.txt' are too open. It is required that your private key files are NOT accessible by others. This private key will be ignored. Load key "private_key.txt": bad permissions centos@**.**.**.**: Permission denied (publickey,gssapi-keyex,gssapi-with-mic). |
秘密鍵のパーミッションが広すぎるということです。なので以下のコマンドで制限します。
1 |
$ chmod 400 private_key.txt |
この後に、もう一度sshするコマンドを実行すればログインできるはずです。
ルート権限になります。
1 |
$ sudo su - |
デフォルトだとタイムゾーンが日本になっていない場合があるので以下をします。
1 |
# timedatectl set-timezone Asia/Tokyo |
これをしないと、SERPOSCOPEで記録されるlogなどの時刻が日本のものではなくなりわかりづらくなってしまいます。
Nginxのインストールと設定
Nginxをインストールします。
1 |
# yum -y install nginx |
ベーシック認証を利用するために、以下をインストールします。
1 |
# yum -y install httpd-tools |
ベーシック認証のためのファイルを作成します。
webfoodのところにはあなたが設定したいユーザ名に置き換えてください。password:の後には、あなたが設定したいパスワードを入力して下さい。
1 2 3 4 |
# sudo htpasswd -c /etc/nginx/.htpasswd webfood New password: Re-type new password: Adding password for user webfood |
Nginxの設定ファイルを編集します。
1 |
# vi /etc/nginx/nginx.conf |
server{}というセクションを以下に置き換えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
server { client_max_body_size 100M; listen 80 default_server; listen [::]:80 default_server; server_name _; root /var/www/serposcope; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { auth_basic "Restricted"; # 認証時に表示されるメッセージ auth_basic_user_file /etc/nginx/.htpasswd; # .htpasswdファイルのパス root /var/www/serposcope; proxy_pass http://127.0.0.1:7134; proxy_set_header X-Forwarded-Host $host; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } } |
2行目はSERPOSCOPEの画面からファイルをアップロードできるようにするために設定しています。バックアップなどのファイルをリストアする際にアップロードできるようにするためにファイルの最大サイズを100MBに設定しています。デフォルトでは1MBなので、それを超えるファイルをアップロードしようとすると「413 Request Entity Too Large」というエラーが発生してしまいます。
12、13行目でベーシック認証の設定をしています。SERPOSCOPE自体にログイン機能があるので不要といえば不要ですが、SERPOSCOPEのログイン画面すら人に見られたくなかったり、セキュリティをさらに高めるために設定しています。一度ログインすれば基本的に再度認証を求められることはなくわずらわしくないので、設定しておいて損は無いです。
15、16行目でポート番号7134へリダイレクトしています。通常SERPOSCOPEは「http://**.**.**.**:7134」というようにURLの最後に7134というポート番号をつけてアクセスする必要があるのですが、この設定のおかげでシンプルに「http://**.**.**.**」でアクセスできるようになります。
設定を反映するためにNginxを再起動します。
1 |
# systemctl restart nginx |
サーバーを再起動しても自動的にNginxを起動するために以下をします。
1 |
# systemctl enable nginx |
スポンサーリンク
SELinuxの設定を変更
SELinuxというOS付属のセキュリティシステムが動いています。デフォルトのままだと先ほど設定したNginxのポート番号7134へのリダイレクトが機能しません。なので、以下を設定します。
1 2 |
# setsebool -P httpd_can_network_relay 1 # semanage port -a -t http_port_t -p tcp 7134 |
Javaのインストール
以下でJavaをインストールします。
1 |
# yum -y install java-1.8.0-openjdk.x86_64 |
確認します。
1 2 3 4 |
# java -version openjdk version "1.8.0_312" OpenJDK Runtime Environment (build 1.8.0_312-b07) OpenJDK 64-Bit Server VM (build 25.312-b07, mixed mode) |
SERPOSCOPEの配置と起動
配置するディレクトリを作ります。
1 2 |
# mkdir -p /var/www/serposcope # cd /var/www/serposcope |
以下のようにしてSERPOSCOPEのファイルを取得します。
1 |
# curl -OL https://serposcope.serphacker.com/download/2.14.0/serposcope-2.14.0.jar |
上記のURLには執筆時点でのバージョン番号が含まれています。このURLは公式ページで以下のようにして取得できます。
SERPOSCOPEを起動します。nohupと&をつけることでターミナル終了後も動き続けます。
1 |
# nohup java -jar /var/www/serposcope/serposcope-2.14.0.jar & |
WEBブラウザからアクセス
WEBブラウザから「http://**.**.**.**」というURLにアクセスします。「**.**.**.**」はインスタンスのIPアドレスに置き換えます。
すると以下のようなベーシック認証のプロンプトが表示されるので、先ほど設定したユーザ名とパスワードを入力してログインします。
これでSERPOSCOPEの登録画面が表示されます。メールアドレスとパスワードを登録してください。
ログイン画面が表示されるので、今登録したメールアドレスとパスワードでログインします。全て英語の画面になります。
GRCとは違う!「GROUP」という概念
さっそくチェック対象のサイトやキーワードを登録していきます。まず「GROUPS」というメニューを押します。
新しいGROUPを作ります。
GROUPという概念がGRCから移行した方にとっては少しわかりづらいかもしれません。
GRCの「グループ」はあくまで表示だけの問題です。項目をまとめて表示してくれます。各項目は複数のグループに所属できるので、タグ的な使い方ができます。
これに対して、SERPOSCOPEのGROUPは、キーワードとサイトのセットです。あるキーワード群に対して、複数のサイトを順位チェックします。同じキーワード群でチェックしたい複数のサイトがあれば、一つのグループにそれらのサイトを所属させます。すると、一度の処理でそれら複数のサイトの順位を確認することができます。
GRCだと同じキーワードで複数のサイトをチェックしたい場合、それぞれのサイトごとに処理が走ってしまいます。なので、SERPOSCOPEでうまくGROUPを設定すれば、GRCよりも処理が少なくチェックできるということです。
とはいえ、現実的には、同じキーワード群で複数のサイトをチェックしたいケースは少ないと思います。例えば、「脱毛サロン比較サイトA」、「脱毛サロン比較サイトB」のように、ニッチなジャンルで複数のサイトを運営している場合はそのケースにあてはまるでしょう。とはいえ、昨今はそういうゴリゴリのアフィリエイトサイトは少なくなっていると思います。
なので、グループ一つに対して、サイト一つを所属させるという運用になると思います。したがって、私は以下のようにグループ名はサイト名(ドメイン名)にしてしまいます。
次にそのグループにサイトを登録します。
NAMEとPatternにもドメイン名でOKです。
キーワードは一括登録できるけどちょっとトリッキー
サイトを登録したら、キーワードの登録をします。
「New Search」の画面で、Keywordを入力したら、Countryには「JP-Japan」、Deviceには「Mobile」を選択してSaveします。基本的に昨今はスマホからのアクセスが主流になっているのでMobileだけチェックすればいいでしょう。これまでの経験上、スマホからの検索順位もパソコンからの検索順位もそこまで変わらないので、どちらでも良いと言えば良いです。両方調べたい場合は、それぞれの分登録します。とはいえ、全キーワードを両方チェックしていたら処理が多くなってしまうので、Mobileだけで十分です。
他の項目は特に何も設定しなくて大丈夫です。
ちなみに、設定画面でCountryのデフォルト値を変えられます。「JP-Japan」にしておくと楽です。ADMINからGOOGLEをクリックします。
少しスクロールすると、デフォルト値を設定できるフォームがあります。Deviceもあるので設定できるのかと思ったのですが、なぜかここでMobileにしても反映されませんでした。多分バグでしょう。
キーワードは複数を一括登録することもできます。先ほどの「New Search」の画面で、「Bulk Import」を押します。
すると複数行入力できるフォームが現れるので、1行に1キーワードを入力します。ただ、Countryをはじめとする他の項目も入力する必要があり、カンマ区切りで入力する必要があります。
keyword,country-code,datacenter,device,local,custom
という順番です。必要なのは、keyword、country-code、deviceです。なので、例えば、「エッセンシャル思考 書評」というキーワードなら、
エッセンシャル思考 書評,JP,,mobile,,
と入力します。残念ながらデフォルト値にJPと設定していても、ここでは指定する必要があります。これを1行に1キーワード分を入力します。例えば4つのキーワードなら以下のように入力します。
エッセンシャル思考 書評,JP,,mobile,,
エッセンシャル思考 要約,JP,,mobile,,
エッセンシャル思考 感想,JP,,mobile,,
ヨメレバ 使い方,JP,,mobile,,
キーワードが数十個など多くなってくると、1行1行を手作業で作ると大変です。なので、正規表現が使えるエディターなどを使って、キーワードだけの一覧に、残りの文字列を一括で付与するといいでしょう。例えば、上記は元々は以下のキーワードだけの一覧でした。
エッセンシャル思考 書評
エッセンシャル思考 要約
エッセンシャル思考 感想
ヨメレバ 使い方
私はAtomというエディターを使っています。正規表現を有効にして置換します。置換対象として以下を指定します。これは改行コードを表す正規表現です。
\n
置換後の文字列を以下とします。改行コードの前に、他の項目を示すカンマ区切りの文字列を指定しています。
,JP,,mobile,,\n
これで一括置換すると、一瞬で先ほどの形式になります。この辺りは人それぞれ楽な方法があると思いますので、一例としてやり方を説明しました。
キーワードが登録できたら、さっそく順位チェックの処理を走らせます。
メーターが表示されるので、100%になったら完了です。
初回でたまたまチェック処理が成功することもあります。しかし、このままだと、多くの場合はエラーが発生すると思ってください。エラーへの対策は後述します。
チェック処理のスピードは厳密に比べてはいないのですが、GRCと比べて遅いということはないです。私の場合、初期設定のままで954キーワードで64分かかっています。ざっくり1000キーワードで1時間ということです。
順位を確認するには、サイトごとの画面まで行く必要があります。まずGROUPSを押します。
グループ名を押します。
サイト名を押します。
すると順位が表示されます。
スポンサーリンク
毎日特定の時間に自動的に一括チェックできる
SERPOSCOPEはわざわざ手動でチェック処理を起動しなくても、毎日特定の時間に自動的にチェック処理をしてくれるように設定できます。GRCでもできましたが、SERPOSCOPEはサーバー側にあるので、パソコンを開いていなくてもチェックしてくれます。
ADMINからGENERALを開きます。
Cron Timeに、毎日自動的にチェックしてほしい時間を入力してSaveします。私の場合は、朝方の私が作業していない時間に走らせるようにしています。5時丁度などはGoogleさんに怪しまれそうなので、少し中途半端な時間にしています。
絶対に起こるチェック処理でのエラー
チェック処理を走らせると間違いなくエラーが発生すると思ってください。以下のように「Failure」と表示されます。Logsを押すとエラーの内容を確認できます。
ログのエラーの周辺部分を切り出しました。
1 2 3 4 5 |
[2021-12-16 17:09:28,760] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - GET https://www.google.com/search?q=#OBF#search-104#&gl=jp&num=100 via proxy:direct try 1 [2021-12-16 17:09:29,181] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT status=[302] exception=[none] [2021-12-16 17:09:29,714] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT[refetch] status=[302] exception=[none] [2021-12-16 17:09:29,715] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - captcha form detected via proxy:direct [2021-12-16 17:09:29,762] [google-0] WARN c.s.s.t.g.GoogleTaskRunnable - scrap failed for #OBF#search-104# because of ERROR_CAPTCHA_NO_SOLVER |
5行目の「ERROR_CAPTCHA_NO_SOLVER」というのがエラーの種類を表しています。結論からいうと、このエラーは解決可能です。
ANTI CAPTCHAでこのエラーは解消
ERROR_CAPTCHA_NO_SOLVERというエラーについて説明します。最近のWebサービスでは、人間とSERPOSCOPEのようなボットを区別するためにCAPTCHAという仕組みがあります。これは手書きの文字の画像を読ませて入力させたり、特定の種類の写真を選ばせたりします。人間と判断できれば、正常に使用させてくれますが、ボットだと判断されればエラーを表示しそれ以上の利用を拒否します。Googleも怪しいアクセスには、検索結果を返さずCAPTCHAを表示します。AIなどの技術を使ってもボットはこれをクリアできません。
しかし、最近ではこのCAPTCHAを乗り越える仕組みが出来てきています。どのような仕組みかというと、AIではなく「人間」を使います。ボットに対してCAPTCHAが表示された時に、即座に世界中に待機している人間の誰かに自動的に割り振ります。その人がそのCAPTCHAを解きます。すると、WEBサービスはそのボットを人間とみなしてくれます。
おそらく、そのCAPTCHAを解いてくれる人は、発展途上国に住む方々だと思われます。解くごとにわずかばかりのお金が彼らに支払われます。先進国に住む人にとっては少額でも、物価の安い発展途上国の人にとってみれば良い仕事になっているのでしょう。なので、そのような仕組みを使うボットを運営する側の人がお金を払うことになります。とはいえ、あとで説明しますが、SERPOSCOPEの場合、非常に少額で無視レベルできるのコストです。
そのようなCAPTCHAを乗り越える仕組みの一つがANTI CAPTCHAというサービスです。日本人スタッフがいないのか、日本語が少しおかしい部分がありますが、それはご愛嬌(笑)
このサービスでアカウントを作って入金します。
メールアドレスに送られてきたパスワードを使ってログインします。ログインすると利用規約が表示されます。
入金します。前払いである程度のデポジットをしておき、CAPTCHAを解決してもらうごとにそこから引かれるという仕組みです。
様々な支払い手段がありますが、私の場合はVISAで行いました。
この支払い方法の選択の意味がよくわからなかったのですが、とりあえず「クレジットまたはデビットカードでのお支払い」を選択しました。
最少額の5ドルを選択します。
カード情報を入力します。
ちなみにKyashなどのプリペイド型のカード情報だとうまくいかないようです。通常のクレジットカードの情報を入力します。
一人一人に割り振られる、アカウントキーをコピーします。
これをSERPOSCOPE側の設定画面で入力します。どこに入力するかというと、ADMINからGENERALを開きます。
少しスクロールすると、ANTI CAPTCHA用の入力欄があります。ここに先ほどのキーを入力し、「Test credentials」を押して問題なければSaveします。これでERROR_CAPTCHA_NO_SOLVERは発生しなくなります。
ちなみに、同様の他のサービス用の入力欄もあります。複数のサービスを設定しておくと、一つのサービスで解決してくれる人がすぐに応募してくれない場合、他のサービスに切り替わり、解決できないという可能性をさらに下げることができます。とはいえ、私の場合はANTI CAPTCHAだけでも問題は発生していません。
ANTI CAPTCHAにどのくらいコストがかかるのか気になると思いますが、思った以上に少ないです。ANTI CAPTCHAの管理画面で、利用実績を確認できます。
なんと1日1回〜3回程度しか利用されておらず、金額にすると0.002〜0.006ドルしか使われていません。私はこの時点で954キーワードありますが、キーワードごとにCAPTCHAが発生するわけではなく、1日に1回〜3回程度発生してそれを解決すれば他のキーワードでは発生していないということです。
1週間使いましたが0.02ドルしか使われていません。なので、1ヶ月使っても0.08ドルということです。大体9円程度です。
つまり、954キーワードでも1月9円ということです。なので無視できるレベルのコストと言っていいでしょう。
おそらく、キーワードの数に比例してコストが増えるわけではないです。基本的に何キーワードあっても一括処理は1日1回です。そのたびに1〜3回程度CAPTCHAが発生するだけだからです。
CAPTCHAの問題はGRCでも発生しているはずです。GRCでも裏ではこういうサービスを使って対処しているのでしょう。
ERROR_NETWORKはやっかいかも
実は最初に作ったWebArena Indigoで最初に作ったVPSでチェック処理を走らせた際に、Failureとなりました。その時のログからエラー周辺を切り出したものです。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[2021-12-18 03:06:08,474] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - GET https://www.google.com/search?q=#OBF#search-309#&gl=jp&num=100 via proxy:direct try 1 [2021-12-18 03:06:08,617] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT status=[302] exception=[none] [2021-12-18 03:06:08,675] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT[refetch] status=[302] exception=[none] [2021-12-18 03:06:08,675] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - GET https://www.google.com/search?q=#OBF#search-309#&gl=jp&num=100 via proxy:direct try 2 [2021-12-18 03:06:08,841] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT status=[302] exception=[none] [2021-12-18 03:06:08,884] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT[refetch] status=[302] exception=[none] [2021-12-18 03:06:08,884] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - GET https://www.google.com/search?q=#OBF#search-309#&gl=jp&num=100 via proxy:direct try 3 [2021-12-18 03:06:09,054] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT status=[302] exception=[none] [2021-12-18 03:06:09,099] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT[refetch] status=[302] exception=[none] [2021-12-18 03:06:09,107] [google-0] WARN c.s.s.t.g.GoogleTaskRunnable - scrap failed for #OBF#search-309# because of ERROR_NETWORK [2021-12-18 03:06:09,108] [google-0] WARN c.s.s.t.g.GoogleTaskRunnable - no more proxy, stopping the thread [2021-12-18 03:06:09,108] [google-0] INFO c.s.s.t.g.GoogleTaskRunnable - google thread stopped [2021-12-18 03:06:09,143] [Thread-13] WARN c.s.s.t.g.GoogleTask - 1 proxies failed during the task |
10行目に「ERROR_NETWORK」とあります。ネットで調べると、設定画面で変更できるGoogleへのアクセスの間隔(Pause)です。キーワードごとにGoogleへアクセスしますが、その間隔の時間を長くとることでこのエラーはなくなる、という情報がありました。
最初に何キーワードかは成功していて、途中でこのエラーが発生している場合は、もしかしたらPauseの値を調整することでエラーが発生しなくなるかもしれません。
しかし、私の場合は、1キーワード目でこのエラーが発生します。何回処理をやり直しても1キーワード目で発生します。なので、Pauseは関係ありません。
数時間試行錯誤した末、よくわからなかったので、IndigoでVPSをゼロから作成しなおして、再度SERPOSCOPEをセットアップして処理を実行したら、なぜかこのエラーは発生しなくなりました。
もしかしたら、何らかの理由で一度Googleにボット認定されたらIPアドレスがブラックリストに載ってしまうのかもしれません。なのでVPSを作り直してIPアドレスが変わった途端、エラーが無くなったのかもしれません。
VPSは簡単に作り直せて手軽にIPアドレスを変えられるので、SERPOSCOPEと相性がいいですね。ちなみに、GRCなどで手元の端末から順位チェックしていてブラックリストに入れられてしまった場合は大変です。オフィスや自宅やモバイルWifiのIPアドレスがブラックリストに入れられたことになります。それらのIPアドレスは簡単には変えられません。
Googleの仕様変更で処理が落ちてもすぐに対応
ある日数日ぶりにSERPOSCOPEにブラウザからアクセスしてみると、Failureという赤文字が表示されました。Tasksの画面を開くと、6日前からタスクが落ちていることがわかりました。
ログを開いてみると、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
[2022-01-19 04:11:00,151] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - GET https://www.google.com/search?q=#OBF#search-643#&gl=jp&num=100 via proxy:direct try 1 [2022-01-19 04:11:00,541] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT status=[302] exception=[none] [2022-01-19 04:11:00,975] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT[refetch] status=[302] exception=[none] [2022-01-19 04:11:00,975] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - captcha form detected via proxy:direct [2022-01-19 04:11:01,010] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - noscript form detected, trying with captcha image [2022-01-19 04:11:01,010] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - can't find captcha img tag [2022-01-19 04:11:01,010] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - GET https://www.google.com/search?q=#OBF#search-643#&gl=jp&num=100 via proxy:direct try 2 [2022-01-19 04:11:01,404] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT status=[302] exception=[none] [2022-01-19 04:11:01,656] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT[refetch] status=[302] exception=[none] [2022-01-19 04:11:01,656] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - captcha form detected via proxy:direct [2022-01-19 04:11:01,692] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - noscript form detected, trying with captcha image [2022-01-19 04:11:01,693] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - can't find captcha img tag [2022-01-19 04:11:01,693] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - GET https://www.google.com/search?q=#OBF#search-643#&gl=jp&num=100 via proxy:direct try 3 [2022-01-19 04:11:02,235] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT status=[302] exception=[none] [2022-01-19 04:11:02,562] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT[refetch] status=[302] exception=[none] [2022-01-19 04:11:02,562] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - captcha form detected via proxy:direct [2022-01-19 04:11:02,598] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - noscript form detected, trying with captcha image [2022-01-19 04:11:02,598] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - can't find captcha img tag [2022-01-19 04:11:02,598] [google-0] WARN c.s.s.t.g.GoogleTaskRunnable - scrap failed for #OBF#search-643# because of ERROR_NETWORK [2022-01-19 04:11:02,598] [google-0] WARN c.s.s.t.g.GoogleTaskRunnable - no more proxy, stopping the thread [2022-01-19 04:11:02,598] [google-0] INFO c.s.s.t.g.GoogleTaskRunnable - google thread stopped [2022-01-19 04:11:02,601] [Thread-43] WARN c.s.s.t.g.GoogleTask - 1 proxies failed during the task |
5、6行目のようなメッセージが出て、「can't find captcha img tag」となっていました。19行目で「ERROR_NETWORK」となり処理が終了していました。
とりあえず、他の人も同じような事象を経験していないかフォーラムを調べてみました。
すると、以下のように全く同じ事象を報告するスレッドがあり、読んで行くと開発側がすぐに対応して最新版で修正すると書いてありました。
Problems with solving captchas
おそらくGoogle側でなんらかの変更があったと思われます。なので、一斉にみなさんエラーが出てここで報告されて、開発側が対処したということです。
この辺りは対応が早いですね。
SERPOSCOPEの画面をよくみると、上のほうにいつもは無い「NEW VERSION!」という文字が表示されていました。
おそらく最新版にUPGRADEすれば直るだろうと考えました。
ただ、6日間気がつかなかったので、処理が落ちたらメールなどで通知してくれる仕組みがあればもっと早く気付くのになと思います。まぁ、ログを解析して落ちてたらメール通知するシェルスクリプトを自分で書いてCronに登録しておけば、同じことができそうですが。
最新版へのUPGRADE方法
公式ドキュメントにUPGRADE方法はサラッとしか書いてありません。
How to upgrade serposcope ?
Before any upgarde, backup your database using the backup feature of the admin panel or by copying the data directory (see below).
Then just install over previous serposcope install.
データのバックアップをとって、前バージョンに新バージョンを上書けと書いてあります。
データのバックアップはとってもいいのですが、明確にデータのディレクトリが決まっているので、UPGRADEの作業で壊れることはないと思うので、特にとりませんでした。
心配であれば、設定画面の「SAVE」でSQLダンプのファイルをダウンロードしておいてもいいかもしれません。
VPSにターミナルからSSHでログインしてUPGRADEの作業をします。
1 2 3 |
$ ssh -i private_key.txt centos@**.**.**.** $ sudo su - # cd /var/www/serposcope |
以下のようにしてSERPOSCOPEの最新のファイルを取得します。指定するURLは前述したインストール時と同じように、公式ページから取得できます。この処理は数分かかります。
1 |
# curl -OL https://serposcope.serphacker.com/download/2.15.0/serposcope-2.15.0.jar |
現在動いているプロセスの番号を調べて、落とします。
1 2 3 4 |
# ps -ef | grep java root 16158 1 0 2021 ? 01:55:43 java -jar /var/www/serposcope/serposcope-2.14.0.jar root 99789 99700 0 16:29 pts/0 00:00:00 grep --color=auto java # kill -9 16158 |
この段階でブラウザでアクセスしてみると、Nginxの404エラーが出て落ちていることがわかります。
新しい方のファイル名を指定して起動します。
1 |
# nohup java -jar /var/www/serposcope/serposcope-2.15.0.jar & |
ここで古い方のファイルは削除しても大丈夫ですが、念のため何かあった時に切り戻すために次のUPGRADE時まで残しておいてもいいかもしれません。
これでブラウザからアクセスするとSERPOSCOPEのログイン画面が出るので、ログインするとバージョン番号が最新になっていることが確認できます。
GRCでもおそらく同じようにUPGRADEしなければならない機会はあるはずですが、GRCはクリック1つでUPGRADEできるのであまり意識することはありませんでした。その点SERPOSCOPのUPGRADE作業は少し手数が多いですね。
UPGRADEが完了したので、手動でチェック処理を走らせると問題なく完了しました。
スポンサーリンク
データ量が多くなりそう
少し運用していて気づいたのですが、キーワード一つ一つについて、自分のサイト以外のURLも表示してくれます。ということは、これらのURLも全て毎回保存しているというこです。GRCはこのような機能はデフォルトでは無かったと思います。なので、SERPOSCOPEではデータ量が多くなることが少し心配です。
気になったので、SERPOSCOPEのデータが保存されるdb.mv.dbというファイルを調べてみたところ、約340MBになっていました。
約1,000キーワードで1か月使った状態です。ということは1年使うと4GB程度になります。私のVPSは20GBの容量ですが、現在使用可能なのが17GBなので4年程度使えることになります。まぁ、4年使えればいいかなと思いますが、GRCでは容量について意識もしなかったので、少しストレスかもしれません。
設定画面で「History limit」という項目があり、データを何日残すかを決められます。ここでVPSの容量を超えない日数にすればいいと思います。デフォルトは365日になっていてちょっと短いので、伸ばしてもいいかもしれません。
個人的には人のサイトのURLまでは保存しなくてよくて、順位だけ保存してくれれば十分なのになぁと思います。このあたりは変えて欲しいですね。
あと、自動チェックは毎日動く仕様になっているのですが、1週間に1回とかでも良いしその方がデータ量を抑えられると思います。頻度を設定で変更できないのが残念です。
スマホで手軽に確認できる
ブラウザから使えるので、当然スマホからも確認できます。なので電車で移動中にちょろっと見ることだって可能です。処理が落ちた時にメール通知が無いという不満をもらしましたが、毎日のようにスマホでチェックしていれば、処理が落ちていてもすぐに気が付けるかもしれません。
ただ、PC用の画面になっているので、スマホだと少し見づらいです。表が横長なので、左にある肝心のキーワードを見るためには、左まで横スクロールしなければなりません。
画面を横にすると、少し見やすくなりますが、やはりキーワードは左に横スクロールする必要があります。
普通のWEBサイトと同じようにブックマークできるので、iPhoneならホーム画面に入れてワンタップで開くことができます。まるでGRCをスマホにインストールしているかのような感覚です。
ちなみに、iPhoneのSafariだと、なぜかベーシック認証を毎回求められてしまうので、以下の方法でパスワードを保存しておくのがおすすめです。
謎の502エラーで手動でやり直しするハメに
SERPOSCOPE運用開始から50日目くらいに、Failureという赤い文字が表示されていて、その日の自動チェック処理が落ちていることに気づきました。
1 2 3 4 5 6 7 8 9 10 11 12 |
[2022-02-03 04:38:13,668] [google-0] INFO c.s.s.t.g.GoogleTaskRunnable - search "#OBF#search-757#" | try 1 | total search done : 442/969 [2022-02-03 04:38:13,668] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - GET https://www.google.com/search?q=#OBF#search-757#&gl=jp&num=100 via proxy:direct try 1 [2022-02-03 04:38:15,239] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT status=[502] exception=[none] [2022-02-03 04:38:15,239] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - GET https://www.google.com/search?q=#OBF#search-757#&gl=jp&num=100 via proxy:direct try 2 [2022-02-03 04:38:16,778] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT status=[502] exception=[none] [2022-02-03 04:38:16,778] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - GET https://www.google.com/search?q=#OBF#search-757#&gl=jp&num=100 via proxy:direct try 3 [2022-02-03 04:38:18,313] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT status=[502] exception=[none] [2022-02-03 04:38:18,313] [google-0] WARN c.s.s.t.g.GoogleTaskRunnable - scrap failed for #OBF#search-757# because of ERROR_NETWORK [2022-02-03 04:38:18,316] [google-0] WARN c.s.s.t.g.GoogleTaskRunnable - no more proxy, stopping the thread [2022-02-03 04:38:18,316] [google-0] INFO c.s.s.t.g.GoogleTaskRunnable - google thread stopped [2022-02-03 04:38:18,319] [Thread-28] WARN c.s.s.t.g.GoogleTask - 1 proxies failed during the task [2022-02-03 04:38:18,319] [Thread-28] WARN c.s.s.t.g.GoogleTask - 527 searches have not been checked |
1,000個ほどのキーワードのちょうど半分位終わったところで、上の3、5、7行目の502というステータスコードを3回連続受けて、最終的に8行目のERROR_NETWORKが出て処理が終了してしまっていました。
今までSERPOSCPEのログでは見たことがなかったので、理由が全く思いうかばなかったのですが、とりあえず処理を手動で起動してみました。
グローバルメニューの「CHECH RANKS」をクリックして表示される、「Recheck failed/new keywords」を押せばいいのかな、と思いました。ボタンの下に
Recheck failed keywords of the previous task or recently added keywords(will update previous task without changing the check date)
前回のタスクで失敗したキーワードか最近追加したキーワードをチェックする(前回のタスクをチェック日付を変えずに更新する)
と書かれています。(和訳は私による)
ただ、もう一つ似たようなボタンがあったのを思い出しました。「Tasks」をクリックすると表示される画面のそれぞれのタスクの右側に、「Rescan SERP」というボタンがあります。これを押した方がいいのかなという気もしました。(下の画面は今回のエラーのタスクではありません)
試しに押してみると、下のようなメッセージが表示されました。
SERP rescan is only needed when:
- Website added while a task was running
- Manual import of SERP in the databaseSERP rescanは以下の場合にのみ必要になる
- Websiteがタスクの実行中に追加された
- データベースに手動でSERPをインポートした
と書かれています。(和訳は私による)
よくわからなかったけど、最初に押そうとした「Recheck failed/new keywords」の説明の方がフィットしていたので、「Recheck failed/new keywords」を押しました。
すると、失敗したキーワードだけチェックされました。順調に進んでいます。完了すると、赤くなっていたこの日のタスクが緑に変わりました。もしかしたら、「SERP rescan」を押しても同じ事が起きるのかもしれませんが。
さて、502というステータースコードは何だったのでしょうか?調べたところ、サーバー側(つまりGoogle側)の問題だそうです。
つまり、こちらでは何もできません。もしかしたらGoogleで障害が発生していたのかもしれません。何時間か経って、手動で実行した時には障害が直っていて、適切にチェックできたと推察されます。
とはいえ、GRCは何年も使ってもこのようなことはなかったと思うので、ちょっと不安になりました。もし障害が発生していたら、GRCでも同じようにチェックができなくなるはずなのですが。今回は相当タイミング悪く障害が起きていたのかなと思いたいです。もしくは、GRCの時もこのように処理が止まっていたのかもしれないですが、自動的にある程度の時間を待って実行し直すプログラムなどがあり、うまく502エラーに対処していたのかもしれません。
この502エラーが他に起きていないか気になったので、ログを調べてみました。すると、この日のログの処理が落ちる前に3回ほど発生していました。しかし、そこでは処理は落ちていなかったのです。例えば、以下の3行目です。
1 2 3 4 5 6 |
[2022-02-03 04:15:08,677] [google-0] INFO c.s.s.t.g.GoogleTaskRunnable - search "#OBF#search-656#" | try 1 | total search done : 84/969 [2022-02-03 04:15:08,677] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - GET https://www.google.com/search?q=#OBF#search-656#&gl=jp&num=100 via proxy:direct try 1 [2022-02-03 04:15:10,380] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT status=[502] exception=[none] [2022-02-03 04:15:10,380] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - GET https://www.google.com/search?q=#OBF#search-656#&gl=jp&num=100 via proxy:direct try 2 [2022-02-03 04:15:11,341] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT status=[200] exception=[none] [2022-02-03 04:15:11,346] [google-0] TRACE c.s.s.s.g.s.GoogleScraper - sleeping 5000 milliseconds |
しかし、5行目を見て頂くとわかるように、2回目のtryだと200ステータスが返ってきており、正常にチェックできているのです。
一つのキーワードにつき、うまくチェックできない場合、3回までGoogleへのアクセスをtryします。処理が落ちることになったキーワードでは、3回とも502が返ってきたため落ちました。しかし、その前に実行された落ちなかった3つのキーワードでは、すべて2回目のtryで200が返ってきていました。
ということは、この日、断続的に502が発生するタイミングがあったり、復旧したりというのを繰り返していたのでしょう。運悪く502の状態が長く続いて3回のtryがその時間帯に入ってしまって落ちてしまったということでしょう。
ちなみに、この日以外の過去のログも見て、502が発生していないか確認したところ、発生していませんでした。なので、かなり稀なケースと言えると考えています。
ただ、また発生しない保証はありません。この事象に対して設定で何かできないかと考え、設定画面を見てみました。「ADMIN」というグローバルメニューから「Google」をクリックします。
するとtryの回数は3回で固定だと思っていたのですが、上のように「Fetch retries」という値で変えられることがわかりました。なので、これを10に変えてみました。3回のうちには502から復旧しないが、10回やるうちに復旧するかもしれないかなと考えたので。
ちなみに、この数値を増やしても処理時間が大幅に伸びることはないと考えています。というのは、基本的にほとんどのキーワードは1アクセスで成功しています。稀に502などが発生し、その時だけretryが発生するからです。
また、今回の件とは関係無いのですが、この画面で一つ気になったのが、「Pause」の「Min」と「Max」という設定値です。今まで、Googleへのアクセスは「5秒置き」に固定されていたのはMinとMaxが両方とも5になっていたからということがわかりました。この二つの値を別のものにすれば、その間に入る乱数を毎回発生させ、その時間だけ置く、というようにできるようです。
Googleから見れば、毎回カチッと全く同じ秒数を置いてアクセスしてくる人がいたら、ボットだと判断しやすくなるのではないでしょうか。ボットだと判断されると私のサーバーのIPアドレスをブラックリストに入れられて、アクセスできなくされてしまうかもしれません。なので、ここをMinに4、Maxに6を入れました。
ANTI CAPTCHAとのデータ連携でタスクが落ちた?
さらに5日後また「Fiailure」と表示され、確認するとタスクが落ちていました。ログをみると、7行目以降のまだ見たことのないERRORが発生しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[2022-02-08 04:10:56,964] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - GET https://www.google.com/search?q=#OBF#search-77#&gl=jp&num=100 via proxy:direct try 1 [2022-02-08 04:10:57,474] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT status=[302] exception=[none] [2022-02-08 04:10:57,841] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT[refetch] status=[302] exception=[none] [2022-02-08 04:10:57,841] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - captcha form detected via proxy:direct [2022-02-08 04:10:57,877] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - trying with captcha recaptcha [2022-02-08 04:10:57,877] [google-0] INFO c.s.s.s.c.s.RandomCaptchaSolver - trying anticaptcha [2022-02-08 04:10:58,808] [google-0] ERROR c.s.s.t.g.GoogleTaskRunnable - unhandled exception, aborting the thread java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer at com.serphacker.serposcope.scraper.captcha.solver.AntiCaptchaSolver.solve(AntiCaptchaSolver.java:197) ~[serposcope-2.15.0.jar:na] at com.serphacker.serposcope.scraper.captcha.solver.RandomCaptchaSolver.solve(RandomCaptchaSolver.java:47) ~[serposcope-2.15.0.jar:na] at com.serphacker.serposcope.scraper.google.scraper.GoogleScraper.recaptchaForm(GoogleScraper.java:546) ~[serposcope-2.15.0.jar:na] at com.serphacker.serposcope.scraper.google.scraper.GoogleScraper.handleCaptchaRedirect(GoogleScraper.java:487) ~[serposcope-2.15.0.jar:na] at com.serphacker.serposcope.scraper.google.scraper.GoogleScraper.downloadSerp(GoogleScraper.java:185) ~[serposcope-2.15.0.jar:na] at com.serphacker.serposcope.scraper.google.scraper.GoogleScraper.scrap(GoogleScraper.java:101) ~[serposcope-2.15.0.jar:na] at com.serphacker.serposcope.task.google.GoogleTaskRunnable.run(GoogleTaskRunnable.java:99) ~[serposcope-2.15.0.jar:na] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_312] [2022-02-08 04:10:58,813] [google-0] INFO c.s.s.t.g.GoogleTaskRunnable - google thread stopped [2022-02-08 04:10:58,816] [Thread-34] WARN c.s.s.t.g.GoogleTask - 0 proxies failed during the task |
今まではタスクが落ちていてもWARNだったのでERRORというのはもっと深刻なのかと少し焦りました。
よく見ると、ANTI CAPTCHAが起動したタイミングで起きています。"java.lang.Long cannot be cast to java.lang.Integer"とあるので、期待したデータ形式じゃないデータを受け取ってしまったことによって発生したと考えられます。
フォーラムを確認してもまだ誰も何の報告もしていません。ANTI CAPTCHA側の問題かもしれないので、そちらの管理画面を開いてみても特に何のお知らせもありません。
とりあえず、手動で実行しなおしてみたところ、やはり同じエラーが発生します。時間がなかったのでとりあえずは放置しました。
数時間後、ANTI CAPTCHA以外のsolverを使えばいいのかな、とか対応を考えました。もしそれでも同じことが発生するなら、GRCに戻らなきゃダメかなと暗い気持ちになっていました。とりあえず、何も変えずにもう一回だけ手動実行してみることにしました。
すると、なんと正常にタスクが全て完了しました。ANTI CAPTCHAも1回起動して、正常に完了していました。ますますわからなくなり、余計に不安になりました。
翌日、なんとなくANTI CAPTCHAの管理画面を開いてみると、1件お知らせが来ていました。通知のアイコンをクリックしてそれを開くと、以下のようなメッセージが表示されました。
Problem with bigInt resolved
Today some of our customers had problems with our API. When a new task was created, API returned taskId which had value larger than 2147483647, which was not supported in those customers apps. Their software was converting this value to a negative integer like -2152295413 and they couldn't request task results with this ID.
We've reset the task id counter and now all IDs are generated in range from 0 to 2147483647. Your apps should start working again without issues. We'll monitor this in the future and will reset the counter, but if you'd like to improve this moment, then ask your developer to implement support of bigint values for our task IDs.
Previously there were no issues with this because we were restarting database server more frequently and ID counter was resetting automatically.
OK
要するに、ANTI CAPTCHA側が返すタスクのIDがある値を超える値(bigInt)の場合、SERPOSCOPE側が負の値に変換してしまうので、エラーが発生してしまうということです。今回はANTI CAPTCHA側が対応し、IDをリセットして小さい値に戻したのでエラーが発生しなくなったということです。問題発生の翌日には対応したのはすごく早いですね。ANTI CAPTCHA側にとってはSERPOSCOPEのユーザは無視できない程大きいのでしょう。SERPOSCOPEがbigIntを扱えないのが原因だ!と言って問題を放置していたら、他のsolver業者にみんな乗り換えちゃいますからね。
とはいえ、本質的な問題はSERPOSCOPEがbigIntを扱えないことな気もするので、改修をするべきかもしれません。
あと、Errorが起きても、処理を全て落とすのではなく、別のsolverを起動するなど、処理を続ける工夫があってもいいかもしれません。(もしかしたらそうなってるのかな?別のsolverを設定していないのでわかりません)
このタイミングでフォーラムをのぞくと、同じエラーを報告する人がいたので、上記のことを教えてあげました。
とりあえず、原因がわかったので安心しました。しかし、このようなことでしばしば問題が起きると面倒だな、という気もします。
とはいえ、SERPOSCOPEは必ず毎日実行されるのに対して、GRCは気が向いた時にパソコンを起動した日にしか実行しません。なので、SERPOSCPEの方が問題を見る機会は多くなってしまうのは仕方ない、とも言えるので、もう少し長い目で見てあげることにします。
ある日404エラー発生。Javaプロセスが落ちた?
ある日ブラウザからアクセスすると404 Not Foundの画面が表示されました。
また不具合かー、と思って気分が落ち込みましたが、冷静さを取り戻して原因究明に取り組みました。
iPhoneからもアクセスしてみると、ベーシック認証をした後は、同じように404 Not Foundの画面が表示されました。
この画面はNginxが出している画面なのでサーバーは落ちておらず、Nginxまでは動いているということです。なので、Javaのプロセスが落ちているのかな、と推測できます。
ターミナルからサーバーにログインして確認していきます。
1 2 |
$ ssh -i private_key.txt centos@**.**.**.** $ sudo su - |
SERPOSCOPEのプロセスの存在を確認します。
1 2 |
# ps -ef | grep java root 230478 230458 0 20:36 pts/1 00:00:00 grep --color=auto java |
やはりプロセスがなくなっています。
なので、またSERPOSCOPEを起動するコマンドを実行します。ファイル名のバージョン番号はご自身の環境のもに変えて下さい。
1 |
# nohup java -jar /var/www/serposcope/serposcope-2.15.0.jar & |
これでまた正常に動き出します。
とはいえ、原因特定&再発防止しなければなりません。
プロセスが落ちた時の状況がわかるログが見たいところです。どこにログがあるかを調べていたところ、プロセスが落ちた場合は、以下の記事にあるようにhs_err_pid*.logというようなファイル名でログが生成されるらしいのですが、みつかりません。
よくわからなかったのですが、サーバー全体のログが集まっているように見えた/var/logの中を探すことにしました。タイムスタンプが新しいファイルから探して行きます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# cd /var/log # ls -ltl total 14928 -rw-------. 1 root root 782654 Mar 2 21:05 secure -rw-------. 1 root utmp 178176 Mar 2 21:05 btmp -rw-r--r--. 1 root root 27979 Mar 2 21:01 cron -rw-------. 1 root root 45701 Mar 2 20:48 messages -rw-rw-r--. 1 root utmp 292292 Mar 2 20:48 lastlog -rw-rw-r--. 1 root utmp 8832 Mar 2 20:48 wtmp -rw-r--r--. 1 root root 554926 Mar 2 20:29 dnf.log -rw-r--r--. 1 root root 76039 Mar 2 20:29 dnf.rpm.log -rw-r--r--. 1 root root 793218 Mar 2 20:29 dnf.librepo.log -rw-------. 1 root root 1380 Mar 2 18:41 hawkey.log (以後省略) |
すると、messagesというファイル内に怪しい部分をみつけました。
1 |
# cat messages |
これでも抜粋ですが、長くてすみません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
Mar 1 05:22:17 i-14100000241979 systemd[1]: Starting dnf makecache... Mar 1 05:22:18 i-14100000241979 dnf[227197]: CentOS Stream 8 - AppStream 6.2 kB/s | 4.4 kB 00:00 Mar 1 05:22:26 i-14100000241979 dnf[227197]: CentOS Stream 8 - AppStream 2.5 MB/s | 20 MB 00:08 Mar 1 05:25:07 i-14100000241979 kernel: pool-2-thread-1 invoked oom-killer: gfp_mask=0x6200ca(GFP_HIGHUSER_MOVABLE), order=0, oom_score_adj=0 Mar 1 05:25:07 i-14100000241979 kernel: CPU: 0 PID: 99819 Comm: pool-2-thread-1 Kdump: loaded Not tainted 4.18.0-277.el8.x86_64 #1 Mar 1 05:25:07 i-14100000241979 kernel: Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 Mar 1 05:25:07 i-14100000241979 kernel: Call Trace: Mar 1 05:25:07 i-14100000241979 kernel: dump_stack+0x5c/0x80 Mar 1 05:25:07 i-14100000241979 kernel: dump_header+0x4a/0x1db Mar 1 05:25:07 i-14100000241979 kernel: oom_kill_process.cold.32+0xb/0x10 Mar 1 05:25:07 i-14100000241979 kernel: out_of_memory+0x1ab/0x4a0 Mar 1 05:25:07 i-14100000241979 kernel: __alloc_pages_slowpath+0xc02/0xd20 Mar 1 05:25:07 i-14100000241979 kernel: __alloc_pages_nodemask+0x283/0x2c0 Mar 1 05:25:07 i-14100000241979 kernel: pagecache_get_page+0xc0/0x2e0 Mar 1 05:25:07 i-14100000241979 kernel: filemap_fault+0x79e/0xa20 Mar 1 05:25:07 i-14100000241979 kernel: ? __mod_memcg_lruvec_state+0x21/0x100 Mar 1 05:25:07 i-14100000241979 kernel: ? page_add_file_rmap+0x12a/0x190 Mar 1 05:25:07 i-14100000241979 kernel: ? alloc_set_pte+0x21c/0x440 Mar 1 05:25:07 i-14100000241979 kernel: ? _cond_resched+0x15/0x30 Mar 1 05:25:07 i-14100000241979 kernel: __xfs_filemap_fault+0x6d/0x200 [xfs] Mar 1 05:25:07 i-14100000241979 kernel: __do_fault+0x36/0xd0 Mar 1 05:25:07 i-14100000241979 kernel: __handle_mm_fault+0x9f9/0xc20 Mar 1 05:25:07 i-14100000241979 kernel: handle_mm_fault+0xc2/0x1d0 Mar 1 05:25:07 i-14100000241979 kernel: __do_page_fault+0x21b/0x4b0 Mar 1 05:25:07 i-14100000241979 kernel: do_page_fault+0x37/0x130 Mar 1 05:25:07 i-14100000241979 kernel: ? page_fault+0x8/0x30 Mar 1 05:25:07 i-14100000241979 kernel: page_fault+0x1e/0x30 Mar 1 05:25:07 i-14100000241979 kernel: RIP: 0033:0x7f847c8fcaf5 Mar 1 05:25:07 i-14100000241979 kernel: Code: Unable to access opcode bytes at RIP 0x7f847c8fcacb. Mar 1 05:25:07 i-14100000241979 kernel: RSP: 002b:00007f843b8ef4e0 EFLAGS: 00010246 Mar 1 05:25:07 i-14100000241979 kernel: RAX: 0000000000000008 RBX: 00007f843b8f04a0 RCX: 0000000000000000 Mar 1 05:25:07 i-14100000241979 kernel: RDX: 00007f843b8f04a0 RSI: 00007f847ca64584 RDI: 00007f84601f3d10 Mar 1 05:25:07 i-14100000241979 kernel: RBP: 00007f843b8ef520 R08: 0000000000000000 R09: 0000000000000002 Mar 1 05:25:07 i-14100000241979 kernel: R10: 0000000000000008 R11: 0000000000000073 R12: 00007f84601f3618 Mar 1 05:25:07 i-14100000241979 kernel: R13: 00007f84601f3648 R14: 0000000000000002 R15: 0000000000000001 Mar 1 05:25:07 i-14100000241979 kernel: Mem-Info: Mar 1 05:25:07 i-14100000241979 kernel: active_anon:3281 inactive_anon:169441 isolated_anon:0#012 active_file:0 inactive_file:3236 isolated_file:6#012 unevictable:0 dirty:0 writeback:0#012 slab_reclaimable:5615 slab_unreclaimable:8149#012 mapped:1404 shmem:10853 pagetables:1951 bounce:0#012 free:10148 free_pcp:0 free_cma:0 Mar 1 05:25:07 i-14100000241979 kernel: Node 0 active_anon:13124kB inactive_anon:677764kB active_file:0kB inactive_file:12944kB unevictable:0kB isolated(anon):0kB isolated(file):24kB mapped:5616kB dirty:0kB writeback:0kB shmem:43412kB shmem_thp: 0kB shmem_pmdmapped: 0kB anon_thp: 421888kB writeback_tmp:0kB all_unreclaimable? no Mar 1 05:25:07 i-14100000241979 kernel: Node 0 DMA free:3656kB min:760kB low:948kB high:1136kB active_anon:0kB inactive_anon:11160kB active_file:0kB inactive_file:196kB unevictable:0kB writepending:0kB present:15992kB managed:15360kB mlocked:0kB kernel_stack:0kB pagetables:136kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB Mar 1 05:25:07 i-14100000241979 kernel: lowmem_reserve[]: 0 726 726 726 726 Mar 1 05:25:07 i-14100000241979 kernel: Node 0 DMA32 free:36936kB min:36940kB low:46172kB high:55404kB active_anon:13124kB inactive_anon:666604kB active_file:0kB inactive_file:12740kB unevictable:0kB writepending:0kB present:1032172kB managed:812960kB mlocked:0kB kernel_stack:2096kB pagetables:7668kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB Mar 1 05:25:07 i-14100000241979 kernel: lowmem_reserve[]: 0 0 0 0 0 Mar 1 05:25:07 i-14100000241979 kernel: Node 0 DMA: 10*4kB (UM) 4*8kB (U) 4*16kB (UM) 10*32kB (U) 4*64kB (UM) 3*128kB (U) 4*256kB (UM) 1*512kB (M) 1*1024kB (U) 0*2048kB 0*4096kB = 3656kB Mar 1 05:25:07 i-14100000241979 kernel: Node 0 DMA32: 906*4kB (UME) 819*8kB (UME) 496*16kB (UME) 165*32kB (UME) 108*64kB (UME) 42*128kB (UME) 3*256kB (M) 1*512kB (M) 0*1024kB 0*2048kB 0*4096kB = 36960kB Mar 1 05:25:07 i-14100000241979 kernel: Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB Mar 1 05:25:07 i-14100000241979 kernel: 14093 total pagecache pages Mar 1 05:25:07 i-14100000241979 kernel: 0 pages in swap cache Mar 1 05:25:07 i-14100000241979 kernel: Swap cache stats: add 0, delete 0, find 0/0 Mar 1 05:25:07 i-14100000241979 kernel: Free swap = 0kB Mar 1 05:25:07 i-14100000241979 kernel: Total swap = 0kB Mar 1 05:25:07 i-14100000241979 kernel: 262041 pages RAM Mar 1 05:25:07 i-14100000241979 kernel: 0 pages HighMem/MovableOnly Mar 1 05:25:07 i-14100000241979 kernel: 54961 pages reserved Mar 1 05:25:07 i-14100000241979 kernel: 0 pages hwpoisoned Mar 1 05:25:07 i-14100000241979 kernel: Tasks state (memory values in pages): Mar 1 05:25:07 i-14100000241979 kernel: [ pid ] uid tgid total_vm rss pgtables_bytes swapents oom_score_adj name Mar 1 05:25:07 i-14100000241979 kernel: [ 608] 0 608 30130 1479 249856 0 0 systemd-journal Mar 1 05:25:07 i-14100000241979 kernel: [ 662] 32 662 16791 195 167936 0 0 rpcbind Mar 1 05:25:07 i-14100000241979 kernel: [ 664] 0 664 35437 208 155648 0 -1000 auditd Mar 1 05:25:07 i-14100000241979 kernel: [ 666] 0 666 12136 90 147456 0 0 sedispatch Mar 1 05:25:07 i-14100000241979 kernel: [ 677] 0 677 31539 700 245760 0 -1000 systemd-udevd Mar 1 05:25:07 i-14100000241979 kernel: [ 701] 0 701 101930 514 446464 0 0 sssd Mar 1 05:25:07 i-14100000241979 kernel: [ 707] 81 707 21260 247 163840 0 -900 dbus-daemon Mar 1 05:25:07 i-14100000241979 kernel: [ 713] 998 713 404526 2373 331776 0 0 polkitd Mar 1 05:25:07 i-14100000241979 kernel: [ 721] 992 721 29974 134 151552 0 0 chronyd Mar 1 05:25:07 i-14100000241979 kernel: [ 729] 991 729 40036 205 208896 0 0 rngd Mar 1 05:25:07 i-14100000241979 kernel: [ 752] 0 752 104632 728 446464 0 0 sssd_be Mar 1 05:25:07 i-14100000241979 kernel: [ 762] 0 762 107533 513 479232 0 0 sssd_nss Mar 1 05:25:07 i-14100000241979 kernel: [ 775] 0 775 25924 576 221184 0 0 systemd-logind Mar 1 05:25:07 i-14100000241979 kernel: [ 885] 0 885 150347 621 380928 0 0 NetworkManager Mar 1 05:25:07 i-14100000241979 kernel: [ 889] 0 889 156590 3313 434176 0 0 tuned Mar 1 05:25:07 i-14100000241979 kernel: [ 895] 0 895 77888 165 180224 0 0 gssproxy Mar 1 05:25:07 i-14100000241979 kernel: [ 942] 0 942 62937 1854 266240 0 0 rsyslogd Mar 1 05:25:07 i-14100000241979 kernel: [ 948] 0 948 61679 217 106496 0 0 crond Mar 1 05:25:07 i-14100000241979 kernel: [ 949] 0 949 56497 29 77824 0 0 agetty Mar 1 05:25:07 i-14100000241979 kernel: [ 950] 0 950 56587 28 69632 0 0 agetty Mar 1 05:25:07 i-14100000241979 kernel: [ 1112] 0 1112 23078 233 196608 0 -1000 sshd Mar 1 05:25:07 i-14100000241979 kernel: [ 4592] 1000 4592 25217 375 233472 0 0 systemd Mar 1 05:25:07 i-14100000241979 kernel: [ 4596] 1000 4596 45558 1197 327680 0 0 (sd-pam) Mar 1 05:25:07 i-14100000241979 kernel: [ 15600] 0 15600 29787 530 221184 0 0 nginx Mar 1 05:25:07 i-14100000241979 kernel: [ 15601] 990 15601 37973 691 278528 0 0 nginx Mar 1 05:25:07 i-14100000241979 kernel: [ 99793] 0 99793 610267 115105 1273856 0 0 java Mar 1 05:25:07 i-14100000241979 kernel: [ 227197] 0 227197 225091 30116 983040 0 0 dnf Mar 1 05:25:07 i-14100000241979 kernel: oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/user.slice/user-1000.slice/session-3.scope,task=java,pid=99793,uid=0 Mar 1 05:25:07 i-14100000241979 kernel: Out of memory: Killed process 99793 (java) total-vm:2441068kB, anon-rss:460420kB, file-rss:0kB, shmem-rss:0kB, UID:0 pgtables:1244kB oom_score_adj:0 Mar 1 05:25:07 i-14100000241979 kernel: oom_reaper: reaped process 99793 (java), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB Mar 1 05:25:07 i-14100000241979 systemd[1]: session-3.scope: Succeeded. Mar 1 05:25:07 i-14100000241979 systemd-logind[775]: Removed session 3. Mar 1 05:25:07 i-14100000241979 systemd[1]: Stopping User Manager for UID 1000... Mar 1 05:25:07 i-14100000241979 systemd[4592]: Stopped target Default. Mar 1 05:25:07 i-14100000241979 systemd[4592]: Stopped target Basic System. Mar 1 05:25:07 i-14100000241979 systemd[4592]: Stopped target Timers. Mar 1 05:25:07 i-14100000241979 systemd[4592]: grub-boot-success.timer: Succeeded. Mar 1 05:25:07 i-14100000241979 systemd[4592]: Stopped Mark boot as successful after the user session has run 2 minutes. Mar 1 05:25:07 i-14100000241979 systemd[4592]: Stopped target Paths. Mar 1 05:25:07 i-14100000241979 systemd[4592]: Stopped target Sockets. Mar 1 05:25:07 i-14100000241979 systemd[4592]: dbus.socket: Succeeded. Mar 1 05:25:07 i-14100000241979 systemd[4592]: Closed D-Bus User Message Bus Socket. Mar 1 05:25:07 i-14100000241979 systemd[4592]: Reached target Shutdown. Mar 1 05:25:07 i-14100000241979 systemd[4592]: Starting Exit the Session... Mar 1 05:25:07 i-14100000241979 systemd[4592]: selinux: avc: received policyload notice (seqno=2) Mar 1 05:25:07 i-14100000241979 systemd[4592]: selinux: avc: received policyload notice (seqno=3) Mar 1 05:25:07 i-14100000241979 systemd[4592]: selinux: avc: received policyload notice (seqno=4) Mar 1 05:25:07 i-14100000241979 systemd[1]: user@1000.service: Succeeded. Mar 1 05:25:07 i-14100000241979 systemd[1]: Stopped User Manager for UID 1000. Mar 1 05:25:07 i-14100000241979 systemd[1]: Stopping /run/user/1000 mount wrapper... Mar 1 05:25:07 i-14100000241979 systemd[1]: Removed slice User Slice of UID 1000. Mar 1 05:25:08 i-14100000241979 systemd[1]: run-user-1000.mount: Succeeded. Mar 1 05:25:08 i-14100000241979 systemd[1]: user-runtime-dir@1000.service: Succeeded. Mar 1 05:25:08 i-14100000241979 systemd[1]: Stopped /run/user/1000 mount wrapper. Mar 1 05:25:16 i-14100000241979 dnf[227197]: CentOS Stream 8 - BaseOS 637 B/s | 3.9 kB 00:06 Mar 1 05:27:42 i-14100000241979 dnf[227197]: CentOS Stream 8 - BaseOS 69 kB/s | 9.8 MB 02:26 Mar 1 05:27:42 i-14100000241979 dnf[227197]: Errors during downloading metadata for repository 'baseos': Mar 1 05:27:42 i-14100000241979 dnf[227197]: - Curl error (28): Timeout was reached for http://mirrors.thzhost.com/centos/8-stream/BaseOS/x86_64/os/repodata/5a08020b627f685de23a8eee3c09a3fb703d539400891e9c4afdd4c0f10c9081-primary.xml.gz [Operation too slow. Less than 1000 bytes/sec transferred the last 30 seconds] Mar 1 05:27:42 i-14100000241979 dnf[227197]: - Curl error (28): Timeout was reached for http://mirrors.thzhost.com/centos/8-stream/BaseOS/x86_64/os/repodata/0b5437ef4340cf4c3bf7c6c821ed2e8a89338cdd941ca8a32b5e1830815f036c-comps-BaseOS.x86_64.xml [Operation too slow. Less than 1000 bytes/sec transferred the last 30 seconds] Mar 1 05:27:42 i-14100000241979 dnf[227197]: - Curl error (28): Timeout was reached for http://mirrors.thzhost.com/centos/8-stream/BaseOS/x86_64/os/repodata/33a0459561869aaf956521d0c4d1812f3af2fd7f65940dd4285a041b7bd8c634-filelists.xml.gz [Operation too slow. Less than 1000 bytes/sec transferred the last 30 seconds] Mar 1 05:27:42 i-14100000241979 dnf[227197]: Error: Failed to download metadata for repo 'baseos': Yum repo downloading error: Downloading error(s): repodata/5a08020b627f685de23a8eee3c09a3fb703d539400891e9c4afdd4c0f10c9081-primary.xml.gz - Download failed: Curl error (28): Timeout was reached for http://mirrors.thzhost.com/centos/8-stream/BaseOS/x86_64/os/repodata/5a08020b627f685de23a8eee3c09a3fb703d539400891e9c4afdd4c0f10c9081-primary.xml.gz [Operation too slow. Less than 1000 bytes/sec transferred the last 30 seconds] Mar 1 05:27:42 i-14100000241979 systemd[1]: dnf-makecache.service: Main process exited, code=exited, status=1/FAILURE Mar 1 05:27:42 i-14100000241979 systemd[1]: dnf-makecache.service: Failed with result 'exit-code'. Mar 1 05:27:42 i-14100000241979 systemd[1]: Failed to start dnf makecache. |
まず、85行目で「Out of memory」が発生しJavaのプロセスがkillされていることがわかります。この上の方を見ていくと、4行目でoom-killerが起動しています。oom-killerはメモリーが足りなくなった時に、自動的にメモリーを多く消費しているプロセスをkillするものです。
49、50行目を読むと、swapがであることがわかります。以下の記事に沿ってswapを設定することにしました。
【AWS】SpringBootアプリが不定期で落ちるので、原因を探ってみた【Linux】
以下でswapのファイルを作ります。今回は1GB分作ります。
1 2 3 4 5 6 7 8 9 10 |
# dd if=/dev/zero of=/var/swap bs=1M count=1024 1024+0 records in 1024+0 records out 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 9.29488 s, 116 MB/s # # # mkswap /var/swap mkswap: /var/swap: insecure permissions 0644, 0600 suggested. Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes) no label, UUID=9a5e31c8-4ece-48ae-8b89-94cb149c800f |
パーミッションを変えたほうがいいというメッセージが出たので変えます。
1 |
# chmod 600 /var/swap |
スワップファイルを有効にします。
1 |
# swapon /var/swap |
確認します。これはswapを有効にする前にも見ておくべきでした。
1 2 3 4 5 |
# free -ht total used free shared buff/cache available Mem: 808Mi 369Mi 68Mi 42Mi 370Mi 280Mi Swap: 1.0Gi 0.0Ki 1.0Gi Total: 1.8Gi 370Mi 1.1Gi |
これでしばらく同じことが発生しないか様子をみます。
ただ、この対処策はディスクから1GB分をswapとして確保しておくすることになるで、保存できるデータが1GB分少なくなることを意味します。
ちなみに、messagesの問題発生部分をよく読むと、dnfが自動で起動した時に発生していることがわかります。なので、以下の記事のようにdnfの自動起動自体を停止するという解決策も考えられます。
systemdのtimerでdnfのアップデート確認が自動で行われていた
とはいえ、この解決策は、OSやモジュールなどを自動でアップデートしてくれる機能を止めることになるので、定期的に手動でのアップデートが必要になるということです。手動で実行する際も、swapが足りなくなる可能性もあるので、やはりswapを設定する解決策の方が本質的かもしれません。
Anti Captchaのワーカーが足りなくてエラーが発生
久しぶりにSERPOSCOPEを開いてみると、以下のように少し前にエラーが発生していて一括処理が落ちていました。
落ちている日が1日だけで、それ以降は正常に完了しているのが不思議でした。
ログを確認してみると以下のようになっていました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
[2022-03-30 04:13:50,408] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - GET https://www.google.com/search?q=#OBF#search-458#&gl=jp&num=100 via proxy:direct try 3 [2022-03-30 04:13:50,915] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT status=[302] exception=[none] [2022-03-30 04:13:51,344] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT[refetch] status=[302] exception=[none] [2022-03-30 04:13:51,344] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - captcha form detected via proxy:direct [2022-03-30 04:13:51,381] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - trying with captcha recaptcha [2022-03-30 04:13:51,382] [google-0] INFO c.s.s.s.c.s.RandomCaptchaSolver - trying anticaptcha [2022-03-30 04:13:57,015] [google-0] DEBUG c.s.s.s.c.s.AntiCaptchaSolver - server is overloaded "{"errorId":2,"errorCode":"ERROR_NO_SLOT_AVAILABLE","errorDescription":"No idle workers are available at the moment. Please try a bit later or increase your maximum bid in menu Settings - API Setup in Anti-Captcha Customers Area."}", sleeping 5000 ms [2022-03-30 04:14:06,187] [google-0] DEBUG c.s.s.s.c.s.AntiCaptchaSolver - server is overloaded "{"errorId":2,"errorCode":"ERROR_NO_SLOT_AVAILABLE","errorDescription":"No idle workers are available at the moment. Please try a bit later or increase your maximum bid in menu Settings - API Setup in Anti-Captcha Customers Area."}", sleeping 10000 ms [2022-03-30 04:14:21,430] [google-0] DEBUG c.s.s.s.c.s.AntiCaptchaSolver - server is overloaded "{"errorId":2,"errorCode":"ERROR_NO_SLOT_AVAILABLE","errorDescription":"No idle workers are available at the moment. Please try a bit later or increase your maximum bid in menu Settings - API Setup in Anti-Captcha Customers Area."}", sleeping 15000 ms [2022-03-30 04:14:36,432] [google-0] DEBUG c.s.s.s.c.s.AntiCaptchaSolver - server is overloaded "null", sleeping 20000 ms [2022-03-30 04:14:59,297] [google-0] DEBUG c.s.s.s.c.s.AntiCaptchaSolver - server is overloaded "{"errorId":2,"errorCode":"ERROR_NO_SLOT_AVAILABLE","errorDescription":"No idle workers are available at the moment. Please try a bit later or increase your maximum bid in menu Settings - API Setup in Anti-Captcha Customers Area."}", sleeping 25000 ms [2022-03-30 04:15:24,298] [google-0] INFO c.s.s.s.c.s.RandomCaptchaSolver - anticaptcha failed with NETWORK_ERROR [2022-03-30 04:15:24,299] [google-0] INFO c.s.s.s.c.s.RandomCaptchaSolver - all captcha solver failed [2022-03-30 04:15:24,299] [google-0] ERROR c.s.s.s.g.s.GoogleScraper - solver can't resolve captcha error = NETWORK_ERROR [2022-03-30 04:15:24,300] [google-0] WARN c.s.s.t.g.GoogleTaskRunnable - scrap failed for #OBF#search-458# because of ERROR_CAPTCHA_INCORRECT [2022-03-30 04:15:24,301] [google-0] WARN c.s.s.t.g.GoogleTaskRunnable - no more proxy, stopping the thread [2022-03-30 04:15:24,302] [google-0] INFO c.s.s.t.g.GoogleTaskRunnable - google thread stopped [2022-03-30 04:15:24,309] [Thread-65] WARN c.s.s.t.g.GoogleTask - 1 proxies failed during the task [2022-03-30 04:15:24,309] [Thread-65] WARN c.s.s.t.g.GoogleTask - 943 searches have not been checked [2022-03-30 04:15:24,309] [Thread-65] INFO c.s.s.t.AbstractTask - task done for module GOOGLE [2022-03-30 04:15:24,310] [pool-2-thread-1] INFO s.s.CronService - history pruning : 0 runs deleted [2022-03-30 07:32:08,305] [pool-1-thread-1] INFO s.s.Scheduler - last version 2.15.0 | current version 2.15.0 [2022-03-30 08:43:03,903] [qtp99347477-18902] WARN o.e.j.h.HttpParser - Illegal character 0x16 in state=START for buffer HeapByteBuffer@5775aeb2[p=1,l=243,c=16384,r=242]={\x16<<<\x03\x01\x00\xEe\x01\x00\x00\xEa\x03\x03I\x06\xB2\xF9\xBc\x99i...\xDf\x85\xDa\xC6@\xA8\xB9\xC2+33\xD4:\xB6H>>>7pnejOQ8oOL0xX4-w...\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00} [2022-03-30 08:43:03,905] [qtp99347477-18902] WARN o.e.j.h.HttpParser - badMessage: 400 Illegal character 0x16 for HttpChannelOverHttp@24023f4e{r=0,c=false,a=IDLE,uri=-} [2022-03-30 08:43:18,104] [qtp99347477-18903] WARN o.e.j.h.HttpParser - Illegal character 0x16 in state=START for buffer HeapByteBuffer@11b25fbd[p=1,l=243,c=16384,r=242]={\x16<<<\x03\x01\x00\xEe\x01\x00\x00\xEa\x03\x03I\x06\xB2\xF9\xBc\x99i...\xDf\x85\xDa\xC6@\xA8\xB9\xC2+33\xD4:\xB6H>>>AGvVLzAF5mGYP8p2C...\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00} [2022-03-30 08:43:18,105] [qtp99347477-18903] WARN o.e.j.h.HttpParser - badMessage: 400 Illegal character 0x16 for HttpChannelOverHttp@158dd953{r=0,c=false,a=IDLE,uri=-} |
これは繰り返されたエラーの最後の部分です。1行目から14行目までの部分が繰り返され、それ以降は最後の一回にのみ登場し、処理全てが止まってしまっていました。
7行目から複数回表示されるエラーコードにはERROR_NO_SLOT_AVAILABLEとあります。エラーの詳細メッセージでは、
No idle workers are available at the moment. Please try a bit later or increase your maximum bid in menu Settings - API Setup in Anti-Captcha Customers Area.
とあります。
これらのメッセージをもとにGoogleで検索すると、以下のFAQページを見つけました。
このページの「Why do I need a "maximum bid"? Why am I receiving a "no idle workers available" error? Where do I set my bid?」という質問に知りたい事が書いてありました。
簡単に言うと、Anti Captchのワーカーが足りていないということです。ワーカーは世界中にいる実際の人間なので、足りていない時間帯もありますし、タスクの量が多くなり過ぎる時間帯もあるでしょう。足りている時間はデフォルトの料金で処理してくれるのですが、足りていない時は、「maximum bid」という設定値を高くしている人のタスクのみ処理するそうです。私はこの値を設定した記憶がないので、おそらくデフォルト値ですが、5ドルになっていました。
たまたまエラーが起きた日はタスクの量に対してWorkerが足りていなかったのでしょう。それ以降の日は足りていたのでエラーは起きていなかったということです。
対策としては、他のユーザーよりも高いと思われる値をmaximum bidに設定するという手段があります。あと、Anti Captch以外のcaptchaサービスも併せて設定することも考えられます。Anti Captchがダメな場合は、自動的に他のcaptchaサービスを使ってくれます。
とはいえ、今回の理由で処理が落ちた日はかなりレアなので、私の場合は特に何も対処しません。別に何十日に一日くらいチェックできなくても何の問題もないからです。
スポンサーリンク
またGoogleの仕様変更でエラー発生
私のSERPOSCOPEは2022年の6月くらいから動かなくなりました。以下の8行目にあるERROR_CAPTCHA_INCORRECTというエラーが発生したためでです。
1 2 3 4 5 6 7 8 |
[2022-06-03 12:39:02,842] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - GET https://www.google.com/search?q=xxxxxx&gl=fr&num=100 via proxy:direct try 3 [2022-06-03 12:39:03,324] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT status=[302] exception=[none] [2022-06-03 12:39:03,704] [google-0] INFO c.s.s.s.g.s.GoogleScraper - GOT[refetch] status=[302] exception=[none] [2022-06-03 12:39:03,704] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - captcha form detected via proxy:direct [2022-06-03 12:39:03,734] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - trying with captcha recaptcha [2022-06-03 12:39:03,734] [google-0] INFO c.s.s.s.c.s.RandomCaptchaSolver - trying anticaptcha [2022-06-03 12:40:08,338] [google-0] DEBUG c.s.s.s.g.s.GoogleScraper - got captcha response xxxxxxxxxxxx in 64 seconds from anticaptcha [2022-06-03 12:40:09,103] [google-0] WARN c.s.s.t.g.GoogleTaskRunnable - scrap failed for xxxxxx because of ERROR_CAPTCHA_INCORRECT |
これは公式のGithubリポジトリのissueでも取り上げられています。
これを読んでいて分かったのが、やはりGoogleの仕様変更があったということです。このページからリンクされている以下の記事によると
Update on Google Search reCAPTCHA V2
Googleへのクエリで num=xx というのをつけられなくなったということです。つけると、reCAPTCHA V2の認証に飛ばされてしまうということです。先ほどのエラーログの1行目を見て頂くと、 num=100 というのがついています。これは100件の検索結果を持って来い!って意味なんですが、よく考えたら、100件の検索結果を求めるのはボットとかプログラムであって、人間ではないですよね。なので規制して当然と言えば当然です。
これに対処するためにいくつか対処法が先ほどのissueで提示されていました。numを10にすれば num=xxつかなくなるとのことなのでそうしました。しかし、10にするとこれまでと同じ100件の検索結果を得るために10倍の回数クエリを発行するということになります。そうすると、チェック時間もかかるだろうし、Anti Captchaの費用も多くなってしまいます。よく考えると100件の検索結果なんて必要なくて、30件くらいでもいいかなと思いました。単純にAnti Capthcaの費用が3倍になるだけなら全く負担にはなりません。なので、設定は以下のようにしました。
案の定、ERROR_CAPTCHA_INCORRECTで落ちることはなくなりました。しかし、やはりAnti Captchaは3倍では済まない程に消費しており、最初に入金して数ヶ月使っても全然減らなかった約5ドルを数日で使い切ってしまい、reCAPTCHA V2が通らないエラーが発生してしまいました。リクエスト回数が3倍になっただけなのでAnti Captchaの3倍で済むかと思ったのですが、なぜか数十倍のスピードで消費しました。やはりGoogleの仕様変更でreCAPTCHA V2に飛ばされる頻度自体が激増しているのかもしれません。
ここでまた先程のissueを眺めていたら衝撃的なコメントを発見してしまいました
noguespi commented on Jun 11, 2022
For your information, as specified since january 2020 serposcope is no more maintenained and I encourage you to move to another solution.
SERPOSCOPEの管理者曰く、SERPOSCOPEはもうメンテナンスしないので、他のツールに移行してくれ、とのことです。しかも2020年から宣言されていたそうです。
まじか、全然気が付かなかった。 SERPOSCOPEを私が使い始めたのは2020年以降です。公式サイトの目立つところに書いてはいないので、なかなか気付けません。少し不親切ですね。
なので、素直に他のツールを探すことにしました。色々と検討した結果、WineというツールでGRCをMacでも動かせることがわかったので、その方法を採用することにしました。次の記事に詳しく説明します。
ちなみに、しばらくすると公式リポジトリのissueで次期バージョンの3についての計画を知りました。もしかしたら、いつかこの問題は解消するかもしれません。
まとめ
SERPOSCOPEの良い点、悪い点についてまとめておきます。
- ソフトウェアは無料なのでサーバ代だけで運用できる
- サーバで運用できるのでPCをいちいち開かなくていい
- WEBアクセスできるのでチームでリモートで管理できる
- 同じキーワードで複数サイトチェックする場合は一度の処理で済む
- Googleのブラックリストに入れられてもVPSを作り直せばすぐに使える
- Googleの仕様変更にも開発側が数日で対応してくれる
- スマホから手軽に確認できる
- YahooやBingには対応していない
- 設定はターミナル作業(黒い画面)が必要になってしまう
- キーワード一括登録時に他の項目もカンマ区切りで入力する必要がある
- 時々エラーが発生する
- エラーで落ちてもメールで通知してくれない
- 人のURLも保存するのでデータ量が多くなりそう
- 自動チェクの頻度は変えられず、毎日が必須。
さいごに
こんな感じで紆余曲折ありましたが、なんとかSERPOSCOPEを使えるようになりました。 GRCとようやくおさらばできます。
さて、検索順位をチェックするのも大事ですが、上位表示するためにのライティングのコツがあります。私が考えたテクニックは自分の「感情」をうまく使うというものです。以下で説明していますので、参考にしてみてください。