取り急ぎ 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 つがおすすめです。

さくらレンタルサーバーでスクレイピング定期実行 & 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 という具合に実行することができます。

Python 開発が可能なロボット Ameca(第一世代)の基本情報

Ameca とは

イギリスのロボット開発企業 Engineered Arts が開発したロボットの一つで、Mesmer、RoboThespian につぐ最新モデル。

人型のデバイスにマイクやカメラ、多数のセンサー、顔認識と音声認識の機能、そして機械学習用のハードウェアを積んだロボットですが、先代の Mesmer の開発で培われた 3D スキャンや表情の再現の技術によって非常にリアルな顔の表情や体の動きを再現する事が可能となっています。

187 センチ 49 キロと、人間で言うとかなりの痩せ型です。

Tinman

本体を Web ブラウザ上でリアルタイムにコントロールする Tinman という機能も統合されており、遠隔地のオペレーターがカメラやマイクを使用してロボットの周囲との会話をする事ができます。

Engineered Arts

平たく言うとビデオ通話の相手方のデバイスを PC からロボットに変えた様なイメージ。

ロボットならではの機能としては、画面上で特定の相手を選択してロボットの目線を合わせたり、オペレーターが話すと音声に合わせてロボットの口も動きます。

また、ロボットの表情を画面上で確認しながらボタンのクリックで感情の表現も可能です。

ユーザーに優しい設計

ロボットの保守やアップデート、変更など一連の作業が Web ブラウザ上で可能。リモートでサポートを受けることも可能。

Ameca に搭載されているたくさんのセンサーやカメラからの情報をリアルタイムで見ることができる。

開発プラットフォームとしての Ameca

主にカスタマーサービスやホスピタリティ、エンタメの分野での使用を想定されて作られていますが、人間型ロボットに関する開発プラットフォームとしての一面もあり、独自 OS の「Tritium」上でコードのテストや開発を行うことができます。

ソフトウェア、ハードウェアともにモジュラー型を採用、そしてクラウドと連携しているため開発やアップグレードがしやすく、頭部のみ、腕のみ、など個々のパーツに分けてテストや開発が可能とのこと。

Tritium OS

Tritium という独自 OS により、クラウド上でロボットの動きや人間とのコミュニケーションのコントロール、メンテナンス、コンテンツ(事前準備したロボットの挙動)の共有などが可能。

2つの相反する行動の命令が同時に来た場合にも、安全な順番で行う様な判断が可能だそうです。

Python IDE

Python の統合開発環境が提供されており、ロボットに搭載されたセンサーで取得した様々な情報を使ったオリジナルの機能や挙動を作成することが可能。ブラウザで開発環境へのアクセスが可能で、コードを書いてその場でロボット上でのテストが可能です。

RESTful API

RESTful API の技術を使って、Web 上で Ameca のコントロールが可能です。

外部の機材との連携やショーとのシンクロ、別の場所にあるセンサーとの連携によって行動を制御したり、遠方のロボットの行動の把握とコントロールを行えます。

CES 2022 で公開予定

レンタルサーバーの大クセPythonは要注意!どうしても使うならこれ

Python が普通に使えるわけではありません

Python を動かすためのレンタルサーバーを探しているそこのあなた。お待ちください。

実はレンタルサーバーでの Python 実行には下記のリスクがあるのをご存知でしたか?

  • SSH 接続できないかも
  • 仮想環境が使えないかも
  • データベースが操作できないかも
  • 最悪 Python の実行にすら辿りつかないかも
キーボード

不用意に怖がらせるつもりはないのですが、ネット上には公式サイトの仕様欄を鵜呑みにした記事が多く、実際自分が Python を使おうとした際に様々な問題にぶち当たりました。

その経験を踏まえ、当サイトでは実際に触って検証しましたので、ぜひサーバー選びの参考にしてみてください。

レンタルサーバーの Python は要注意

レンタルサーバーの公式サイトを見ると仕様欄に Python3 や MySQL が入っているので、何となく Python でプログラムを組みつつ MySQL のデータベースも使えてしまう様な気がしてきます。

が、実際使ってみるとそうもいきません。一つずつ見ていきましょう。

1. SSH 接続できないかも

まず SSH 接続が出来るかどうかの確認です。

SSH 接続とは
Windowsのコマンドプロンプトや Mac のターミナルなどを使ってサーバーを遠隔操作する方法

せっかくサーバーを借りても、SSH 接続が出来ないと Python の実行やパッケージのインストールなどが出来ません

ほとんどの共用サーバーは SSH 接続可能なので、ここはそこまで心配いらないと思いきや、スターサーバーでは SSH 接続出来ません。要注意です。

なぜ公式サイトで「Python」の記載があったのか分かりません。

XREAロリポップエックスサーバーコアサーバーConoha WINGバリューサーバースターサーバー
SSH 接続パスワードパスワード公開鍵公開鍵公開鍵パスワードNG

2. 仮想環境か使えないかも

次は Python の仮想環境が使えるかどうかの確認です。

仮想環境とは
例えば自分のパソコンに Python が入っていて、その中でスクレイピングのプログラムウェブサイト制作のプログラムの2つを作るとします。

それぞれのプログラムに必要なパッケージをインストールしていくと、どのパッケージがどちらのプログラムに使われているのか分からなくなったり、パッケージのアップデートなどでプログラム間の互換性が保てなくなることもあります。

この状況を整理するため、スクレイピング用の実行環境とウェブサイト制作用の実行環境を別々で作り、それぞれの中に必要なパッケージをインストールすることでお互いの干渉を防ぐのが仮想環境です。

これは公式サイトの仕様欄などを見ただけではわからないので、実際に仮想環境作成のコマンドを実行して確認してみました。

結果、そもそも SSH 接続も出来なかったスターサーバーに加え、バリューサーバーも仮想環境の作成ができませんでした。

逆に、それ以外のサーバーは問題なく仮想環境の作成ができました。

XREAロリポップエックスサーバーコアサーバーConoha WINGバリューサーバースターサーバー
SSH 接続パスワードパスワード公開鍵公開鍵公開鍵パスワードNG
仮想環境OKOKOKOKOKNG--

3. データベースが操作できないかも

レンタルサーバーで Python を使う際、最も気をつけなければならないのがPython でデータベースを使えるサーバーが少ないということです。

大抵のレンタルサーバーは WordPress には特化していて、数クリックで簡単にMySQL のデータベースが作成できることがほとんどですが、「Python でデータベースを操作する」となると話は別です。

mysqlclient モジュールのインストールが出来ない場合がある

共用サーバーで使用できるデータベースはほとんどの場合 MySQL ですが、Python で MySQL のデータベースを操作する場合は、mysqlclient モジュールをインストールする必要があります。

mysqlclent モジュール

実際にコマンドを実行して確認してみた結果、バリューサーバーやエックスサーバーなどでは mysqlclient のインストールで失敗しますし、ロリポップではサーバーに直接インストールはできるのに仮想環境で出来ないというクセもあります。

これも公式サイトの仕様欄などを見ただけではわからないので要注意です。

XREAロリポップエックスサーバーコアサーバーConoha WINGバリューサーバースターサーバー
SSH 接続パスワードパスワード公開鍵公開鍵公開鍵パスワードNG
仮想環境OKOKOKOKOKNG--
MySQLdbOKOK*不明*OK*不明NG--

また、上記の確認でデータベースを使えたとしても、レンタルサーバー特有の制限がかかっていて契約したレンタルサーバーからしかアクセスできない場合もありますので気をつけてください。

レンタルサーバーでのデータベース操作

つまり自分のパソコンからは操作できず、データベースを操作するスクリプトをレンタルサーバーに置いてそのスクリプトを実行するという様な回りくどい事をする羽目になります。

レンタルサーバー x Python ならほぼ XREA 一択

はい、というわけで SSH接続、仮想環境、MySQLdb 全て考慮すると、一番問題なく使えるのは XREA です。

XREA
公式サイトXREA
OSLinux (CentOS)
Python のバージョンPython2, Python3
データベース個数XREA Free:1
XREA Plus:5
CRONXREA Free:なし
XREA Plus:あり(個数不明)
ウェブ上の関連記事数多い
おすすめプランXREA Plus
(月額 210 円〜 + 初期費用 0 円)
無料お試し期間7 日間

ロリポップコアサーバーエックスサーバーに関しては SSH 接続と仮想環境の作成は問題ないですが、MySQLdb モジュールの使用に難ありです。

バリューサーバースターサーバーに関しては 仮想環境の作成も出来ないので Python の使用に関してはお勧めしません

その他の参考情報

ここまでで使えるサーバーがだいぶ絞られてしまいましたが、一応使えるデータベースの個数、CRON の個数、関連記事数も確認しましたので記載します。

1. 作成可能なデータベースの個数

Python でスクレイピングした情報など、データベースに保存したりデータベースから取り出したりする必要があります。その際、用途によってデータベースを分けたい場合もあると思いますので、作成可能なデータベースの個数も気にするといいと思います。

2. CRON の個数

CRON は指定した日時によって定期的にプログラムやスクリプトを実行できる機能です。スクレイピングやデータベースの更新など、CRON を使うと便利な場面が多いと思いますが、プランによって同時に設定できる CRON の個数が決まっているのでサーバーを選ぶ際には注目するといいと思います。

3. ウェブ上の関連記事数

サーバーの中で作業をしていく中で、必ず何かしらのエラーが起きて検索する必要があるのが常なので、検索した時にどの程度情報が出てくるかも大事なポイントです。検索結果の数も目安として掲載しますので参考にしてみてください。

ちなみに無料お試し期間があるサーバーも多いので、その間に Python3 を実際に試してみるのもありです。

各レンタルサーバーの検証内容

XREAロリポップエックスサーバーコアサーバーConoha WINGバリューサーバースターサーバー
Python バージョン2.x/3.x2.7/3.72.7/3.4/3.62.x/3.x2.7/3,62.7/3.62.7/3.4/3.6
SSH 接続パスワードパスワード公開鍵公開鍵公開鍵パスワードNG
仮想環境OKOKOKOKOKNG--
MySQLdbOKOK*不明*不明*不明NG--
データベース上限550無制限無制限無制限無制限30
CRON 上限個数不明10無制限不明不明9910
関連記事数多いかなり多いかなり多いかなり少ない多いかなり少ないかなり少ない
おすすめプランXREA PlusスタンダードスタンダードCORE-Xベーシックスタンダードスタンダード

1. XREA

XREA
公式サイトXREA
OSLinux (CentOS)
Python のバージョンPython2, Python3
データベース個数XREA Free:1
XREA Plus:5
CRONXREA Free:なし
XREA Plus:あり(個数不明)
ウェブ上の関連記事数多い
おすすめプランXREA Plus
(月額 210 円〜 + 初期費用 0 円)
無料お試し期間7 日間

SSH 接続

こちらはパスワードベースで SSH にログイン可能なので SSH 接続が簡単です。

Python 仮想環境

下記 4 行のコマンドだけで pip3 を使える状態の Python3 を起動できます。

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

ただ、デフォルトのシェルが rbash でかなり制限があるので、SSH 接続したら初めにコマンド「bash」を実行する必要があります。上のスクリプトの1行目で「bash」と入力しているのがそれです。

MySQL モジュールの使用

上記に続けて下記を順に実行していけば仮想環境内で MySQLdb モジュールを使うこともできます。

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

ウェブ上の関連記事数

「"XREA" "python3"」での検索結果は 5,020 件で、上の2つに比べると少ないですが、これでもよく調べれば普通の使い方には対応できるのではと思います。

おすすめプラン

XREA Free は無料ですが CRON が使えませんし、データベースも 1 つしか持てません。XREA Plus は CRON も使えてデータベースも 5 個まで作れるのでおすすめです。

利用開始するにはバリュードメインのアカウント(無料)作成も必要です。

公式サイトXREA

2. ロリポップ

ロリポップ!
公式サイトロリポップ!
OSLinux (CentOS)
Python のバージョンPython2.7, Python3.7
データベース個数ライトプラン:1
スタンダードプラン:50
CRON 個数ライトプラン:5
スタンダードプラン:10
ウェブ上の関連記事数かなり多い
おすすめプランスタンダード
(月額 440 円〜 + 初期費用 0 円)
無料お試し期間10 日間

SSH 接続

こちらも SSH へのログインはパスワードベースでなので分かりやすいです。

Python 仮想環境

SSH ログイン後はエックスサーバーと同じく下記 3 行のコマンドだけで pip3 を使える状態の Python3 を起動できました。本気で SSH ログインから 10 秒で Python3 を起動できます。

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

MySQL モジュールの使用

ただ、仮想環境内では MySQLdb モジュールがインストール出来ませんでした。仮想環境を作らずに Python3 を使うのであれば MySQLdb はすでに使えます。

$ python3
>>> import MySQLdb
>>> 

仮想環境外で追加パッケージをインストールする場合は「python3 -m pip install パッケージ名」でできる様です。

ウェブ上の関連記事数

「"ロリポップ" "python3"」での検索結果は 18,200 件と、こちらも多くの情報がすでにネット上に存在しています。

おすすめプラン

ライトだとMySQLデータベース1つしか作れないので、50個まで作れる「スタンダード」プランが良いと思います。

CRON もスタンダードプランであれば 10 個まで設定可能です。

こちらも無料お試し時にはクレジットカード情報などの入力は不要です。

公式サイトロリポップ!

3. エックスサーバー

エックスサーバー
公式サイトエックスサーバー
OSLinux
Python のバージョンPython2.7, Python3.4, Python3.6
データベース個数全プラン無制限
CRON 個数全プラン無制限
ウェブ上の関連記事数かなり多い
おすすめプランスタンダード
(月額 990 円 + 初期費用 3,300 円)
無料お試し期間10 日間

SSH 接続

SSH への接続は公開鍵認証の設定が必要で少し面倒ではあります。

Python 仮想環境

SSH ログインさえ出来れば下記のコマンドで pip3 を使える状態の Python3 を起動できます。

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

MySQLdb モジュールの使用

MySQLdb モジュールを使った MySQL の操作ですが、mysqlclient パッケージのインストールに失敗するという情報があります。

ウェブ上の関連記事数

「"エックスサーバー" "python3"」での検索結果は 12,500 件程度と、多くの情報がすでに存在しているので心強いです。

おすすめプラン

基本的な違いはディスクスペースの容量と無料独自ドメインの対象くらいなので「スタンダード」プランで充分だと思います。無料お試しに申し込んでもその時点ではクレジットカード情報などの入力が必要ないのも安心です。

CRON の個数は無制限です。データベースの個数も無制限です。すごいですね。

公式サイトエックスサーバー

4. コアサーバー

コアサーバー
公式サイトコアサーバー
OSLinux
Python のバージョンPython2, Python3
データベース個数全プラン無制限
CRON全プランあり(個数不明)
ウェブ上の関連記事数かなり少ない
おすすめプランCORE-X
(月額 399 円〜 + 初期費用 1,650 円)
無料お試し期間30 日間

SSH 接続

SSH への接続は公開鍵認証の設定が必要で少し面倒です。

Python 仮想環境

SSH ログイン後は他のサーバーと同じ様に「python3 -m venv 任意の仮想環境名」で仮想環境を作成できます。

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

ウェブ上の関連記事数

「"コアサーバー" "python3"」での検索結果は 500 件程度で、かなり少ない状態です。何か問題が起こったとき、まだ解決方法がネット上に載っていない場合も考えられます。

おすすめプラン

全プランで CRON あり、データベースの個数も無制限です。CORE-Xプランで十分足りると思います。

公式サイトコアサーバー

5. ConoHa WING

ConoHa WING
公式サイトConoHa WING
OSLinux (CentOS)
Python のバージョンPython2.7, Python3,6
データベース個数全プラン無制限
CRONあり(対象プラン及び個数不明)
ウェブ上の関連記事数多い
おすすめプランベーシック
(月額 740 円〜 + 初期費用 0 円)
無料お試し期間無し

SSH 接続

SSH への接続は公開鍵認証の設定が必要で少し面倒ではあります。

Python 仮想環境

SSH ログインさえ出来れば下記のコマンドで pip3 を使える状態の Python3 を起動できます。

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

ウェブ上の関連記事数

「"ConoHa WING" "python3"」での検索結果は 1,930 件で少し少ないかと思います。

おすすめプラン

データベースの個数は全プランで無制限です。 CRON は「ジョブスケジューラー」という名前で提供されていますが、個数はわかりませんでした。ベーシックプランがおすすめです。

公式サイトConoHa WING

6. バリューサーバー

バリューサーバー
公式サイトバリューサーバー
OSLinux
Python のバージョンPython2.7, Python3.6
データベース個数エコプラン:1
スタンダードプラン:無制限
CRON 個数エコプラン:10
スタンダードプラン:99
ウェブ上の関連記事数かなり少ない
おすすめプランスタンダード
(月額 367 円〜 + 初期費用 0 円)
無料お試し期間10 日間

SSH 接続

こちらもパスワードベースで SSH にログイン可能なので SSH 接続が簡単ですし、「python」でも「python3」でも Python3 が実行されるのも便利です。(Python2 の起動はコマンド python2 を実行)

Python 仮想環境

が、なぜか Python 仮想環境の作成時にエラーが発生します。

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

仮想環境外で mysqlclient をインストールしようとしてもエラーが発生するので、残念ながら Python の使用に関しては避けた方がいいと思います。

公式サイトバリューサーバー

7. スターサーバー

スターサーバー
公式サイトスターサーバー
OSLinux
Python のバージョンPython2.7, Python3.4, Python3.6
データベース個数ライト:1
スタンダード:30
CRON 個数ライト:5
スタンダード:10
ウェブ上の関連記事数かなり少ない
おすすめプランスタンダード
(月額 440 円〜 + 初期費用 0 円)
無料お試し期間14 日間

SSH 接続

何とスターサーバーは SSH 接続が出来ない仕様になっています。なので Python のコマンド操作なども出来ません。

公式サイトスターサーバー

おすすめは XREA

いかがでしたか?

学習も兼ねて Python を少しいじってみたいという場合は、既存の情報が多い上に SSH 接続、Python3 の実行、仮想環境の作成と全て問題なくできた XREA がおすすめです。

もし自分でも試したい場合は大体のレンタルサーバーが無料お試し期間を設けているので利用してみると良いかもしれません。お試し期間は基本的にクレジットカード情報など入力不要なので安心です。

更なるおすすめは VPS

最後に繰り返しになりますが、Python でプログラミングをしていくのであればレンタルサーバーよりも VPS がおすすめです。絶対に。

ご自身のためにも、下記の記事をチェックしてみてください。

▶︎レンタルサーバーで Python は要注意!VPS が楽得でおすすめ

【番外編】さくらレンタルで無理やり Python 3 と MySQL を使う

ちなみにさくらのレンタルサーバーはそもそも Python 2しか入っていないのでこの記事にも載せていないんですが(現在の推奨は Python 3 で Python 2 は非推奨)一応 Python 3 をインストールして仮想環境で MySQLdb をインストールすることも出来ました。

めんどくさすぎたので正直全くお勧めしないですが、気合いで頑張りたい方々のために一応貼っておきます。

さくらの VPS (Ubuntu 20.04) で Django アプリを作る(3/3)

Ubuntu 環境(さくらのVPS )で Django アプリケーションを作るまでに実際に辿ったステップ。こちらの記事の続編です。

今回はこれまでのステップで作成した Django アプリケーションの HTTPS 化、そして使用データベースを MySQL に変更します。

  1. ドメインの HTTPS 化
    • ポート 443 の開放
    • certbot と Nginx プラグインのインストール
    • certbot の設定
    • 変更内容の確認
  2. 使用データベースを MySQL に変更する
    • MySQL のインストール
    • 非 root ユーザーとデータベースの作成
    • mysqlclient インストールの準備
    • Python 仮想環境と MySQLdb の動作確認

1. サイトの HTTPS 化

サイトに https でアクセスできる様設定します。certbot を使えば Let's Encrypt の TLS/SSL 証明書の取得や設定を簡単に行うことができます。

ポート 443 の開放

さくらインターネットのパケットフィルタを使っている場合、ポート番号 443 が開放されている必要があります。

ファイアウォールで設定する場合は ufw コマンドで必要な設定を行ってください。

certbot と Nginx プラグインのインストール

certbot(Let's Encrypt 使用の HTTPS 自動設定パッケージ)と python3-certbot-nginx(Certbot 用 Nginx プラグイン)をインストールします。

$ sudo apt install certbot python3-certbot-nginx

certbot の設定

Nginx プラグインを使用して自動設定を走らせます。このプロセスによって自動的に sites-available ディレクトリ内の Nginx 設定ファイルに変更が加えられます。

コマンド内「-d」の後に HTTPS 化するドメインを入力します。Nginx の設定ファイル内、server_name に指定されているドメインと一致しているのを確認してください。

$ sudo certbot --nginx -d example.com -d www.example.com

これを実行すると緊急連絡用のメールアドレスの入力を求められ、入力して続けると利用規約への同意、お知らせメール送信の可否、そして最後に HTTP へのリクエストを HTTPS へリダイレクトするか否かを尋ねられるのでそれぞれ回答して進めていきます。

以上で完了です。https でのアクセスが可能になっているはずです。

変更内容の確認

完了後、Nginx 設定ファイルを確認すると「# managed by Certbot」のコメントと共に自動で追記された内容を確認できます。

既存の server ブロック内への追記内容

    listen [::]:443 ssl; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/graffuhs.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/graffuhs.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

新規作成された server ブロックの内容

server {
    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen 80;
        listen [::]:80;

        server_name example.com;
    return 404; # managed by Certbot


}
server {
    if ($host = www.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen 80;
        listen [::]:80;

        server_name www.example.com;
    return 404; # managed by Certbot


}

この設定によって「http://example.com」と「http://www.example.com」両方とも HTTPS へリダイレクトされる様になりました。

2. 使用データベースを MySQL に変更する

MySQL のインストール

コマンド「sudo apt install mysql-server」を実行し、MySQL をインストールします。

adminvps@xx1-234-56789:~$ sudo apt install mysql-server
adminvps@xx1-234-56789:~$ 

コマンド「sudo mysql_secure_installation」を実行。

adminvps@xx1-234-56789:~$ sudo mysql_secure_installation
adminvps@xx1-234-56789:~$ 

コマンド「sudo mysql」で MySQL へアクセスしてみます。

vpsadmin@xx1-234-56789:~$ sudo mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 8.0.23-0ubuntu0.20.04.1 (Ubuntu)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

無事アクセスできました。コマンド「exit」で MySQL から出ます。

mysql> exit
Bye
vpsadmin@xx1-234-56789:~$ 

非 root ユーザーとデータベースの作成

root で接続

sudo mysql -u root
create user ユーザー名 identified by 'パスワード';
GRANT ALL PRIVILEGES ON demodb.* to demouser@'%';
flush privileges;

ここで作成したユーザー名とパスワードを Django の settings.py で使います。

mysqlclient インストールの準備

libmysqlclient-dev と default-libmysqlclient-dev をインストールします。

adminvps@xx1-234-56789:~$ sudo apt install libmysqlclient-dev default-libmysqlclient-dev

Python 仮想環境と MySQLdb の動作確認

(sample) adminvps@xx1-234-56789:~/sample/bin$ pip install wheel
Collecting wheel
  Downloading wheel-0.36.2-py2.py3-none-any.whl (35 kB)
Installing collected packages: wheel
Successfully installed wheel-0.36.2
(sample) adminvps@xx1-234-56789:~/sample/bin$ pip install mysqlclient
Requirement already satisfied: mysqlclient in /home/adminvps/sample/lib/python3.9/site-packages (2.0.3)
(sample) adminvps@xx1-234-56789:~/sample/bin$ 

ここで、Python の仮想環境と MySQLdb の動作確認をしてみます。

Python 仮想環境を作り、起動します。

vpsadmin@ss1-234-56789:~$ python3.9 -m venv testvenv
vpsadmin@ss1-234-56789:~$ source testvenv/bin/activate
(testvenv) vpsadmin@ss1-234-56789:~$

wheel をインストールします。

(testvenv) vpsadmin@ss1-234-56789:~$ pip install wheel
Collecting wheel
  Using cached wheel-0.36.2-py2.py3-none-any.whl (35 kB)
Installing collected packages: wheel
Successfully installed wheel-0.36.2
(testvenv) vpsadmin@ss1-234-56789:~$

mysqlclient をインストールします。

(testvenv) vpsadmin@ss1-234-56789:~$ pip install mysqlclient
Processing ./.cache/pip/wheels/43/55/d9/a2243d4b624c18c5cba30bf88e0521147498368068cb302532/mysqlclient-2.0.3-cp39-cp39-linux_x86_64.whl
Installing collected packages: mysqlclient
Successfully installed mysqlclient-2.0.3
(testvenv) vpsadmin@ss1-234-56789:~$ 

*pip install は「mysqlclient」ですが、python で import するときは「import MySQLdb」になります。(import mysqlclient ではない)誰も間違わないかもしれませんが僕はこれでハマってました。。。

Python を起動し、import MySQLdb ができるか確認します。

(testvenv) vpsadmin@ss1-234-56789:~$ python3.9
Python 3.9.0+ (default, Oct 20 2020, 08:43:38) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import MySQLdb
>>> 

無事 import できたので大丈夫そうです。

他の行程へ

▶︎まずは2週間無料でお試し♪さくらのVPS

さくらの VPS (Ubuntu 20.04) で Django アプリを作る(2/3)

Ubuntu 環境(さくらのVPS )で Django アプリケーションを作るまでに実際に辿ったステップ。こちらの記事の続編です。

今回は実際に Django のプロジェクト・アプリケーションを作って公開するところまで。Web サーバーとして Nginx、アプリケーションサーバーとして Gunicorn の設定も行います。

また、今後同じサーバーで複数の Django プロジェクトを作っても大丈夫な様に設定していきます。

Django + Nginx + Gunicorn での設定

全体はとりあえずこんな感じのイメージです。

  1. サイトをホストするディレクトリの作成
    • ルートディレクトリ作成
    • 管理者の変更
  2. Django を動かす
    • Python 仮想環境作成
    • Django インストール
    • Django プロジェクトと Django アプリケーションを作成
    • settings.py の設定
    • Django の動作確認
  3. Web サーバーの設定(Nginx)
    • Web サーバー: Nginx
    • 設定ファイル(nginx.conf)
  4. アプリケーションサーバーの設定(Gunicorn)
    • アプリケーションサーバー: Gunicorn
    • 仮想環境内で pip install gunicorn
    • systemd .socket ファイル
    • systemd .service ファイル
    • Nginx の設定ファイルでソケットを使用する様設定する
  5. 静的ファイルの設定

1. サイトをホストするディレクトリの作成

サーバー上にサイトホスト用ディレクトリを作成しますが、今後を見越し、複数のドメインを同じサーバー上でホスト出来る様に配慮して作業を進めていきます。

ルートディレクトリ作成

サイトをホストするルートディレクトリを作成します。

Nginx はデフォルトで「/var/www/html」というディレクトリを作っていますが、今回は /var/www/ の配下にドメイン名のディレクトリ、そしてその配下に html というディレクトリを作ります。(イメージ:/var/www/example.com/html)

vpsadmin@xx1-234-56789:/var/www$ sudo mkdir -p example.com
[sudo] password for vpsadmin: 
vpsadmin@xx1-234-56789:/var/www$ ls
html  meatthezoo.org
vpsadmin@xx1-234-56789:/var/www$ cd example.com
vpsadmin@xx1-234-56789:/var/www/example.com$ sudo mkdir -p html

管理者の変更

ディレクトリの管理者を変更します。

vpsadmin@xx1-234-56789:/var/www$ sudo chown -R $USER:$USER /var/www/example.com/html

2. Django を動かす

Python 仮想環境作成

ルートディレクトリ(/var/www/example.com/html)直下で「python3 -m venv 仮想環境名」を実行しPython の仮想環境を作成します。

$ python3 -m venv djangovenv

Django インストール

仮想環境を起動し、「pip install django」で Django をインストールします。

% cd djangovenv
% source bin/activate
(djangovenv) % pip install django

Django プロジェクトと Django アプリケーションの作成

Django プロジェクトと Django アプリケーションを作成していきます。

(djangovenv) % django-admin startproject djangoprod
(djangovenv) % cd djangoprod
(djangovenv) % python manage.py startapp djangoapp

settings.py の設定

settings.py の ALLOWED_HOSTS にサイトのドメイン名を登録し、INSTALLED_APS にアプリケーションを追加します。

ALLOWED_HOSTS = ['example.com', 'www.example.com']

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'djangoapp.apps.DjangoAppConfig' # 追記分
]

Django の動作確認

コマンド「python manage.py runserver 0.0.0.0:8000」を実行し、ブラウザの URL バーに「ドメイン名:8000」と打ち込んでみます。

Django デフォルトのロケットの画面が出たら大丈夫です。ちなみにこの画面は settings.py の DEBUG = True の時だけ表示されます。

Djangoのデフォルトエラーページが DEBUG=Falseだと見れないのはなんでか調べた

今現在、Django の runserver を起動した場合に限り、ポート 8000 でなら Django が動くという状態です。

というわけで Web サーバー(Nginx)をアプリケーションサーバー(Gunicorn)を使って下記を解決していきます。

問題解決方法
URL バーでポート 8000 を指定しないとアクセスできないNginx の設定ファイルで、該当するドメイン名にアクセスされたら Django に繋ぐ様変更する
runserver を起動していないとアクセスできないGunicorn を使う

3. Web サーバーの設定(Nginx)

設定ファイル(nginx.conf)

デフォルトの設定ファイルは「/etc/nginx/nginx.conf」

初めから下記の二行が書いてあればこのファイルはノータッチで良さそうです。

  • include /etc/nginx/conf.d/*.conf;
  • include /etc/nginx/sites-enabled/*;

複数ドメイン対応

一つのサーバーで複数のウェブサイトを運営しようとした場合、一つの IP アドレスに複数のドメイン名が紐づく事になります。

そのため、リクエストされた URL に応じて適切なサイトの情報を返せる様設定していきます。

  1. sites-available ディレクトリにドメイン毎の設定ファイルを置く
  2. 各ドメインの設定ファイルでドメインとルートディレクトリを紐付け
  3. それらファイルのシンボリックリンクを sites-enabled ディレクトリに作成
  4. sites-enabled を nginx.conf 本体に include

設定ファイルの複製と編集

「sites-available」ディレクトリの「default」ファイルを個別サイト用にコピーします。

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com

コピーした方のファイルを確認します。下の方に Virtual Host のための設定というところがあるのでそちらを使います。上半分は Default Server のための設定なので全てコメントアウトします。

server_name と location / の部分を編集しました。

example.com ファイルの Virtual Host 設定部分
# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#

server {
        listen 80;
        listen [::]:80;

        server_name www.example.com;
        return 301 http://example.com$request_uri;
}


server {
        listen 80;
        listen [::]:80;

        server_name example.com;

        root /var/www/example.com/html;
        index index.html;

        location / {
                try_files $uri $uri/ =404;
                include proxy_params;
                proxy_pass http://127.0.0.1:8000;
        }
}
ファイル内の概念解説
listenリクエストを受け入れる IP アドレスやポートの指定。
UNIX ドメインソケットのパスでも可。
server_nameリクエストを受け入れるサーバー名(ドメイン名)の指定。
複数のサーバー名をスペース区切りで設定可。
try_filesファイルの存在を指定された順に確認。
$uriリクエストの URI。リダイレクト時など、処理の中で元々のリクエストから書き変わることもある。
include proxy_params/etc/nginx/proxy_params」にプロキシの設定が記載してあるので include。
proxy_passプロキシサーバーの指定。
参照 Nginx Documentation

初めの部分は「www.example.com」へのアクセスを自動的に「example.com」へリダイレクトする設定です。

シンボリックリンクを作成します。

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

Nginx を再起動します。

sudo systemctl restart nginx

そして runserver を実行して、反映を確かめます。

python manage.py runserver 0.0.0.0:8000

これで一つ解決です。ポート 8000 を URL に含めなくても Django に飛ぶ様になりました。

次は runserver を起動していないとアクセスできないという部分を、Gunicorn を使って解決します。

問題解決方法
runserver を起動していないとアクセスできないGunicorn を使う

4. アプリケーションサーバーの設定(Gunicorn)

Nginx から飛んできたリクエストを、待ち受けているソケットから Django アプリケーションに伝える様に設定します。

言い方を変えると Nginx からのリクエストを .socket ファイルが受け、.service ファイルを起動し Gunicorn の処理を実行します。

Gunicorn のインストール

仮想環境内で pip install gunicorn を実行します。

pip install gunicorn

.socket と .service の作成

「/etc/systemd/system/」ディレクトリに .socket と .service を作成します。今回はファイル名をそれぞれ「sample_django.socket」、「sample_django.service」としています。

systemd .socket ファイル

Nginx の設定ファイルで指定したポートでリクエストを待ち受け、 リクエストがあったら指定されているサービスに接続を渡します。

# sample_django.socket

[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/sample_django.sock
[Install]
WantedBy=sockets.target
項目メモ
Descriptionログ出力の際などに使われる
ListenStreamポートの指定。Nginx 設定ファイルの pass_proxy で指定
WantedBysockets.target

systemd .service ファイル

サービスの依存関係や実際の実行内容を定義します。

# sample_django.service

[Unit]
Description=gunicorn daemon
Requires=sample_django.socket
After=network.target
[Service]
User=root
Group=root
WorkingDirectory=/var/www/example.com/html/djangovenv/djangoprod
ExecStart=/var/www/example.com/html/djangovenv/bin/gunicorn --workers 3 --bind unix:/run/sample_django.sock djangoprod.wsgi:application
[Install]
WantedBy=multi-user.target
項目メモ
Descriptionログ出力の際などに使われる
Requires対応する .socket ファイル
After
User
Group
WorkingDirectorymanage.py があるディレクトリのフルパス?
ExecStartsystemctl start した時に実行するコマンド。
.sock と wsgi を bind。
venv 内の gunicorn のフルパス(?)を指定
WantedBy大抵 multi-user.target で大丈夫

サービスを起動します。

systemctl start sample_django.socket
systemctl start sample_django.service

下記を実行すると Gunicorn のステータスを確認できます。

sudo systemctl status sample_django

Nginx 設定ファイルの変更

Nginx 設定ファイルの proxy_pass の部分を下記の様に変更しました。.socket ファイルの ListenStream で設定したポートを指定しています。

location / {
        try_files $uri $uri/ =404;
        include proxy_params;
        # proxy_pass http://127.0.0.1:8000;
        proxy_pass http://unix:/run/sample_django.sock;
}

Nginx の設定を検証し再起動します。

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ sudo systemctl restart nginx

これで runserver を実行しなくても URL を叩けば Django アプリケーションへアクセスできる様になったはずです。

大雑把ですがなんとなく全体像は下記の様なイメージです。

Django + Nginx + Gunicorn での設定

*作業時は何かにつけて「pkill gunicorn」で gunicorn を終わらせた方が良いです。エラーが起きていくらコードを修正しても治らないまま数時間経って、「pkill gunicorn」一発で治ったこともありました。

静的ファイルの設定

実はこの時点では CSS や JavaScript のいわゆる静的ファイルはうまく反映されません。ドメイン名/admin にブラウザでアクセスすると CSS が抜けている状態だと思います。

Django で静的ファイルとうまくやる

本番環境でちゃんと表示される様、settings.py と Nginx の設定ファイルを編集します。

settings.py の編集

settings.py 内では STATICFILES_DIRS と STATIC_ROOT を設定します。

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]
STATIC_ROOT = '/var/www/example.com/html/static'
項目メモ
STATICFILES_DIRScollectstatic が静的ファイルを追加検索する対象のディレクトリ(特定のアプリケーションに属さないものが対象)
STATIC_ROOTcollectstatic 実行時に静的ファイルの集約先となるディレクトリ

collectstatic を実行します。

python manage.py collectstatic

Nginx の設定ファイルの編集

server ディレクティブの中に STATIC_ROOT 指定したパスを追記しました。

        location /static {
                alias /var/www/example.com/html/static;
        }

これでドメイン名/admin を再度確認すると CSS が反映されていると思います。

他の行程へ

▶︎まずは2週間無料でお試し♪さくらのVPS

さくらの VPS (Ubuntu 20.04) で Django アプリを作る(1/3)

Ubuntu 環境(さくらのVPS )で Django アプリケーションを作るまでに実際に辿ったステップを記録します。

手順がかなり多いので途中あまり詳しく書いていないところもありますがご了承ください。

まずは VPS の契約から Ubuntu OS の設定Python のインストールWeb サーバーのインストールまで。

  1. VPS の契約(さくらの VPS)
  2. 独自ドメインの取得
  3. IP アドレスとドメイン名を紐付け
  4. OS (Ubuntu 20.04) のインストール
  5. Ubuntu の初期設定
    • ssh でサーバーへ接続
    • 非 root ユーザーの作成
    • パッケージリストを最新版へ更新
    • パッケージのアップグレード
    • サーバーの再起動
  6. FTP サーバーのインストール
  7. 開発パッケージのインストール
  8. Python と関連パッケージのインストール
    • 依存関係のインストール
    • Python 3.9 のインストール
    • python3.9-dev のインストール
    • 仮想環境(venv)のインストール
  9. Web サーバー(Nginx)のインストール

ちなみに、僕は初め下記の書籍に沿って Django の全体像を勉強しました。書籍の中では AWS を使ったデプロイにも触れられていますので参考にしてみてください。

動かして学ぶ! Python Django開発入門 (NEXT ONE)

1. VPS の契約(さくらの VPS)

まずは VPS の契約。私は月額 880 円〜の さくらのVPS 1G プランにしました。

公式ページさくらのVPS 1G

さくらの VPS 以外でも大丈夫

とはいうものの、実はさくらの VPS でなくても Ubuntu OS であればこちらの記事の手順で特に問題ないです。

コントロールパネルの見た目やファイアウォールの設定の部分だけは少し違いますが、それは一番初めの部分でそれ以降は OS に依存するので他の VPS でも変わりません。

Django におすすめの OS と VPS を下記の記事で紹介しているのでぜひ参考にしてみてください。

▶︎ Django のおすすめ VPS(仮想専用サーバー)は OS から選ぶべし
▶︎ Ubuntu を手軽に使える VPS おすすめ 7 選

2. 独自ドメインの取得

サイト公開用の独自ドメインを取得します。こちらもさくらのドメインで取得しました。

3. IP アドレスとドメイン名を紐付け

VPS コントロールパネルの「ネームサーバ登録」をクリックします。

遷移先のページで「ドメインリスト」をクリック後、対象のドメインの「ゾーン編集」をクリックし、情報を登録します。

ゾーン情報の設定に関しては下記の記事にもまとめているので参考にしてみてください。

4. OS (Ubuntu 20.04) のインストール

VPS コントロールパネルの「各種設定」そして「OSインストール」をクリックします。

今回は標準 OS の Ubuntu 20.04 をインストールします。

サーバーのファイアウォールを設定する代わりに、さくら VPS のパケットフィルタの機能でポートの開閉を設定しています。

ファイアウォールで設定する場合はパケットフィルタをオフにします。

「インストールを実行する」をクリックし、Ubuntu のインストールを開始します。

先ほどと重複しますが、Ubuntu 以外にも Django におすすめの OS を下記の記事で紹介しているのでもしよければ見てみてください。

▶︎ Django におすすめの OS と VPS の選び方

5. Ubuntu の初期設定

ssh でサーバーへ接続

ターミナルで「ssh 管理ユーザー名@ホスト名」と打ち込み接続します。ホスト名は下記の通りコントロールパネルの「ネットワーク情報」タブで確認できます。

下記の様にコマンド「ssh 管理ユーザー名@ホスト名」を入力します。

% ssh ubuntu@xx1-234-56789.vs.sakura.ne.jp

初めて接続する際に下記の様に「The authenticity of host 'xx1-234-56789.vs.sakura.ne.jp (123.456.78.90)' can't be established.」とメッセージが出ることがありますが特に問題ないので yes と打ち込みます。

The authenticity of host 'xx1-234-56789.vs.sakura.ne.jp (123.456.78.90)' can't be established.
ECDSA key fingerprint is XXX123:ABCDEFGHIJKLMNOPQRSTUVWXYZ.
Are you sure you want to continue connecting (yes/no/[fingerprint])? 
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'xx1-234-56789.vs.sakura.ne.jp.123.456.78.90' (ECDSA) to the list of known hosts.
% ssh ubuntu@xx1-234-56789.vs.sakura.ne.jp
ubuntu@xx1-234-56789.vs.sakura.ne.jp's password: 

パスワードを入力し無事 ssh で サーバーへログインできました。

% ssh ubuntu@xx1-234-56789.vs.sakura.ne.jp
ubuntu@xx1-234-56789.vs.sakura.ne.jp's password: 
Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-52-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Fri Apr  9 08:11:04 JST 2021

  System load:  0.0               Processes:             105
  Usage of /:   2.0% of 94.43GB   Users logged in:       0
  Memory usage: 16%               IPv4 address for ens3: 123.456.78.90
  Swap usage:   0%


66 updates can be installed immediately.
0 of these updates are security updates.
To see these additional updates run: apt list --upgradable


The list of available updates is more than a week old.
To check for new updates run: sudo apt update


The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.


SAKURA internet [Virtual Private Server SERVICE]

To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

ubuntu@xx1-234-56789:~$ 

3行目に「Welcome to Ubuntu 20.04.1 LTS」と書かれてあります。それ以降の部分はサーバーの容量やアップデートなどの案内事項です。

非 root ユーザーの作成

ログインしたユーザーを root ユーザーへ昇格し、新たな sudo ユーザーを作成します。詳しくは下記の記事を参照してください。

パッケージリストを最新版へ更新

コマンド「sudo apt update」でパッケージリストを最新版に更新します。

ubuntu@xx1-234-56789:~$ sudo apt update
ubuntu@xx1-234-56789:~$ 

パッケージのアップグレード

コマンド「sudo apt upgrade」を実行し、サーバーに元々インストールされているパッケージに対してアップグレードを実施します。

ubuntu@xx1-234-56789:~$ sudo apt upgrade
ubuntu@xx1-234-56789:~$ 

サーバーの再起動

コマンド「sudo reboot」を実行し、サーバーを再起動します。

ubuntu@xx1-234-56789:~$ sudo reboot
Connection to xx1-234-56789.vs.sakura.ne.jp closed by remote host.
Connection to xx1-234-56789.vs.sakura.ne.jp closed.
% 

6. FTP サーバーのインストール

FTP 接続ができる様にしたいので vsftpd をインストールします。コマンド「sudo apt install vsftpd」を実行します。

ubuntu@ik1-437-50827:~$ sudo apt install vsftpd
ubuntu@ik1-437-50827:~$ 

Cyberduck で接続できました。

7. 開発パッケージのインストール

adminvps@xx1-234-56789:~$ sudo apt install build-essential
adminvps@xx1-234-56789:~$ 

8. Python と関連パッケージのインストール

コマンド「python3 -V」で Ubuntu 20.04 にもともと入っている Python のバージョンを確認します。

adminvps@xx1-234-56789:~$ python3 -V
Python 3.8.5
adminvps@xx1-234-56789:~$

Python 3.8.5 が入っていました。この後 Python 3.9 をインストールします。

依存関係のインストール

Python 自体をインストールする前に必要な依存関係をインストールします。コマンド「sudo apt install 〜」で様々なパッケージをインストールします。

adminvps@xx1-234-56789:~$ sudo apt install zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev wget libbz2-dev
adminvps@xx1-234-56789:~$ 

Python 3.9 のインストール

依存関係のインストールが完了したら、Python 3.9 をインストールします。

adminvps@xx1-234-56789:~$ sudo apt install python3.9
adminvps@xx1-234-56789:~$ 

python3.9-dev のインストール

adminvps@xx1-234-56789:~$ sudo apt install python3.9-dev
adminvps@xx1-234-56789:~$ 

仮想環境(venv)のインストール

Python の仮想環境である venv をインストールするためコマンド「sudo apt-get install python3.9-venv」を実行します。

adminvps@xx1-234-56789:~$ sudo apt-get install python3.9-venv
adminvps@xx1-234-56789:~$ 

9. Web サーバー(Nginx)のインストール

コマンド「sudo apt install nginx」で Nginx をインストールします。

adminvps@xx1-234-56789:~$ sudo apt install nginx
adminvps@xx1-234-56789:~$ 

ブラウザの URL バーにサーバーの IP アドレスを入れてみて、下記のページが出れば無事インストールされています。

とりあえず VPS に Ubuntu が入りPython と Nginx がインストールされた状態です。

他の行程へ

▶︎まずは2週間無料でお試し♪さくらのVPS

【Ubuntu】Python の CaboCha をインストールして形態素解析を行う

Ubuntu 20.04 で CaboCha を使える様にした時の手順を記録しておきます。

  1. MeCab のインストール
  2. mecab-ipadic-neologd のインストール
  3. CRF++ のインストール
  4. CaboCha のインストール
  5. Pythonへのバインディング

まだインストールしていなければ build-essential をインストールします。

$ sudo apt install build-essential

1. MeCab のインストール

$ sudo apt install mecab
$ sudo apt install libmecab-dev
$ sudo apt install mecab-ipadic

この時点でコマンド「mecab」を実行して何か文章を入力すると MeCab が形態素解析をしてくれます。

$ mecab
今日はいい天気ですね。
今日	名詞,副詞可能,*,*,*,*,今日,キョウ,キョー
は	助詞,係助詞,*,*,*,*,は,ハ,ワ
いい	形容詞,自立,*,*,形容詞・イイ,基本形,いい,イイ,イイ
天気	名詞,一般,*,*,*,*,天気,テンキ,テンキ
です	助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
ね	助詞,終助詞,*,*,*,*,ね,ネ,ネ
。	記号,句点,*,*,*,*,。,。,。

2. mecab-ipadic-neologd のインストール

新語に対応した NEologd 辞書(mecab-ipadic-neologd)をインストールします。

$ cd /var/lib/mecab/dic
$ sudo git clone https://github.com/neologd/mecab-ipadic-neologd.git
$ cd mecab-ipadic-neologd
$ sudo bin/install-mecab-ipadic-neologd

「/usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd」にインストールされたので、MeCab 実行時に「-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd」を渡してあげると mecab-ipadic-neologd を辞書として使うことができます。

$ mecab -d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd
霜降り明星が好きです。
霜降り明星	名詞,固有名詞,人名,一般,*,*,霜降り明星,シモフリミョウジョウ,シモフリミョウジョー
が	助詞,格助詞,一般,*,*,*,が,ガ,ガ
好き	名詞,形容動詞語幹,*,*,*,*,好き,スキ,スキ
です	助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
。	記号,句点,*,*,*,*,。,。,。
EOS

上では「霜降り明星」が一つの名詞として認識されていますが、デフォルトの辞書だと下記の様に「霜降り」と「明星」が別々の言葉として認識されています。

$ mecab
霜降り明星が好きです。
霜降り	名詞,一般,*,*,*,*,霜降り,シモフリ,シモフリ
明星	名詞,一般,*,*,*,*,明星,ミョウジョウ,ミョージョー
が	助詞,格助詞,一般,*,*,*,が,ガ,ガ
好き	名詞,形容動詞語幹,*,*,*,*,好き,スキ,スキ
です	助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
。	記号,句点,*,*,*,*,。,。,。
EOS

3. CRF++ のインストール

CRF++-0.58.tar.gz

$ cd
$ wget "https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7QVR6VXJ5dWExSTQ" -O CRF++-0.58.tar.gz
$ tar zxvf CRF++-0.58.tar.gz
$ cd CRF++-0.58
$ ./configure
$ sudo ldconfig
$ rm CRF++-0.58.tar.gz

4. CaboCha のインストール

cabocha-0.68.tar.bz2 をダウンロードします。Google Drive に配置されているので少し複雑です。

$ FILE_ID=0B4y35FiV1wh7SDd1Q1dUQkZQaUU
$ FILE_NAME=cabocha-0.69.tar.bz2
$ curl -sc /tmp/cookie "https://drive.google.com/uc?export=download&id=${FILE_ID}" > /dev/null
$ CODE="$(awk '/_warning_/ {print $NF}' /tmp/cookie)"  
$ curl -Lb /tmp/cookie "https://drive.google.com/uc?export=download&confirm=${CODE}&id=${FILE_ID}" -o ${FILE_NAME}

cabocha-0.68.tar.bz2 を解凍、インストールしていきます。

$ bzip2 -dc cabocha-0.69.tar.bz2 | tar xvf -
$ cd cabocha-0.69
$ ./configure --with-mecab-config=`which mecab-config` --with-charset=UTF8
$ make
$ make check
$ sudo make install
$ sudo ldconfig

先程の MeCab を同じ様に、コマンド「cabocha」を実行して何か文章を入力すると CaboCha が係り受けを出してくれます。

$ cabocha
今日はいい天気ですね。
      今日は---D
          いい-D
    天気ですね。
EOS

5. Pythonへのバインディング

Python の仮想環境を立ち上げた状態で下記を実行します。

$ cd python
$ python setup.py install
$ pip install mecab-python3

下記の通り Python で CaboCha が使える様になりました。

>>> import CaboCha
>>> sentence = '霜降り明星(しもふりみょうじょう)は、2018年『M-1グランプリ』14代目王者。'
>>> c = CaboCha.Parser('-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd')
>>> print(c.parseToString(sentence))
        霜降り明星-----D      
              (しも-D |      
                  ふり-D      
      みょうじょう)は、-----D
                    2018年-D |
           『M-1グランプリ』-D
                  14代目王者。
EOS

【Python】CaboCha のツリーを XML から JSON に変換する

CaboCha のツリーを扱いたいのですがデフォルトでは JSON でのアウトプットがない様なので、xmltodict を利用して XML 形式から JSON 形式に変換します。

XML での表出

まず、XML の表出は下記の様になります。

import CaboCha

c = CaboCha.Parser()

tree = c.parse('今日は天気がとても良いですね。')
xmltree = tree.toString(CaboCha.FORMAT_XML)
print(xmltree)

XML アウトプット

<sentence>
 <chunk id="0" link="3" rel="D" score="-1.359140" head="0" func="1">
  <tok id="0" feature="名詞,副詞可能,*,*,*,*,今日,キョウ,キョー">今日</tok>
  <tok id="1" feature="助詞,係助詞,*,*,*,*,は,ハ,ワ">は</tok>
 </chunk>
 <chunk id="1" link="3" rel="D" score="-1.359140" head="2" func="3">
  <tok id="2" feature="名詞,一般,*,*,*,*,天気,テンキ,テンキ">天気</tok>
  <tok id="3" feature="助詞,格助詞,一般,*,*,*,が,ガ,ガ">が</tok>
 </chunk>
 <chunk id="2" link="3" rel="D" score="-1.359140" head="4" func="4">
  <tok id="4" feature="副詞,助詞類接続,*,*,*,*,とても,トテモ,トテモ">とても</tok>
 </chunk>
 <chunk id="3" link="-1" rel="D" score="0.000000" head="5" func="7">
  <tok id="5" feature="形容詞,自立,*,*,形容詞・アウオ段,基本形,良い,ヨイ,ヨイ">良い</tok>
  <tok id="6" feature="助動詞,*,*,*,特殊・デス,基本形,です,デス,デス">です</tok>
  <tok id="7" feature="助詞,終助詞,*,*,*,*,ね,ネ,ネ">ね</tok>
  <tok id="8" feature="記号,句点,*,*,*,*,。,。,。">。</tok>
 </chunk>
</sentence>

JSON での表出

xmltodict を使うので、インストールしていない場合はコマンド「pip install xmltodict」でインストールしてください。

import CaboCha
import xmltodict
import json

c = CaboCha.Parser()

tree = c.parse('今日は天気がとても良いですね。')
xmltree = tree.toString(CaboCha.FORMAT_XML)
jsonobj = xmltodict.parse(xmltree, attr_prefix='', cdata_key='surface', dict_constructor=dict)
print(json.dumps(jsonobj, indent=2, ensure_ascii=False))

JSON アウトプット

{
  "sentence": {
    "chunk": [
      {
        "id": "0",
        "link": "3",
        "rel": "D",
        "score": "-1.359140",
        "head": "0",
        "func": "1",
        "tok": [
          {
            "id": "0",
            "feature": "名詞,副詞可能,*,*,*,*,今日,キョウ,キョー",
            "surface": "今日"
          },
          {
            "id": "1",
            "feature": "助詞,係助詞,*,*,*,*,は,ハ,ワ",
            "surface": "は"
          }
        ]
      },
      {
        "id": "1",
        "link": "3",
        "rel": "D",
        "score": "-1.359140",
        "head": "2",
        "func": "3",
        "tok": [
          {
            "id": "2",
            "feature": "名詞,一般,*,*,*,*,天気,テンキ,テンキ",
            "surface": "天気"
          },
          {
            "id": "3",
            "feature": "助詞,格助詞,一般,*,*,*,が,ガ,ガ",
            "surface": "が"
          }
        ]
      },
      {
        "id": "2",
        "link": "3",
        "rel": "D",
        "score": "-1.359140",
        "head": "4",
        "func": "4",
        "tok": {
          "id": "4",
          "feature": "副詞,助詞類接続,*,*,*,*,とても,トテモ,トテモ",
          "surface": "とても"
        }
      },
      {
        "id": "3",
        "link": "-1",
        "rel": "D",
        "score": "0.000000",
        "head": "5",
        "func": "7",
        "tok": [
          {
            "id": "5",
            "feature": "形容詞,自立,*,*,形容詞・アウオ段,基本形,良い,ヨイ,ヨイ",
            "surface": "良い"
          },
          {
            "id": "6",
            "feature": "助動詞,*,*,*,特殊・デス,基本形,です,デス,デス",
            "surface": "です"
          },
          {
            "id": "7",
            "feature": "助詞,終助詞,*,*,*,*,ね,ネ,ネ",
            "surface": "ね"
          },
          {
            "id": "8",
            "feature": "記号,句点,*,*,*,*,。,。,。",
            "surface": "。"
          }
        ]
      }
    ]
  }
}

さらに改良

上記でも JSON 形式で返ってきますが、chunk や tok 要素の中身が 1 つしかない時にリスト形式になっていない、feature がカンマ区切りの文字列(リスト形式でない)になっているなど少し不便です。

下記の様に処理を追加するとフォーマットを揃えることができます。

import CaboCha
import xmltodict
import json

c = CaboCha.Parser()

tree = c.parse('今日は天気がとても良いですね。')
xmltree = tree.toString(CaboCha.FORMAT_XML)
jsonobj = xmltodict.parse(xmltree, attr_prefix='', cdata_key='surface', dict_constructor=dict)

# 追記分 ↓
if jsonobj['sentence']: # sentence が存在する際に処理を行う
    if type(jsonobj['sentence']['chunk']) is not list: # chunk を必ずリスト形式にする
        jsonobj['sentence']['chunk'] = [jsonobj['sentence']['chunk']]
    
    for chunk in jsonobj['sentence']['chunk']:
        if type(chunk['tok']) is not list: # tok を必ずリスト形式にする
            chunk['tok'] = [chunk['tok']]
        
        for tok in chunk['tok']:
            feature_list = tok['feature'].split(',') # feature をリスト形式に変換
            tok['feature'] = feature_list
# 追記分 ↑

print(json.dumps(jsonobj, indent=2, ensure_ascii=False))

JSON アウトプット ver 2

{
  "sentence": {
    "chunk": [
      {
        "id": "0",
        "link": "3",
        "rel": "D",
        "score": "-1.359140",
        "head": "0",
        "func": "1",
        "tok": [
          {
            "id": "0",
            "feature": [
              "名詞",
              "副詞可能",
              "*",
              "*",
              "*",
              "*",
              "今日",
              "キョウ",
              "キョー"
            ],
            "surface": "今日"
          },
          {
            "id": "1",
            "feature": [
              "助詞",
              "係助詞",
              "*",
              "*",
              "*",
              "*",
              "は",
              "ハ",
              "ワ"
            ],
            "surface": "は"
          }
        ]
      },
      {
        "id": "1",
        "link": "3",
        "rel": "D",
        "score": "-1.359140",
        "head": "2",
        "func": "3",
        "tok": [
          {
            "id": "2",
            "feature": [
              "名詞",
              "一般",
              "*",
              "*",
              "*",
              "*",
              "天気",
              "テンキ",
              "テンキ"
            ],
            "surface": "天気"
          },
          {
            "id": "3",
            "feature": [
              "助詞",
              "格助詞",
              "一般",
              "*",
              "*",
              "*",
              "が",
              "ガ",
              "ガ"
            ],
            "surface": "が"
          }
        ]
      },
      {
        "id": "2",
        "link": "3",
        "rel": "D",
        "score": "-1.359140",
        "head": "4",
        "func": "4",
        "tok": [
          {
            "id": "4",
            "feature": [
              "副詞",
              "助詞類接続",
              "*",
              "*",
              "*",
              "*",
              "とても",
              "トテモ",
              "トテモ"
            ],
            "surface": "とても"
          }
        ]
      },
      {
        "id": "3",
        "link": "-1",
        "rel": "D",
        "score": "0.000000",
        "head": "5",
        "func": "7",
        "tok": [
          {
            "id": "5",
            "feature": [
              "形容詞",
              "自立",
              "*",
              "*",
              "形容詞・アウオ段",
              "基本形",
              "良い",
              "ヨイ",
              "ヨイ"
            ],
            "surface": "良い"
          },
          {
            "id": "6",
            "feature": [
              "助動詞",
              "*",
              "*",
              "*",
              "特殊・デス",
              "基本形",
              "です",
              "デス",
              "デス"
            ],
            "surface": "です"
          },
          {
            "id": "7",
            "feature": [
              "助詞",
              "終助詞",
              "*",
              "*",
              "*",
              "*",
              "ね",
              "ネ",
              "ネ"
            ],
            "surface": "ね"
          },
          {
            "id": "8",
            "feature": [
              "記号",
              "句点",
              "*",
              "*",
              "*",
              "*",
              "。",
              "。",
              "。"
            ],
            "surface": "。"
          }
        ]
      }
    ]
  }
}