ソースコードで学ぶWebプログラミング

[Python]お問い合わせフォームの作り方

お問い合わせフォームとは、サイト訪問者がサイト運営者と連絡を取るための窓口となるものです。フォーム画面は、HTMLのフォームタグで構成され、送信されたデータを受け取るWebプログラムが必要となります。今回は、そのデータを受け取るフォーム用プログラムをPython言語で作成します。

Pythonでお問い合わせフォームを作る方法

お問い合わせフォームには、どのような機能が必要となるか洗い出してみます。まず連絡を取り合うために、フォームから送信者のメールアドレスを受け取れるようにします。また送信先は、プログラム内で設定できるようにします。

1.データ「件名、送信者名、送信者アドレス、本文」を受け取る ・POSTリクエストで受け取る 2.データ「件名、送信者名、送信者アドレス、本文」を送信データに変換する ・送信データは、文字コードISO-2022-JPで送信する ・件名には、日本語を含める ・送信者名には、日本語を含める ・宛先には、日本語を含める 3.送信データを出力する ・指定アドレスに送信する

要件毎に送信するメール文章をテンプレート化しておく方法もありますが、今回は問い合わせのみとして、プログラム内に直接設定する構成にします。

Pythonで同サーバからメールを送信する方法

Pythonで、sendmailコマンドからメールを送信するには、subprocessモジュールのPopenが利用できます。メールの件名や宛先の名前に日本語を使用したい場合は、email.headerモジュールを使用します。

#!/usr/bin/python3 from email.mime.text import MIMEText from email.header import Header from subprocess import Popen, PIPE # sendmailのパス SENDMAIL = '/usr/sbin/sendmail' # 管理者メールアドレス ADMIN_MAIL = '***' def send_mail(s): if 'from_name' in s: s['from'] = "%s <%s>" % (Header(s['from_name'],'ISO-2022-JP').encode(),s['from']) if 'to_name' in s: s['to'] = "%s <%s>" % (Header(s['to_name'],'ISO-2022-JP').encode(),s['to']) msg = MIMEText(s['body'], 'plain', 'ISO-2022-JP') msg['From'] = s['from'] msg['To'] = s['to'] msg['Subject'] = Header(s['sub'],'ISO-2022-JP').encode() p = Popen([SENDMAIL, '-t'], stdin=PIPE, universal_newlines=True) p.communicate(msg.as_string()) # 送信サンプル s = { "to":ADMIN_MAIL, "to_name":"受信者", "from":ADMIN_MAIL, "from_name":"送信者", "sub":"件名", "body":"メール本文" } send_mail(s)

動作チェック用のコードも載せておきます。入力エラーの時、エラー用のURLへ飛ばし、送信後は完了用のURLへ飛ばしています。Pythonでは、標準ライブラリではドメインチェックを行えません。今回は正規表現で簡易的なチェックのみ行います。

import os import sys import re import cgi_decode cgi_decode.Set() # GET,POST,COOKIE,FILES が使えるように # フォームから送信があった時 if os.environ.get('REQUEST_METHOD')=='POST': send = POST.get('from','') name = POST.get('name','') sub = POST.get('sub','') body = POST.get('body','') # メールドメインの確認 簡易チェック domain = False m = re.search('@[a-zA-Z0-9\-\.]+\.[a-zA-Z]+', send) if m: domain = True # お名前、メールアドレスが空欄、ドメインが存在しない場合エラー if name=='' or send=='' or domain==False: print('Status: 301 Moved Permanently') print('Location: '+os.environ.get('SCRIPT_NAME')+"?result=error\n") sys.exit() body = '''お名前:{} メールアドレス:{} お問い合わせ内容: {} '''.format(name,send,body) # 管理者へメール body1 = '''下記の問い合わせがありました。 '''+body s = { 'to':ADMIN_MAIL, 'to_name':'管理者', 'from':send, 'from_name':name, 'sub':sub, 'body':body1 } send_mail(s) # 送信者へメール body2 = '''下記の送信を行いました。 '''+body s = { 'to':send, 'to_name':name, 'from':ADMIN_MAIL, 'from_name':'自動返信', 'sub':'[送信控え]'+sub, 'body':body2 } send_mail(s) print('Status: 301 Moved Permanently') print('Location: '+os.environ.get('SCRIPT_NAME')+"?result=success\n") sys.exit()

Pythonでは、ヒアドキュメントによりHTMLタグをプログラムソース内に記述出来ます。

print("Content-Type: text/html; charset=utf-8\n") ht = '''<html> <head> <meta charset="utf-8"> <title>[Python]お問い合わせフォーム</title> <style> table { margin: 50px auto; width: 500px; } td { padding: 5px 0; } input,select,textarea { padding: 5px; width: 100%; } textarea { height: 100px; } .required { color: red; } #caution { margin-top: 50px; text-align: center; color: #a00; } #complete { margin-top: 50px; text-align: center; color: #060; } </style> </head> <body> ''' print(ht) if GET.get('result','')=='success': ht = ''' <div id="complete">送信を実行しました。ご返信まで今しばらくお待ちください。</div> </body> </html> ''' print(ht) sys.exit() elif GET.get('result','')=='error': print('<div id="caution">必須事項をご入力ください</div>') ht = ''' <form method="post"> <table> <tr> <th>件名</th> <td> <select name="sub"> <option value="資料のご請求">資料のご請求</option> <option value="お申込み">お申込み</option> <option value="お問い合わせ">お問い合わせ</option> </select> </td> </tr> <tr> <th>お名前<span class="required">*</span></th> <td> <input type="text" name="name"> </td> </tr> <tr> <th>メールアドレス<span class="required">*</span></th> <td> <input type="text" name="from"> </td> </tr> <tr> <th>お問い合わせ内容</th> <td> <textarea name="body"></textarea> </td> </tr> <tr> <td colspan="2"><input type="submit" value="送信"></td> </tr> </form> </body> </html> ''' print(ht)

Pythonで別サーバからメールを送信する方法

別サーバにあるメールサーバから送信したい場合、SMTPサーバに接続して送信する事になります。Pythonでは、標準ライブラリのsmtplibを利用できます。

#!/usr/bin/python3 import smtplib from email.mime.text import MIMEText from email.header import Header # SMTPサーバ MAIL_HOST = '***' # 接続ユーザ MAIL_USER = '***' # パスワード MAIL_PASS = '***' # ポート番号 MAIL_PORT = 587 def send_mail(s): if 'from_name' in s: s['from'] = "%s <%s>" % (Header(s['from_name'],'ISO-2022-JP').encode(),s['from']) if 'to_name' in s: s['to'] = "%s <%s>" % (Header(s['to_name'],'ISO-2022-JP').encode(),s['to']) msg = MIMEText(s['body'], 'plain', 'ISO-2022-JP') msg['From'] = s['from'] msg['To'] = s['to'] msg['Subject'] = Header(s['sub'],'ISO-2022-JP').encode() p = smtplib.SMTP(MAIL_HOST, MAIL_PORT) p.ehlo() p.starttls() p.ehlo() p.login(MAIL_USER, MAIL_PASS) p.send_message(msg) p.close() # 送信サンプル s = { "to":MAIL_USER, "to_name":"受信者", "from":MAIL_USER, "from_name":"送信者", "sub":"件名", "body":"メール本文" } send_mail(s)