Certbot で新ドメインに Let's Encrypt SSL を適用

サーバー上で使っている複数のドメインの内、一部に対して Let's Encrypt が適用されていなかったので、追加適用しました。

Ubuntu 20.04 で Web サーバーとして Nginx を使っています。

すでに Certbot はインストール済みです。

自動更新タイマーの確認

「sudo systemctl status certbot.timer」を実行して、Certbot の自動更新のタイマーが動いているか確認します。

$ sudo systemctl status certbot.timer
[sudo] password for ユーザー名: 
● certbot.timer - Run certbot twice daily
     Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Wed 2022-05-18 22:15:43 JST; 5 months 2 days ago
    Trigger: Fri 2022-10-21 07:14:04 JST; 9h left
   Triggers: ● certbot.service

「Active: active (waiting) since Wed 2022-05-18 22:15:43 JST; 5 months 2 days ago」となっている通り、タイマー自体は動いています。

新ドメインへの Let's Encrypt 適用

「$ sudo certbot」を実行します。

$ sudo certbot
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: www.graffuhs.com
2: example.com
3: sub1.example.com
4: sub2.example.com
5: sub3.example.com
6: www.example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 

どのドメインに対して HTTPS を有効にするか聞かれます。

今回は「sub3.example.com」に適用したいので「5」と入力しました。

Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 5
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for sub3.example.com
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/example.com

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

Web サーバーの設定に対して HTTP → HTTPS へのリダイレクトを行うか聞かれますが、実は設定ファイル上ではすでにリダイレクト設定はしておいたので、今回は「1」(リダイレクトなし)とします。

Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 1
Future versions of Certbot will automatically configure the webserver so that all requests redirect to secure HTTPS access. You can control this behavior and disable this warning with the --redirect and --no-redirect flags.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://sub3.example.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=sub3.example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

特にエラーもなく、これで完了です。ブラウザで確認してみても鍵マークがついていますね。

ちなみに

もう特にする事はないですが、上記メッセージの最後の行にサイトをテストできる URL が貼ってあったので飛んでみました。

こんな感じです。

それから、証明書と chain(?)、そして鍵ファイルの場所が書いてありました。直接アクセスはできませんでしたが、システム上こんな感じで管理されている様です。

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/sub3.example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/sub3.example.com/privkey.pem
   Your cert will expire on 2023-01-18. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

取り急ぎ Django でログイン機能を作った方法(クラスベースビュー)

とりあえず Django のクラスベースビューでログイン機能を追加した時の内容をまとめます。

  1. views.py で LoginRequiredMixin の継承
  2. forms.py でログインフォームを作成
  3. views.py で ログインビューの作成
  4. urls.py でパスと view の紐付け
  5. ログイン用テンプレートの作成
  6. ログインの動きのまとめ
  7. ログアウトページの作成

views.py で LoginRequiredMixin の継承

非ログインユーザーに表示させたくない View 全てで LoginRequiredMixin を継承します。

複数のクラスを継承している場合、下記の例の様に必ず一番目に記述します。

# views.py
class ClassList(LoginRequiredMixin, generic.ListView):
    model = ClassMaster
    template_name = 'class_list.html'

class ClubList(LoginRequiredMixin, generic.ListView):
    model = ClubMaster
    template_name = 'club_list.html'

非ログインユーザーが LoginRequiredMixin を継承したビューに当たった場合、デフォルトで accounts/login/ にリダイレクトされますが、下記の様に settings.py に明示的に LOGIN_URL としてリダイレクト先を設定することも可能です。

# settings.py
LOGIN_URL = 'http://ドメイン名/login' # 一例です。

上記いずれかのパスでログインビューを表示する様、後ほど設定します。

また、リダイレクトされる際、元々アクセスしようとしていたパスを next パラメータとして URL に保持した状態で飛んでいきます。これも後ほどログイン後のリダイレクトに利用します。

forms.py でログインフォームを作成

AuthenticationForm クラスを継承してフォームを作成します。とりあえず username と password のみ認証対象とします。

# forms.py

from django.contrib.auth.models import User
from django.contrib.auth.forms import AuthenticationForm

class LoginForm(AuthenticationForm):
    class Meta:
        model = User
        fields = ['username', 'password']

views.py で ログインビューの作成

ログイン用のビューは LoginView クラスを継承して作成します。

ログインフォームの表示と、ユーザーから submit されたログイン情報の認証、そしてユーザーが元々アクセスしようとしていたページへのリダイレクト等を担ってくれます。

# views.py

from django.contrib.auth.views import LoginView

class MyLoginView(LoginView):
    form_class = LoginForm

template_name を指定しなくてもデフォルトで registration/login.html になっているので上記の例では明記していませんが、他の view 同様 「template_name = 'login.html'」の様に設定することも可能です。

また、LoginView クラスは POST 時に next URL を渡すとログイン後その URL にリダイレクトしてくれます

"If called via POST with user submitted credentials, it tries to log the user in. If login is successful, the view redirects to the URL specified in next. If next isn’t provided, it redirects to settings.LOGIN_REDIRECT_URL (which defaults to /accounts/profile/). If login isn’t successful, it redisplays the login form."

後ほどテンプレートを作成する際に form からの POST 時に next 渡す様設定します。

urls.py でパスと view の紐付け

アプリケーションレベルの urls.py にログインページのパスとログイン用 view の紐付けを記載します。

# urls.py

from django.urls import path
from . import views

app_name = 'sample_app'
urlpatterns = [
    #〜省略〜
    path('accounts/login/', views.MyLoginView.as_view(), name="login"),
    #〜省略〜
]

ログイン用テンプレートの作成

作成したログインフォームを表示するテンプレートを作ります。

Form 部分の記述は下記の様な感じ。

<!--login.html-->
 
<form action="{% url 'sample_app:login' %}" method="post">
    {% csrf_token %}
        {{ form.as_p }}
        <p><input type="hidden" name="next" value="{{next}}"></p>
        <p><input type="submit" value="ログイン"></p>
    </form>

いくつかポイントがあります。

  • ログインフォーム自身に対して POST する。
  • input の一つとして、リダイレクトされた時に持ってきた next URL を裏で取っておく(type="hidden" で非表示にしています)。

こうしておくことで、ログイン成功時に LoginView がリダイレクトしてくれます。

ログインの動きのまとめ

というわけで、ログイン部分を一通り作りました。

非ログインユーザーがアクセスした場合、下記の様な流れになります。

  1. 非ログインユーザーがページへアクセスしようとする。
  2. LoginRequiredMixin によって、アクセスしようとしていたページのパスを next に保持したままログインページ(LoginView)へリダイレクトされる。
  3. リダイレクト先でのログインフォームでユーザー名とパスワードを Submit する際、next も一緒に LoginView に対して POST する。
  4. 認証に問題がなければ、ログインされ、next のパスにリダイレクトされる。

ログアウトページの作成

一応ログアウト部分もやっつけで書いておきます。

サイトのヘッダー部分など、どこかしらにログアウト用リンクを作って、ログアウトビューとつなげる感じです。

views.py

LogoutView クラスを継承したビューを作成し、任意の template_name を指定します。

# views.py

class MyLogoutView(LogoutView):
    template_name = 'テンプレート名.html'

urls.py

ログアウト用のパスとログアウト用の view を繋げるだけです。

# urls.py

from django.urls import path
from . import views

app_name = 'sample_app'
urlpatterns = [
    #〜省略〜
    path('accounts/login/', views.MyLoginView.as_view(), name="login"),
    path('accounts/logout/', views.MyLogoutView.as_view(), name="logout"),
    #〜省略〜
]

テンプレート

テンプレートでは、任意の場所にハイパーリンクを置いてログアウト用 URL に飛ぶ様にすれば大丈夫です。

【レンタルサーバーより断然優位】Python 実行のおすすめ VPS 5 選

使える技術と使えない技術

レンタルサーバー(共用サーバー)は安いし、Python の勉強だったりサービスの公開にも使えるなと思っているそこのあなた。ちょっと待ってください。

実はレンタルサーバーの Python には純粋な Python とは違う様々なクセがあるのをご存知でしたか?

ものによって SSH 接続できない仮想環境が使えないデータベースが操作できない等、まともに実行できないことも多々あります。

なぜエラーが出るんだろう

私自身、元々使っていたさくらのレンタルサーバーでの Python 実行を散々試行錯誤した結果、さくらの VPS を借りることにしました。

その経験を踏まえても、Python を動かすにはレンタルサーバーではなく VPS をおすすめします。

こちらの記事ではその理由とおすすめの VPS をあわせて紹介しますので、ぜひ参考にしてみてください。

また、一般的に「レンタルサーバー」というと「共用サーバー」のことを指す事が多いので、こちらの記事でも「共用サーバー」の意味で「レンタルサーバー」を使用します。

レンタルサーバー x Python のリスク

結論から言うと、レンタルサーバーで Python プログラミングを行うのは一部を除いて難易度が無駄に高いです。

その理由はレンタルサーバーならではの権限の制限。Python 開発に必要な環境が作れない事がしばしばあります。

そしてそれを解決する術がない場合も多いのです。

1. 公式サイトと現実の違い

公式サイトで共用サーバーの仕様欄を見ると、大抵 Python3 と MySQL データベースの記載があるため一見問題なさそうです。

ただ、実際に使ってみるとさまざまな制限がかかっているのが共用サーバーです。

ざっくりいうと、物によって下記の様な事象があります。(他にもあるかも)

  • SSH 接続ができない → Python すら触れない
  • 仮想環境が使えない → 複数のアプリを作るのに向いていない
  • Python でデータベースが使えない → スクレイピング等に向いていない
Python が普通に使えるわけではありません

私が少し触って確認できたものだけでこんな感じなので、もっとプログラミングを進めていくと他にもいろいろ出てくる気はします。

詳しくは下記の記事も読んでみてください。

▶︎【7社比較】レンタルサーバーの大クセ Python は本当は使いづらい?

2. 環境構築からエラー頻発

プログラミングで物を作っていこうとすると様々なエラーが発生します。

これは普通のことで、都度調べて修正していくのがプログラミングです。

ただ、ここまで読んでいただいてわかる通り、レンタルサーバーでは環境構築の時点でエラーが発生しまくります。

環境構築というのは「Python を使える様にする」、「データベースを使える様にする」、などいわば準備段階です。レンタルサーバーではこの準備段階でつまづくため肝心のプログラミングに辿り着く前に心を折られます

3. レンタルサーバー x Python のエラーは情報が無い

そういった「レンタルサーバーならではのエラー」を調べても情報はほとんどなく、たとえ英語で調べても日本のレンタルサーバーに関連する情報は見つかりません。

そして散々時間をかけて調べた挙句「そもそも権限がないのでどうしようもない」という事が多々あります。

それも環境構築の段階でです。

レンタルサーバー特有のエラー

同じ労力を払うならVPSの方が有意義

ここまでレンタルサーバーの Python 環境構築がいかに難しいか説明してきましたが、その点 VPS は制限がほとんどないので逆にスムーズです。

VPSはハードルが高い様に思うかもしれませんが、Pythonを使う、データベースを使う、などに関してはレンタルサーバーよりもシンプルなケースが多いです。

また、Python プログラミングに関する既存の情報量は、レンタルサーバーと比べて VPS の方が圧倒的に多いです。

使えない技術 vs 使える技術

レンタルサーバーも VPS も、一筋縄では行かない事が多いです。

どうせ時間をかけるなら、レンタルサーバーでそもそも存在するかも分からない解決法を探るよりも、VPSで Linux 系サーバーの操作Python のプログラミング など、実践的な事を学んでいく方がコスパが良いと思いませんか?

使える技術と使えない技術

もし「将来的に業務でも使える様になれば」と考えているなら余計に VPS の方が良いです。業務の Python 実行環境にレンタルサーバーを使う会社は流石にないはずです。

そもそも VPS も月々 700 円〜900 円程度ですしね。

VPS はレンタルサーバーと比べて圧倒的に自由度が高く、「どの会社の VPS か」よりも「どの OS か」の方が重要だったりします。

詳しくはこちらの記事を参照いただければと思いますが、OS は既存情報の多い Ubuntu、Debian、CentOS がおすすめです。

後々エラーなどに出くわした際にも参考になる情報が多く便利です。

というわけでそろそろ「どの VPS がおすすめなのか」を説明します。

OS のインストールが簡単な VPS がおすすめ

実は、メジャーな VPS は大体 Ubuntu、Debian、CentOS に対応しています。ではその中で更に絞るには何を基準にしたらいいでしょうか。

ここは「OS インストールの簡単さ」で選びましょう。

実は VPS によっては特定の OS インストールをほぼ自動でやってくれるものがあります。

例えばさくらの VPS であればコントロールパネルで選択した OS を自動でインストールしてくれますし、GMO のクラウド VPS であれば契約時に選択した OS をインストールされた状態でサーバーが用意されます。

さらに ConoHa VPS に関しては Python のウェブ開発フレームワークである Django のセットアップまである程度自動化されています。

こうして選べば、インストールが簡単で問題解決もしやすい環境を整える事が出来ます。

各社の OS 自動インストールの対象は下記の通りです。

自動 OSConoHa VPSさくらの VPSお名前.com VPSGMO クラウド VPSKagoya Cloud VPS
Ubuntu
Debian
CentOS
その他Django テンプレ無料お試し

1. ConoHa VPS

ConoHa VPS
自動インストール対象 OSCentOS 7.1 〜 7.9
CentOS Stream 8
CentOS Stream 9
Ubuntu 18.04
Ubuntu 20.04
Debian 9.13
Debian 10.10
Debian 11.0
自動インストール方法サーバー追加時にテンプレートを選択することでサーバー作成と同時にOSのインストールやアプリケーションサーバーの構築が完了。

公式ページVPS を追加する
おすすめプラン1G(初期費用無料 + 月額 723 円〜)

解説

今回紹介する中で対応 OS の種類が最も豊富なのがこちらの ConoHa VPS。

「VPSをもっと速く、かんたんに」というキャッチコピーだけあって、OS だけでなく Django のテンプレートもあり、簡単にセットアップが可能です。「Django のインストールは自分でやりたい」という方はもちろんそれも可能です。

自動インストール対象の OS の種類も多いですし、下の記事の様に公式が親切に色々な情報を載せているのもポイントです。

3 ステップで簡単に始められるとの事で、公式サイトに「たったの25秒で〜サーバーが作れます。」とありますので試してみてください。笑

公式サイトConoHa VPS

2. さくらの VPS

さくらのVPS
自動インストール対象 OSUbuntu 18.04
Ubuntu 20.04
CentOS 7
CentOS Stream 8
自動インストール方法VPSコントロールパネルからワンクリックで再インストールが可能。

公式ページさくらの VPS 新規追加(コントロールパネル)
おすすめプラン1G(初期費用無料 + 月額 880 円〜)

解説

かなり気軽に使える VPS で、私自身もさくらの VPS を使っています。ポートの開閉をコントロールパネル上のクリックで行えるパケットフィルター機能が地味に楽です。

ユーザーへのサポートをかなり意識していて、公式サイトでも VPS のセットアップの手順を詳しく説明してくれているのもありがたいです。

ネコでもわかる!さくらのVPS講座 ~第二回「サーバーをさわってみよう!」

「Django VPS」で検索すると最も日本語記事が出てくるのは「さくらの VPS」です。

公式サイトさくらのVPS

3. お名前.com VPS

お名前.com VPS
自動インストール対象 OSUbuntu 18.04
Ubuntu 20.04
CentOS 7.5 ~ 7.9
CentOS Stream 8
Debian 9.13
Debian 10.10
自動インストール方法VPSコントロールパネルのサーバーセットアップで OS とバージョンを選択可能。

公式ページサーバーを初期セットアップする
おすすめプラン1G(初期費用無料 + 月額 873 円)

解説

オンラインでのお申込みから最短10分で利用開始できるというお名前.com の VPS。

KVM という仮想化方式を採用していて、ネットワークやディスクI/Oのパフォーマンスを良くする Virtio ドライバにも対応するなどハイパフォーマンスを追求している VPS

OS の初期インストールの方法は下記の公式ページに記載があります。

公式サイトお名前.com VPS

4. クラウドVPS by GMO

GMOクラウドのVPS 詳細はこちら
自動インストール対象 OSCentOS 7.9
CentOS 8.2
Ubuntu 20.04
Debian 10.0
自動インストール方法契約時に選択した OS をインストールした状態でサーバーが用意される。

公式ページ新規サーバー申し込み方法
おすすめプランV1(初期費用無料 + 月額 968 円〜)
お得な情報14 日間無料お試し

解説

コンテナ技術を採用していて、一般的な仮想マシンに比べて軽量で vCPU やメモリなどの負荷が小さく、リソースを効率的に利用できる VPS。どちらかというと法人ユーザーを想定しているようですが、14 日間の無料お試し期間があるのは他と違う点です 。

契約時の OS 選択について下記の公式ページで解説が載っています。

公式サイトGMOクラウドのVPS 詳細はこちら

5. KAGOYA Cloud VPS

カゴヤ・ジャパン
自動インストール対象 OSCentOS 7
CentOS 8
CentOS Stream 8
Ubuntu 18.04
Ubuntu 20.04
自動インストール方法専用コントロールパネルからテンプレートとアプリケーションを選択して環境構築可能。

公式ページインスタンス作成
おすすめプラン1コア/1GB(初期費用無料 + 月額 〜550 円)

解説

コントロールパネルから即座にスペック変更することができます

こちらもコントロールパネルからインスタンスを作成する際に任意の OS を指定することができます。

公式サイトカゴヤ・ジャパン

個人的には ConoHa VPS かさくらの VPS がおすすめ

OS インストールの手軽さを基準に Python のおすすめ VPS を 5 つ紹介しましたが、いかがだったでしょうか?

個人的なおすすめは ConoHa VPSさくらの VPS です。

ConoHa VPS は申し込み時の手軽ささくらの VPS は既に利用している人がかなりいる & 私自身も Django に利用していて全く不満がないからというのが理由です。

大量のデータを取り扱う大規模なアプリケーションを作成するのであれば GMO のクラウド VPSお名前.com の VPS(KVM)もいいかと思いますが、個人 Python プログラムを作っていく場合は前述の 2 つがおすすめです。

XREA のレンタルサーバーにSSHでログインする方法

SSH を有効化する

まず XREA のダッシュボードで SSH を有効化する必要があります。

サイト設定 > ツール/セキュリティーをクリックします。

遷移先の画面で「SSH接続IP許可」をクリックします。

続けて「SSH接続のIPを許可する」をクリックします。

これでまず SSH 接続ができるようになりました。

サーバー、アカウント、パスワードを確認

契約情報の画面を開き、サーバーアカウント情報の欄を参照します。

ここでログインに必要な情報を確認できます。

  • サーバー
  • アカウント
  • パスワード

これらの情報を使って SSH 接続していきます。

ターミナルを起動する

ターミナルを起動し、「ssh アカウント@サーバー」の形式で入力します。

例えば、サーバーが「s123.xrea.com」でアカウントが「abcabc」だった場合、上記画面の情報を元にコマンドは「ssh abcabc@s123.xrea.com」となります。入力して Enter。

% ssh ssh abcabc@s123.xrea.com

初回は下記のようなメッセージが表示され、yes か no を求められますが、yes と入力して Enter で大丈夫です。

The authenticity of host 's123.xrea.com (123.45.6.78)' can't be established. ECDSA key fingerprint is XXXXXX:XxXXXxxXX+XXXXXXXXxxxxxxXXxXxxxxXXxXXXX. Are you sure you want to continue connecting (yes/no/[fingerprint])?

yes そして Enterすると下記のメッセージが表示され、続けてパスワードを求められます。

Warning: Permanently added 's123.xrea.com,123.45.6.78' (ECDSA) to the list of known hosts.

パスワード入力してログイン完了

下記の様にパスワードを求められるので入力します。(タイプしても表示されないので注意)

abcabc@s123.xrea.com's password: 

パスワードを入力して Enter を押下すればログイン完了です。

PHP のバージョンを確認

ログインついでに現在インストールされている PHP のバージョンも確認してみます。コマンド「php --version」を実行してみます。

$ php --version
PHP 7.0.33 (cgi-fcgi) (built: Feb  3 2021 10:55:56)
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
    with the ionCube PHP Loader + ionCube24 v10.3.9, Copyright (c) 2002-2019, by ionCube Ltd.
    with Zend OPcache v7.0.33, Copyright (c) 1999-2017, by Zend Technologies
    with Xdebug v2.9.0, Copyright (c) 2002-2019, by Derick Rethans
$ 

PHP 7.0.33 が入っている様です。

ついでに Python のバージョンを確認

さらについでに現在インストールされている Python のバージョンも確認してみます。コマンド「python --version」と「python3 --version 」をそれぞれ実行してみます。

$ python --version
Python 2.7.5
$ python3 --version
Python 3.6.13

と言うわけで現在は Python 2.7.5 と Python 3.6.13 が入っていますね。

そしてさらについでに下記3行を順に実行すれば Python 仮想環境の作成&起動もできます。

$ python3 -m venv python3-venv
$ source python3-venv/bin/activate
(python3-venv) $ python

ついでに、Python 仮想環境の中で下記を順に実行していけば MySQL のデータベースを取り扱うための MySQLdb モジュールを使うこともできます。

>>> exit()
$ pip install mysqlclient
$ python
>>> import MySQLdb
>>> 

バリューサーバーのレンタルサーバーにSSHでログインする方法

SSH を有効化する

まずバリューサーバーのコントロールパネルで SSH を有効化する必要があります。

左側のメニューでお役立ちツールをクリックします。

そして下に表示されるメニューで「SSH接続」をクリックします。

下記で「SSH登録」をクリックします。

これで SSH を有効化する設定は完了です。数分待ちます。

サーバー、アカウント、パスワードを確認

ダッシュボードのメニューから FTP > FTP設定・アカウント発行をクリックします。

ここでログインに必要な情報を確認できます。

  • FTPサーバー
  • FTPアカウント
  • FTPパスワード

これらの情報を使って SSH 接続していきます。

ターミナルを起動する

ターミナルを起動し、「ssh FTPアカウント@FTPサーバー」の形式で入力します。

例えば、FTPサーバーが「s12.valueserver.jp」でFTPアカウントが「abcabc」だった場合、上記画面の情報を元にコマンドは「ssh abcabc@s12.valueserver.jp」となります。入力して Enter。

% ssh ssh abcabc@s123.xrea.com

初回は下記のようなメッセージが表示され、yes か no を求められますが、yes と入力して Enter で大丈夫です。

The authenticity of host 's12.valueserver.jp (123.4.567.89)' can't be established. ECDSA key fingerprint is XXXXXX:XxXXXxxXX+XXXXXXXXxxxxxxXXxXxxxxXXxXXXX. Are you sure you want to continue connecting (yes/no/[fingerprint])?

yes そして Enter すると下記のメッセージが表示され、続けてパスワードを求められます。

Warning: Permanently added 's12.valueserver.jp,123.45.6.78' (ECDSA) to the list of known hosts.

パスワード入力してログイン完了

下記の様にパスワードを求められるので入力します。(タイプしても表示されないので注意)

abcabc@s123.xrea.com's password: 

パスワードを入力して Enter を押下すればログイン完了です。

PHP のバージョンを確認

ログインついでに現在インストールされている PHP のバージョンも確認してみます。コマンド「php --version」を実行してみます。

$ php --version
PHP 7.4.25 (cgi-fcgi) (built: Oct 19 2021 15:18:10)
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.27, Copyright (c), by Zend Technologies
$ 

PHP 7.4.25 が入っている様です。

ついでに Python のバージョンを確認

さらについでに Python のバージョンも確認してみます。コマンド「python --version」と「python3 --version 」をそれぞれ実行してみます。

$ python --version
Python 3.6.8
$ python3 --version
Python 3.6.8

現状 python でも python3 でも Python 3.6.8 が実行されるみたいですね。Python2 を起動したいときはコマンド「python2」を実行します。

ただ、Python 仮想環境の作成を実行しようとすると何かエラーが返ってきますね。

$ python3 -m venv python3-venv
Error: Command '['/virtual/アカウント名/python3-venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 2.

ロリポップのレンタルサーバーにSSHでログインする方法

SSH を有効化する

まずロリポップのユーザー専用ページで SSH を有効化する必要があります。

サーバーの管理・設定 > SSH をクリックします。

下記の画面が表示されるので「SSHを有効にする」をクリックします。

これでまず SSH 接続ができるようになりました。

アカウント名、初期ドメイン、パスワードを確認

次の画面でログインに必要な情報を確認できます。

  • サーバー
  • アカウント
  • 接続ポート
  • パスワード

これらの情報を使って SSH 接続していきます。

ターミナルを起動する

ターミナルを起動し、「ssh アカウント@サーバー -p 接続ポート」の形式で入力します。

例えば、アカウントが「bambina.jp-abcabc」だった場合、上記画面の情報を元に「ssh bambina.jp-abcabc@ssh.lolipop.jp -p 2222」となります。入力して Enter。

% ssh bambina.jp-abcabc@ssh.lolipop.jp -p 2222

初回は下記のようなメッセージが表示され、yes か no を求められますが、yes と入力して Enter で大丈夫です。

The authenticity of host '[ssh.lolipop.jp]:2222 ([133.130.35.108]:2222)' can't be established. ECDSA key fingerprint is XXXXXX:XxXXXxxXX+XXXXXXXXxxxxxxXXxXxxxxXXxXXXX. Are you sure you want to continue connecting (yes/no/[fingerprint])?

yes そして Enterすると下記のメッセージが表示され、続けてパスワードを求められます。

Warning: Permanently added '[ssh.lolipop.jp]:2222,[133.130.35.108]:2222' (RSA) to the list of known hosts.

パスワード入力してログイン完了

下記の様にパスワードを求められるので入力します。(タイプしても表示されないので注意)

bambina.jp-abcabc@ssh.lolipop.jp's password: 

パスワードを入力して Enter を押下すればログイン完了です。

ただ、ログインシェルが rbash になっていてかなり制限がかかっているので、ログイン後にコマンド「bash」を実行して rbash から bash に切り替える必要があります。

ついでに Python のバージョンを確認

ログインついでに現在インストールされている Python のバージョンも確認してみます。コマンド「python --version」と「python3 --version 」をそれぞれ実行してみます。

$ python --version
Python 2.7.5
$ python3 --version
Python 3.7.12

と言うわけで現在は Python 2.7.5 と Python 3.7.12 が入っていますね。

そしてさらについでに下記を順に実行すれば Python 仮想環境の作成&起動もできます。

$ bash
$ python3 -m venv python3-venv
$ source python3-venv/bin/activate
(python3-venv) $ python
Python 3.6.13 (default, Apr  7 2021, 03:38:31) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 

さらについでに MySQLdb モジュールを使える様 mysqlclient をインストールしようとすると。。

>>> exit()
$ pip install mysqlclient
Collecting mysqlclient
  Using cached mysqlclient-2.1.0.tar.gz (87 kB)
    ERROR: Command errored out with exit status 1:
     command: /home/users/0/bambina.jp-アカウント/python3-venv/bin/python3 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-zoshgtdz/mysqlclient/setup.py'"'"'; __file__='"'"'/tmp/pip-install-zoshgtdz/mysqlclient/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-l1irr5km
         cwd: /tmp/pip-install-zoshgtdz/mysqlclient/
    Complete output (15 lines):
    /bin/sh: mysql_config: コマンドが見つかりません
    /bin/sh: mariadb_config: コマンドが見つかりません
    /bin/sh: mysql_config: コマンドが見つかりません
    mysql_config --version
    mariadb_config --version
    mysql_config --libs
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-zoshgtdz/mysqlclient/setup.py", line 15, in <module>
        metadata, options = get_config()
      File "/tmp/pip-install-zoshgtdz/mysqlclient/setup_posix.py", line 70, in get_config
        libs = mysql_config("libs")
      File "/tmp/pip-install-zoshgtdz/mysqlclient/setup_posix.py", line 31, in mysql_config
        raise OSError("{} not found".format(_mysql_config_path))
    OSError: mysql_config not found
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
WARNING: You are using pip version 20.1.1; however, version 21.3.1 is available.
You should consider upgrading via the '/home/users/0/bambina.jp-アカウント/python3-venv/bin/python3 -m pip install --upgrade pip' command.

エラーが出てしまいました。

さくらレンタルサーバーでスクレイピング定期実行 & DB 保存

さくらのレンタルサーバを使ってスクレイピングをする方法をまとめます。

初めに言いますがページ遷移はカバーしていません。

eBay の商品情報を例としてページの要素を取得し、MySQL のデータベースに insert する一連の過程をまとめたいと思います。最後は CRON を使って定期実行させる設定も行います。

なので最低限 MySQL と CRON が使える「さくらのレンタルサーバ スタンダード」以上のプランを想定しています。

一応自分の忘備録としてまとめていますが、過程を追っていただければと思います。

  1. 実行環境の準備
  2. スクレイピングをしてみる
  3. データを保存する DB の作成
  4. Python からデータベースを操作する
  5. CRON で定期実行する

1. 実行環境の準備

さくらのレンタルサーバを契約する

まず始めるにあたってさくらのレンタルサーバを契約します。

冒頭でも書きましたが、データの保存と定期実行を行う前提なので MySQL と CRON が使える「さくらのレンタルサーバ スタンダード」以上のプランを使用します。

Python3 のインストール

サーバーへアクセスできる様になったら、Python3 をインストールして仮想環境を作成します。

さくらレンタルサーバのデフォルトの Python は Python2 なので Python3 を別途インストールする必要があります。下記の記事で手順を説明しています。

▶︎Python3 をインストールする方法

仮想環境の作成

Python3 のインストールが完了したら、任意の場所に仮想環境を作成します。

例として仮想環境「scraping_venv」を作成します。

% python3 -m venv scraping_venv
% 

仮想環境のパスに入り起動します。

% cd scraping_venv
% source bin/activate.csh
(scraping_venv) % 

3. スクレイピングをしてみる

では早速、requests モジュールを使ってページの情報を取得してみます。

requests のインストール

Web ページの取得に便利な requests をインストールするためコマンド「pip3 install requests」を実行します。

(scraping_venv) % pip3 install requests

インストールが完了したら Python3 を起動しますが、仮想環境を起動しているのでコマンド「python」で 起動できます。

(scraping_venv) % python
Python 3.9.0 (default, Jan  3 2021, 10:29:59) 
[GCC 4.2.1 20070831 patched [FreeBSD]] on freebsd9
Type "help", "copyright", "credits" or "license" for more information.
>>>

eBay ページの取得

requests をインポートし、requests.get() で URL「https://www.ebay.com/b/Video-Game-Consoles/139971/bn_320033」のソースコードを取得します。

>>> import requests
>>> r = requests.get('https://www.ebay.com/b/Video-Game-Consoles/139971/bn_320033')
>>> 

一旦変数 r に全部入ったので、r.text を実行するとソースコードが確認できます。

>>> r.text
'<!DOCTYPE html><!--[if IE 9]><html class="ie9" lang="ja"><![endif]--><!--[if gt IE 9]><!--><html lang="ja"><!--<![endif]--><head><style>\n    .font-marketsans body {\n        font-family: "Market Sans", Arial, sans-serif;\n    }\n</style><script>\n    (function() {\n        var useCustomFont = (\'fontDisplay\' in document.documentElement.style) ||\n                        (localStorage && localStorage.getItem(\'ebay-font\'));\n        if (useCustomFont) {\n            document.documentElement.classList.add(\'font-marketsans\');\n        }\n    })();\n</script><meta charset="utf-8"><link rel="'preconnect'" href="https://ir.ebaystatic.com" /><meta Property="og:description" Content="Shop eBay for great deals on ビデオゲームコンソール. You'll find new or used products in ビデオゲームコンソール on eBay. Free shipping on selected items." />

ソースコードを取得出来ることを確認できたので「exit()」を実行して一旦 Python のコンソールから出ます。

>>> exit() 
(scraping_venv) % 

Beautiful Soup で HTML 要素抽出

ページのソースを取得することはできたので、今度はそのソースコードから具体的な HTML の要素を抽出していきます。

HTML の取り扱いに便利な BeautifulSoup4 をインストールするためコマンド「pip3 install beautifulsoup4」を実行します。

(scraping_venv) % pip3 install beautifulsoup4

インストールが完了したら再度 Python3 を起動して BeautifulSoup と requestsをインポートします。

(scraping_venv) % python3
>>> from bs4 import BeautifulSoup
>>> import requests
>>> 

とりあえず eBay のページからサムネイル URL、商品名、商品ページ URL を取得したいと思います。

>>> r = requests.get('https://www.ebay.com/b/Video-Game-Consoles/139971/bn_320033')
>>> soup = BeautifulSoup(r.text,'html.parser')
>>> sitem = soup.find_all('li',class_='s-item') # クラス名が「s-item」の li 要素のリストを取得

Chrome のデベロッパーツールでページの構造を確認したところ、どうやらサムネイル URL、商品名、商品ページ URL は li 要素の中に含まれていて、その li 要素のクラス名が s-item だったので上記の様に取得しました。

取得した li 要素はリスト形式になっているので、for ループで各 li 要素からそれぞれの項目を抽出し、print していきます。

>>> for li in sitem: # 各 li 要素に対して処理を行う
...     img = li.find('img') # li 要素内の img 要素を取得
...     img_src = img.get('src') # img 要素内の src 属性を取得
...     name = li.find('h3') # li 要素内の h3 要素を取得
...     name_text = name.text # h3 要素内の文字列を取得
...     link = li.find('a') # li 要素内の a 要素を取得
...     link_href = link.get('href') # a 要素内の href 属性を取得
...     print(img_src)
...     print(name_text)
...     print(link_href)
... 

Enter を2度押下するとプログラムが実行されサムネイル、商品名、商品ページ URL が交互に表出されます。

... 
https://i.ebayimg.com/thumbs/images/g/Tl0AAOSwZpJgOul6/s-l300.jpg
ソニー PS5 ブルーレイエディションコンソール ( ディスク版 ) - クリスマス前に配達 !
https://www.ebay.com/p/19040936896?iid=154349758236
https://i.ebayimg.com/thumbs/images/g/AD4AAOSw3YphYRwA/s-l300.jpg
オリジナルNintendo EntertainmentシステムビデオゲームバンドルセットキットNESコンソールOG
https://www.ebay.com/p/101801921?iid=333818163486
https://i.ebayimg.com/thumbs/images/g/910AAOSwV5FhgtgV/s-l300.jpg
ソニー PS5 PlayStation 5 デジタル版コンソール-クリスマス配信前 !
https://www.ebay.com/p/25040975636?iid=154369068285

〜省略〜

https://ir.ebaystatic.com/cr/v/c1/s_1x2.gif
Microsoft Xbox One Day One Edition - 500 ギガバイトコンソールキネクトボックスコントローラテスト済み
https://www.ebay.com/itm/284613629401?hash=item42444b55d9:g:jBkAAOSwqldh5hbZ
https://ir.ebaystatic.com/cr/v/c1/s_1x2.gif
Nintendo Wii コンソール RVL-001 パワーリード 、 TVリード 、 センサーバー付き
https://www.ebay.com/itm/165287981385?hash=item267bee7149:g:I00AAOSwibph5VVv
https://ir.ebaystatic.com/cr/v/c1/s_1x2.gif
カシオゲームカンフーファイトCG - 310 ハンドヘルドゲーム 1990
https://www.ebay.com/itm/125105279976?hash=item1d20db13e8:g:J-IAAOSwn8dh5cND
>>> 

無事情報の抽出が出来ることを確認できたので、一旦「exit()」で Python のコマンドプロンプトから出ます。

>>> exit()
(scraping_venv) % 

同じ処理を Python ファイルで実行

一括で処理を実行できる様に、これまで実行したコマンドをまとめて下記のように一つのファイル(ebay_scraping.py)にまとめました。

# ebay_scraping.py
from bs4 import BeautifulSoup
import requests

r = requests.get('https://www.ebay.com/b/Video-Game-Consoles/139971/bn_320033')
soup = BeautifulSoup(r.text,'html.parser')
sitem = soup.find_all('li',class_='s-item') # クラス名が「s-item」の li 要素のリストを取得

for li in sitem: # 各 li 要素に対して処理を行う
    img = li.find('img') # li 要素内の img 要素を取得
    img_src = img.get('src') # img 要素内の src 属性を取得
    name = li.find('h3') # li 要素内の h3 要素を取得
    name_text = name.text # h3 要素内の文字列を取得
    link = li.find('a') # li 要素内の a 要素を取得
    link_href = link.get('href') # a 要素内の href 属性を取得
    print(img_src)
    print(name_text)
    print(link_href)

これを仮想環境「scraping_venv」直下にアップロードします。

そしてコマンド「python3 ebay_scraping.py」を実行します。

(scraping_venv) % python3 ebay_scraping.py
https://i.ebayimg.com/thumbs/images/g/Tl0AAOSwZpJgOul6/s-l300.jpg
ソニー PS5 ブルーレイエディションコンソール ( ディスク版 ) - クリスマス前に配達 !
https://www.ebay.com/p/19040936896?iid=154349758236
https://i.ebayimg.com/thumbs/images/g/GygAAOSwehBh5hlm/s-l300.jpg
ソニー PSP-3000 コンソール キングダム ハートゲームコンソール モンスターハンターゲームソフト付き
https://www.ebay.com/itm/313838198557?hash=item491236df1d:g:GygAAOSwehBh5hlm
https://i.ebayimg.com/thumbs/images/g/AD4AAOSw3YphYRwA/s-l300.jpg
オリジナルNintendo EntertainmentシステムビデオゲームバンドルセットキットNESコンソールOG
https://www.ebay.com/p/101801921?iid=333818163486

〜省略〜

https://ir.ebaystatic.com/cr/v/c1/s_1x2.gif
新品 ソニー PS4 Playstation 4 コンソール 1 TBスリム-新品送料無料
https://www.ebay.com/p/13031982632?iid=255337489506
https://ir.ebaystatic.com/cr/v/c1/s_1x2.gif
Nintendo GameCubeモデルNo. DOL -101 コンソールパーツと修理のみゲーム付き
https://www.ebay.com/itm/165288586955?hash=item267bf7aecb:g:TIgAAOSwZf9h5cbT
https://ir.ebaystatic.com/cr/v/c1/s_1x2.gif
Nintendo GameCube リージョンスイッチ付き LED mod カスタムコントローラ付き
https://www.ebay.com/itm/165288874148?hash=item267bfc10a4:g:u1cAAOSw3MJh5fWT
(scraping_venv) % 

無事サムネイル、商品名、商品ページ URL、が表出されました。ページに掲載される商品がタイミングによって違うので前回の実行時と若干内容が変わっています。

4. データベースの作成

ここまではただターミナル上に print してきましたが、これらの情報をデータベースに保存できる様にします。

さくらレンタルのコントロールパネルでデータベース作成

コントロールパネルのデータベースのセクションで「新規追加」をクリックします。

WordPress を使っている場合はそのデータベースが既にあると思いますが、何かを間違えて WordPress 用のテーブルに影響が出ると良くないので新規のデータベースを作ることをお勧めします。

無事新たなデータベースが作成されたので phpMyAdmin へログインします。

phpMyAdmin でテーブル作成

ログインした後、先ほど作成したデータベースを選択するとテーブル作成の画面に遷移すると思います。

テーブル名を入力して「Go」をクリックします。

カラム名、形式、長さを入力して「Save」をクリックします。

これでテーブル作成は完了です。下記のように反映されていると思います。

これでデータベースとその中にテーブルが出来上がりました。

5. Python からデータベースを操作する

では Python プログラムで抽出した情報をそのままデータベースのテーブルに insert 出来るようにしていきます。

MySQLdb モジュールで操作する

まずは Python で MySQL を操作するために必要な MySQLdb モジュールを使える様、ピp3で「mysqlclient」をインストールします。

(scraping_venv) % pip3 install mysqlclient

インストールしたら Python を起動し、MySQLdb をインポートしてデータベースに接続します。

(scraping_venv) % python3
>>> import MySQLdb
>>> conn = MySQLdb.connect(host='データベースサーバ', db='データベース名',user='ユーザー名',passwd='パスワード',charset='utf8mb4')
>>>

そして試しに先ほど作成したテーブル「ebay_products」に select クエリを叩いてみます。

>>> c = conn.cursor()
>>> c.execute('select * from ebay_products')
0
>>> 

まだデータを何も入れていないので 0 と返ってきています。動作は特に問題なさそうです。

Python ファイルに追記する

では先ほど作成した ebay_scraping.py を編集します。

MySQLdb モジュールでデータベースに接続する部分と合わせて、データを print する代わりにテーブルへ insert する様変更します。

# ebay_scraping.py
from bs4 import BeautifulSoup
import requests
import MySQLdb # 追記分

# 追記分↓
conn = MySQLdb.connect(host='データベースサーバー', db='データベース名',user='ユーザー名',passwd='パスワード',charset='utf8mb4')
c = conn.cursor()
# 追記分↑

r = requests.get('https://www.ebay.com/b/Video-Game-Consoles/139971/bn_320033')
soup = BeautifulSoup(r.text,'html.parser')
sitem = soup.find_all('li',class_='s-item')

for li in sitem:
    img = li.find('img')
    img_src = img.get('src')
    name = li.find('h3')
    name_text = name.text
    link = li.find('a')
    link_href = link.get('href')
    # print(img_src)
    # print(name_text)
    # print(link_href)
    # 追記分↓
    c.execute('insert into ebay_products values("'+img_src+'","'+name_text+'","'+link_href+'")')
    
conn.commit()
# 追記分↑

ではファイルを実行してみます。

(scraping_venv) % python3 ebay_scraping.py
(scraping_venv) % 

phpMyAdmin で対象のテーブルを開くとちゃんとデータが入っています。

これで eBay からデータを取得してデータベースへ保存するところまで出来ました。

6. CRON で定期実行する

作成したプログラムを定期的に実行する上で便利なのが CRON です。さくらのコントロールパネルから設定できるのでこの際やってみましょう。

コントロールパネル左下の「スクリプト設定」>「CRON設定」を開き「スケジュール追加」をクリックします。

設定画面が開くので実行コマンドと実行日時を設定します。毎日 21:00 に実行する設定にします。

「実行コマンド」欄は今回の場合「cd 実行ファイルのパス; Python3 の絶対パス 実行ファイル名」の形で下記の様に入力します。

cd www/notemite/scraping_venv; /home/ユーザー名/local/python/bin/python3 ebay_scraping.py

Python3 の絶対パスはコマンド「which python3」で確認できます。

% which python3
/home/ユーザー名/local/python/bin/python3

「保存する」をクリックして CRON 設定は完了です。

これで毎日 21:00 に ebay_scraping.py が実行され、取得したデータがデータベースのテーブルに insert されていきます。

複数処理を順に実行したい場合

余談ですが、設定できる CRON の数には限りがあるので、一つの処理につき一つの CRON を設定するとすぐ使い切ってしまいます。

なので例えば process_A.py、process_B.py、process_C.py という順番で実行したいプログラムがあった場合、まず CRON 設定の実行コマンドに下記を記述します。

cd www/notemite/scraping_venv; /bin/sh multiple_process.sh

これで CRON からは multiple_process.sh が実行されるので、個別のファイルと同じディレクトリに multiple_process.sh というファイルを作成し下記のように記述します。

#!/bin/sh
/home/ユーザー名/local/python/bin/python3 process_A.py &&
/home/ユーザー名/local/python/bin/python3 process_B.py &&
/home/ユーザー名/local/python/bin/python3 process_C.py

これによって CRON によって multiple_process.sh 呼び出され、まず process_A.py を実行、処理が成功したら process_B.py、さらにそれが成功したら process_C.py という具合に実行することができます。

WordPress 4.7 から 5.8 へ無事アップデート出来たご報告

おそらく 2017 年ごろから更新していなかったので 5 年近く WordPress のアップデートを放置していた様です。

その間に WordPress のエディタは Gutenberg へと大きく変わっておりました。

アップデートした方が良いだろうなと思いつつ「更新時に何かエラーが起きたら」と思うと面倒でずっと放置してきたんですが、いよいよ旧バージョンのエディタが不便に思えて仕方がないので更新することにしました。

WordPress の公式ドキュメントも参考にしつつ進めていきます。

  1. 要件の確認
  2. データベースとファイルのバックアップ
  3. WordPress の更新
  4. 記事のブロックエディタ変換

1. 要件の確認

まず 2022 年 1 月時点での WordPress の要件を確認しておきます。

PHPバージョン 7.4 以上
データベースMySQL バージョン 5.7 以上または MariaDB バージョン 10.2 以上
SSLHTTPS対応
2022 年 1 月時点

では上記を確認していきます。

PHP のバージョン

PHP のバージョンはサーバーに ssh でログインして「php --version」を実行して確認。

% php --version
PHP 7.4.25 (cli) (built: Nov 11 2021 13:56:22) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.25, Copyright (c), by Zend Technologies
% 

PHP 7.4.25 なので用件は満たしています。

MySQL のバージョン

続いて MySQL のバージョンを確認します。サーバーに ssh 等でアクセスできる場合は「mysql --version」を実行して確認できます。

% mysql --version
mysql  Ver 14.14 Distrib 5.5.32, for FreeBSD9.1 (amd64) using  5.2
% 

私はさくらのレンタルサーバーを使っていてデータベースのサーバに ssh 接続出来なかったので、コントロールパネルのデータベースタブで確認しました。

こちらも MySQL 5.7 ということで要件を満たしています。

SSL

HTTPS 対応に関してもさくらのレンタルサーバのコントロールパネルで確認しました。

「ドメイン/SSL」ページで対象のサイトの SSL を確認します。

2. データベースとファイルのバックアップ

上記の画像の通り、データベースとファイルをバックアップするようお勧めされているので従います。

データベースのバックアップ

まずはデータベースから。

phpMyAdmin でデータベースを丸ごとエクスポートします。

phpMyAdmin にログインしたら対象のデータベースを開き、全テーブルにチェックを入れ、「With selected:」の欄で「Export」を選択します。

するとエクスポートの画面へ遷移します。

デフォルトだと「Quick」にチェックが入っていますが「Custom」にチェックを入れます。

このままだと全テーブルの CREATE 文が一つの SQL ファイルにまとまってダウンロードされます。

今回はテーブル毎のファイルでダウンロードした方が便利な気がするので「Output」のセクションで「Export tables as separate files」にチェックを入れます。

「Object creation options」のセクションで「Add DROP TABLE / VIEW / PROCEDURE / FUNCTION / EVENT / TRIGGER statement」と「IF NOT EXISTS (less efficient as indexes will be generated during table creation)」にチェックを入れます。

一番下の「Go」をクリックするとダウンロードが始まります。

ダウンロードされた zip ファイルを解凍するとテーブルごとの SQL が入っています。

これでデータベースのバックアップはよしとします(願望)。

▶︎WordPress のバックアップ(公式サイト)

サイト関連ファイルのバックアップ

サイトのフォルダの一つ上の階層へ移動し、バックアップしておきたいフォルダを丸ごと「cp -r」コマンドでコピーします。

例えば「www」をいうディレクトリの中にある「notemite」というディレクトリ内に、WordPress を含むサイト関連のファイルが全て入っている場合。

「www」ディレクトリで下記のコマンドを実行します。

% cp -r notemite notemite_20220117

これで「www」ディレクトリの中に元々あった「notemite」ディレクトリはそのままの状態で、さらに「notemite_20220117」ディレクトリが作成されました。

これでとりあえずサイト関連のファイルのバックアップも完了です。

3. WordPress の更新

意を決して更新します。

するとしばらくして下記のページに切り替わりました。どうやら更新と同時にサイトが見れなくなるような事態は避けられたようです。

サイトにもアクセスしていくつかページを開いてみましたが、パーマリンクなども異常ありませんでした。よかった。

4. 既存記事をブロック形式へ変換

既存記事を開くと下記のように「クラシック」と表記がある場合があります。

この場合、記事が旧形式のままでブロックエディタに対応していないので、ブロックへ変換します。

「クラシック」の部分をクリックすると下記のように「ブロックへ変換」と表示されます。

そして「ブロックへ変換」をクリックすると、少しわかりづらいかもしれませんが下記の様にブロックエディタのツールボックスが表示される様になります。

これでこの記事もブロック形式へ変換されました。

というわけで WordPress のアップデートは一旦以上です!

Django の ForeignKey や ManyToManyField で取った情報をテンプレートに表示したい

Django の models.py で ForeignKey や ManyToManyField で他のモデルを参照する形になるとき、テンプレートでその他モデルのデータを引っ張って表示したい事も多いと思います。

と言うかそのために他テーブルを参照する事がほとんどかと思います。

いわゆる Join した形をイメージしますが、実は Join するために models.py で特別なことをする必要はほとんどありません。テンプレート上の記述を少し変更すれば完了します。

  1. 芸人、事務所、番組の例
  2. ForeignKey(外部キー)の場合
  3. ManyToManyField の場合

1. 芸人、事務所、番組の例

芸人、事務所、番組の例で説明します。

#models.py

class JimushoMaster(models.Model): # 芸人の所属事務所
    jimusho_name = models.CharField(max_length=20)

class BangumiMaster(models.Model): # 芸人の出演番組 
    bangumi_name = models.CharField(max_length=60, null=False, unique=True)

class GeininMaster(models.Model):
    name = models.CharField(max_length=20, null=False) # 芸人の名前
    jimusho = models.ForeignKey(JimushoMaster, on_delete=models.PROTECT) # 事務所との紐付き(一対多)
    bangumi = models.ManyToManyField(BangumiMaster) # 番組との紐付き(多対多)

芸人と事務所は一体多の関係、芸人と番組は多対多の関係になります。たぶん。

2. ForeignKey(外部キー)

まずは ForeignKey のケースから。

GeininMaster を渡しているテンプレート上で、JimushoMaster の jimusho_name の値を表出したいとします。

この場合 Template 上では「object名.外部キー項目.参照先テーブルの項目」まで入れるとテンプレート上に値を表示させられます。

{{ object.jimusho.jimusho_name }}

この様な感じです。

models.py で def __str__(self): を記述した場合の注意点

ForeignKey の参照先のモデル(この例では JimushoMaster)のクラス定義で「def __str__(self):」を記述している場合、テンプレートで「object.jimusho」までを指定すると、
def __str__(self):で参照している値がそのまま表出されます。

逆に「object.jimusho.jimusho_name」まで記述しても何も表出されないので気をつけてください。

3. ManyToManyField の場合

続いて ManyToManyField で参照している値をテンプレートに表出したい場合。

これまた GeininMaster を渡しているテンプレート上で、BangumiMaster の bangumi_name の値を表出したいとします。

ListView の例になりますが、View から受け取るオブジェクトの一つ一つに対して複数の ManyRelatedManager オブジェクトが返ってくるので一つずつ表出します。

下記の様な感じです。

{% for geinin in object_list %} # 各芸人に対して
    {% for i in geinin.bangumi.all %} # 複数のオブジェクトが返ってくるので
        {{ i.bangumi_name }} # オブジェクトごとに番組名を表出
    {% endfor %}
{% endfor %}

【2021年10月〜12月】YouTube 急上昇入りランキング

2021 年第 4 四半期の YouTube 急上昇動画数をチャンネル別にランキング形式で掲載しています。

チャンネル名ランクイン動画数
東海オンエア28 動画
コムドット25 動画
もちまる日記19 動画
BE:FIRST Official15 動画
両学長 リベラルアーツ大学14 動画
Kuzuha Channel13 動画
にじさんじ12 動画
なにわ男子12 動画
くれいじーまぐねっと CrazyMagnet11 動画
jun channel11 動画
NiziU Official10 動画
日常組9 動画
まいぜんシスターズ9 動画
ジャにのちゃんねる9 動画
はじめしゃちょー2 (hajime)9 動画
伊吹とよへ【オールユーキャンイート】8 動画
モンスト(モンスターストライク)公式8 動画
SixTONES8 動画
Fischer's-フィッシャーズ-8 動画
バンカラジオ8 動画
ROF-MAO / ろふまおチャンネル【にじさんじ】8 動画
48-フォーエイト8 動画
TOHO animation チャンネル8 動画
M-1グランプリ8 動画
カジサック KAJISAC7 動画
INI7 動画
kemio7 動画
Snow Man7 動画
Pekora Ch. 兎田ぺこら7 動画
JRA公式チャンネル7 動画
パパラピーズ7 動画
平成フラミンゴ7 動画
きりのちゃんねる7 動画
ABS-CBN Entertainment7 動画
SMTOWN6 動画
ANNnewsCH6 動画
JPAPA CHANNEL6 動画
HikakinTV6 動画
ハピ(HAPI)6 動画
THE FIRST TAKE6 動画
HikakinGames6 動画
まあたそ6 動画
Rofu〜アジア最強の男たち〜6 動画
北海道日本ハムファイターズ6 動画
【公式】Fate/Grand Order チャンネル6 動画
SKYHICHANNEL6 動画
たくあんTV6 動画
銀魂チャンネル【公式】6 動画
東映映画チャンネル5 動画
中町綾チャンネル5 動画