【WordPress】プラグインなしでスパムコメントのフィルタと一括削除をする

ブログ運営

こんにちは。

コメントを放置して大量にスパムコメントが溜まったり、スパム対策の方法が分からなかったりして困っている方が結構いるのではないでしょうか。
私もその一人だったので、対処の面倒臭さはよく分かります。

そこで今回は、プラグインなしで、スパムコメントを一括削除したうえで今後スパムコメントが溜まらないようにフィルタをかける方法を紹介します。

スパムコメントの一括削除

結論

コメントが保存されているデータベースの中で、スパムに該当するデータに対してスパムフラグを付与します。

私の場合は、MySQLに対して以下のクエリを実行しました。

update `wp_comments` set comment_approved = 'spam' where comment_content is null or comment_content not regexp binary '[ぁ-ん]' or comment_content regexp binary '[A-Z a-z Ѐ-ӿ ؀-ۿ ก-๛ À-ÿ Ạ-Ữ :/,\'\.\s]{32,}' or comment_content regexp binary '^.{0,3}[A-Z a-z Ѐ-ӿ ؀-ۿ ก-๛ À-ÿ Ạ-Ữ :/,\'\.\s]+.{0,3}$' or comment_content regexp binary '' or comment_content regexp binary 'ttps?:' or comment_content regexp binary 'a href='

詳細な手順は以下で説明します。

手順

まず、自分の使っているデータベースに接続します。

外部 (例えば自分のPC) からデータベースに接続する方法もありますが、デフォルトでデータベースが外部接続を拒否する設定になっている可能性があるため、直接接続する方が簡単かもしれません。

私はphpMyAdminから接続しました。

データベース接続に必要な情報 (データベース名、ユーザ名、パスワード、ホスト名) は wp-config.php に記載されているので、接続する前に確認しておきましょう。

wp-config.php の場所は人によって異なると思いますが、私の場合は /サイト名/public_html/wp-config.php にありました。

接続したら、実際にクエリを実行します。

処理の説明

クエリを再掲します。

update `wp_comments` set comment_approved = 'spam' where comment_content is null or comment_content not regexp binary '[ぁ-ん]' or comment_content regexp binary '[A-Z a-z Ѐ-ӿ ؀-ۿ ก-๛ À-ÿ Ạ-Ữ :/,\'\.\s]{32,}' or comment_content regexp binary '^.{0,3}[A-Z a-z Ѐ-ӿ ؀-ۿ ก-๛ À-ÿ Ạ-Ữ :/,\'\.\s]+.{0,3}$' or comment_content regexp binary '' or comment_content regexp binary 'ttps?:' or comment_content regexp binary 'a href='

wp_comments はテーブル名、comment_content は実際のコメント、comment_approved はコメントの承認状況を表すフラグ (デフォルト値は1) です。

このクエリでは、以下のいずれかの条件を満たす行に対して、スパムフラグを付与しています。

  • コメントが空である
  • URLまたはリンクが含まれる
  • ひらがなが含まれない
  • 以下の言語の文字が32文字以上または先頭と末尾3文字を除いてすべてに該当する
    • 英語 (アルファベット)
    • ロシア語 (キリル文字)
    • ペルシア語 (アラビア文字)
    • タイ語
    • トルコ語
    • ベトナム語
    • 一部記号、空白

スパムフラグを付与すると、ページ内のコメント欄にフラグ付与されたコメントが表示されなくなります。

もし心配であれば、実行前に以下のコマンドでスパムフラグが付与されないコメントを確認することができます。
以下のクエリは先程の条件の否定を選択しています。

select * from `wp_comments` where comment_content is not null and comment_content regexp binary '[ぁ-ん]' and comment_content not regexp binary '[A-Z a-z Ѐ-ӿ ؀-ۿ ก-๛ À-ÿ Ạ-Ữ :/,\'\.\s]{32,}' and comment_content not regexp binary '^.{0,3}[A-Z a-z Ѐ-ӿ ؀-ۿ ก-๛ À-ÿ Ạ-Ữ :/,\'\.\s]+.{0,3}$' and comment_content not regexp binary '' and comment_content not regexp binary 'ttps?:' and comment_content not regexp binary 'a href='

しかし、本手順ではスパムフラグを付与しているだけで実際にコメントデータを削除しているわけではないので、神経質にならなくても大丈夫です。簡単に復元可能です。

因みに、上記クエリは中国語や韓国語などの対応していない言語が多々あるため、気になる場合はSQL文をカスタマイズして使ってください。

本当はひらがなを含まないという条件だけで絞り込むつもりでしたが、なぜかうまくいかなかったので、上記のように言語ごとに弾くようにしました。
おそらくUTF-8の文字コードと可変長文字の問題かと思われます。データベースによってはうまくいくのかもしれませんが、少なくともMySQLでは正しく検索できないようです。

もっとスマートな絞り込み方法が分かる方はコメント欄等で共有していただけると嬉しいです。

スパムコメントのフィルタ

結論

functions.php で、スパムに該当するコメントに対してスパムフラグを付与します。

私の場合は、以下のコードを functions.php に追記しました。

function filter_spam_comment($approved, $commentdata) {
  $comment_content = $commentdata['comment_content'];

  if ((! preg_match("/[ぁ-んァ-ヴー]+/u", $comment_content)) || preg_match("/[A-Z a-z Ѐ-ӿ ؀-ۿ ก-๛ À-ÿ Ạ-Ữ 가-힣 :/,\'\.\s]{64,}/u", $comment_content) || preg_match("/^.{0,3}[A-Z a-z Ѐ-ӿ ؀-ۿ ก-๛ À-ÿ Ạ-Ữ 가-힣 :/,\'\.\s]+.{0,3}$/u", $comment_content) || preg_match("/ttps?:/u", $comment_content) || preg_match("/a href=/u", $comment_content)) {
    $approved = 'spam';
  }
  return $approved;
}
add_filter('pre_comment_approved', 'filter_spam_comment', 10, 2);

手順

WordPressのダッシュボードで「外観 > テーマファイルエディター」と進み、ファイルの中から functions.php を選択します。

こうすることで、functions.php ファイルを簡単に編集することができます。

もちろん、他の方法で編集しても構いません。

追記したらファイルを更新(保存)し、エラーが発生しないことを確かめてください。

また、念のためファイル変更前にバックアップを取っておくと良いでしょう。

処理の説明

追記内容を再掲します。

function filter_spam_comment($approved, $commentdata) {
  $comment_content = $commentdata['comment_content'];

  if ((! preg_match("/[ぁ-んァ-ヴー]+/u", $comment_content)) || preg_match("/[A-Z a-z Ѐ-ӿ ؀-ۿ ก-๛ À-ÿ Ạ-Ữ 가-힣 :/,\'\.\s]{64,}/u", $comment_content) || preg_match("/^.{0,3}[A-Z a-z Ѐ-ӿ ؀-ۿ ก-๛ À-ÿ Ạ-Ữ 가-힣 :/,\'\.\s]+.{0,3}$/u", $comment_content) || preg_match("/ttps?:/u", $comment_content) || preg_match("/a href=/u", $comment_content)) {
    $approved = 'spam';
  }
  return $approved;
}
add_filter('pre_comment_approved', 'filter_spam_comment', 10, 2);

このコードでは、pre_comment_approved という関数をフィルタフックしています。

フックすると、$approved, $commentdata が引数として渡されます。
$approved は comment_approved に書き込まれるフラグ、$commentdata はコメント文や著者などコメントに関する情報を持つ配列です。

そのため、$commentdata から comment_content (コメント文) を取得してスパムかどうか判定し、スパムなら $approved をスパムフラグに書き換えて、$approved を返します。

スパムの判定は、一括削除の際の判定とまったく同じです。

add_filter の第3引数には実行優先度(デフォルト値は10)、第4引数には関数に渡す引数の数(デフォルト値は1)を指定しています。

今回は引数を2つ受け取っているので、第4引数を指定しないと以下のようなエラーが発生するため、必須です。

Fatal error: Uncaught ArgumentCountError: Too few arguments to function ...

この処理により、データベースにコメントの情報が書き込まれる前にスパムフラグを付与することができます。

さらに、スパムに該当するコメントが投稿された場合にはメール通知が発生しないようになります。

pre_comment_approved の詳細は pre_comment_approved | Hook をご確認ください。

最後に

この記事では、WordPressでのスパムコメントの対策方法を紹介しました。

プラグインなしで手軽に対策できるので、是非試してみてください。

それでは、また。

ブログ運営技術系

コメント一覧

タイトルとURLをコピーしました