Symfoware

Symfowareについての考察blog

PythonからMariaDB(MySQL)に接続する(mysql-connector-python)

PythonからMariaDB 10に接続してみます。
以前はMySQLdbを使用していたのですが、今回はmysql-connector-pythonを試してみます。

https://pypi.python.org/pypi/mysql-connector-python
https://dev.mysql.com/doc/connector-python/en/


Pythonを動かす端末はUbuntu 16.04。
MariaDBが動いているサーバーはFreeBSD 11.0 + MariaDB 10.1です。

ここで使用した環境です。
http://symfoware.blog68.fc2.com/blog-entry-1966.html



pipによるインストール



pipをインストールしていない場合はインストール。
続いて、mysql-connector-pythonをインストールします。


$ sudo apt install python-pip
$ sudo pip install mysql-connector




mysql.connectorをimport出来るか試してみます。


$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mysql.connector
>>>







接続サンプル



MariaDB側には「test」データベースに「sample」テーブルを作成済です。


  1. create table sample(
  2.     id int,
  3.     val varchar(100)
  4. );




接続情報は以下の通り。


server ip:192.168.1.101
id:admin
password:P@ssw0rd





データベースに接続し、登録や検索を行うサンプルはこんな感じになります。


  1. # -*- coding:utf-8 -*-
  2. import mysql.connector
  3. # データベース接続
  4. con = mysql.connector.connect(
  5.     host='192.168.1.101',
  6.     db='test',
  7.     user='admin',
  8.     passwd='P@ssw0rd'
  9. )
  10. # 辞書型カーソル取得
  11. cur = con.cursor(dictionary=True)
  12. # データの削除
  13. cur.execute('delete from sample')
  14. # 登録(すっぴん)
  15. cur.execute("insert into sample (id, val) values (1, 'テスト1')")
  16. # 登録(プレースフォルダ)
  17. cur.execute("insert into sample (id, val) values (%s, %s)", [2, 'テスト2'])
  18. # 登録(一括)
  19. insert_values = [
  20.     [3, 'テスト3'],
  21.     [4, 'テスト4'],
  22.     [5, 'テスト5']
  23. ]
  24. cur.executemany("insert into sample (id, val) values (%s, %s)", insert_values)
  25. # コミットして変更を確定
  26. con.commit()
  27. # 検索
  28. cur.execute("select * from sample")
  29. # 表示
  30. for row in cur:
  31.     print("id:%d, val:%s" % (row['id'], row['val']))
  32. # 切断
  33. cur.close()
  34. con.close()




カーソル取得時、dictionary=Trueとすることで、フィールド名をキーとした辞書型でデータが取り出せます。
これを指定していないと配列でのデータ取得となるため、
row[0], row[1]のような指定でデータを参照することになります。

自動的にトランザクションが開始されているため、明示的にcommitしないと
変更が確定しません。


実行結果


$ python sample.py
id:1, val:テスト1
id:2, val:テスト2
id:3, val:テスト3
id:4, val:テスト4
id:5, val:テスト5







データ取得方法あれこれ



selectを実行した後のカーソルはそのままイテレートできます。


  1. # -*- coding:utf-8 -*-
  2. import mysql.connector
  3. # データベース接続
  4. con = mysql.connector.connect(
  5.     host='192.168.1.101',
  6.     db='test',
  7.     user='admin',
  8.     passwd='P@ssw0rd'
  9. )
  10. # 辞書型カーソル取得
  11. cur = con.cursor(dictionary=True)
  12. # 検索
  13. cur.execute("select * from sample")
  14. # 表示
  15. for row in cur:
  16.     print("id:%d, val:%s" % (row['id'], row['val']))





fetchoneで先頭のレコードを取り出せます。


  1. # -*- coding:utf-8 -*-
  2. import mysql.connector
  3. # データベース接続
  4. con = mysql.connector.connect(
  5.     host='192.168.1.101',
  6.     db='test',
  7.     user='admin',
  8.     passwd='P@ssw0rd'
  9. )
  10. # 辞書型カーソル取得
  11. cur = con.cursor(dictionary=True)
  12. # 検索
  13. cur.execute("select * from sample")
  14. # 最初の行を取得
  15. row = cur.fetchone()
  16. # 表示
  17. print("id:%d, val:%s" % (row['id'], row['val']))




$ python sample.py
id:1, val:テスト1




fetchoneすると読み込む行が1つ進みます。
次の行がない状態でfetchoneすると「None」になります。

fetchoneしながらすべての行を読み取るプログラムは
こんな感じになります。


  1. # -*- coding:utf-8 -*-
  2. import mysql.connector
  3. # データベース接続
  4. con = mysql.connector.connect(
  5.     host='192.168.1.101',
  6.     db='test',
  7.     user='admin',
  8.     passwd='P@ssw0rd'
  9. )
  10. # 辞書型カーソル取得
  11. cur = con.cursor(dictionary=True)
  12. # 検索
  13. cur.execute("select * from sample")
  14. # 最初の行を取得
  15. row = cur.fetchone()
  16. # データが取得できている間はループ
  17. while row:
  18.     # 表示
  19.     print("id:%d, val:%s" % (row['id'], row['val']))
  20.     # 次の行を読み取り
  21.     row = cur.fetchone()




$ python sample.py
id:1, val:テスト1
id:2, val:テスト2
id:3, val:テスト3
id:4, val:テスト4
id:5, val:テスト5




fetchallですべての行を変数に代入できます。


  1. # -*- coding:utf-8 -*-
  2. import mysql.connector
  3. # データベース接続
  4. con = mysql.connector.connect(
  5.     host='192.168.1.101',
  6.     db='test',
  7.     user='admin',
  8.     passwd='P@ssw0rd'
  9. )
  10. # 辞書型カーソル取得
  11. cur = con.cursor(dictionary=True)
  12. # 検索
  13. cur.execute("select * from sample")
  14. # すべての行を取得
  15. rows = cur.fetchall()
  16. for row in rows:
  17.     # 表示
  18.     print("id:%d, val:%s" % (row['id'], row['val']))




$ python sample.py
id:1, val:テスト1
id:2, val:テスト2
id:3, val:テスト3
id:4, val:テスト4
id:5, val:テスト5




テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/03/23(木) 22:48:03|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Python webサーバー、フレームワークを使用せずにwebアプリ作成

個人的なツール用として簡単なwebアプリを作成したかったのですが、
なんとか素のPythonだけで実装できないか考えてみました。


BaseHTTPServer,SimpleHTTPServer



Python 2系の場合、BaseHTTPServerが標準で組み込まれています。
※Python 3系ではhttp.server

これらを使用すれば良さそうです。

作成するwebアプリでは、htmlやjsファイルは通常通りget。
javascriptからのデータ取得はPOSTのみで行うことにし、
実装を簡単にしました。



POSTデータの解析



POSTデータの解析をどうやれば良いかわからず探したところ、
このドキュメントが参考になりました。

BaseHTTPServer – web サーバを実装するベースクラス

cgi.FieldStorageを使用すれば解析できそうです。



サンプルアプリケーション



アプリケーションは
・index.html
・app.js
・view.py
の3つのファイルで構成しました。

名前を入力すると、応答してくれる簡単なものです。

731_01.png


・index.html


  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>Simple Web</title>
  6.     <script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  7.     <script type="text/javascript" src="./static/js/app.js"></script>
  8. </head>
  9. <body>
  10. <h3>Pythonのみで簡易Webアプリ</h3>
  11. <input type="text" id="name">
  12. <input type="button" id="echo" value="ajaxでデータ取得">
  13. <div id="result"></div>
  14. </body>
  15. </html>




・app.js


  1. $(function() {
  2.     
  3.     // 入力された値をPOSTで送信
  4.     // 応答を表示する
  5.     $('#echo').on('click', function(){
  6.         var name = $('#name').val();
  7.         $.ajax({
  8.             type: 'POST',
  9.             dataType: 'json',
  10.             data: {'name':name},
  11.             url: 'echo',
  12.         }).done(function (data) {
  13.             $('#result').html(data.message);
  14.         });
  15.     });
  16.     
  17. });




・view.py


  1. # -*- coding: utf-8 -*-
  2. import cgi
  3. import json
  4. import BaseHTTPServer
  5. import SimpleHTTPServer
  6. class MyHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
  7.     
  8.     # POSTの実装(GETは継承元にある)
  9.     def do_POST(self):
  10.         
  11.         # リクエストに対応したメソッドを呼び出す
  12.         route = self.path.split('/')[-1]
  13.         if not hasattr(self, route):
  14.             self.send_response(500)
  15.             self.end_headers()
  16.             return
  17.         
  18.         # POSTデータの解析
  19.         form = self._parse_form()
  20.         response = getattr(self, route)(form)
  21.         
  22.         # レスポンス作成
  23.         self.send_response(200)
  24.         self.send_header("Content-type", 'application/json')
  25.         self.send_header("Content-Length", len(response))
  26.         self.end_headers()
  27.         self.wfile.write(response)
  28.         
  29.         
  30.     def _parse_form(self):
  31.         if 'Content-Type' not in self.headers:
  32.             return None
  33.         
  34.         # POSTデータがあれば内容を解析する
  35.         return cgi.FieldStorage(
  36.             fp=self.rfile,
  37.             headers=self.headers,
  38.             environ={
  39.                 'REQUEST_METHOD':'POST',
  40.                 'CONTENT_TYPE':self.headers['Content-Type'],
  41.             }
  42.         )
  43.     
  44.         
  45.         
  46.     # --- router
  47.     def echo(self, form):
  48.         
  49.         name = u'名無し'
  50.         
  51.         # データが送信されていれば、内容を応答
  52.         if 'name' in form:
  53.             name = form['name'].value
  54.         
  55.         message = u'%sさんこんにちは' % name
  56.         data = {'message' : message}
  57.         return json.dumps(data)
  58.     
  59.     
  60. if __name__ == '__main__':
  61.     
  62.     server_address = ('0.0.0.0', 8000)
  63.     httpd = BaseHTTPServer.HTTPServer(server_address, MyHandler)
  64.     print('Serving HTTP on 0.0.0.0 port %d ...' % server_address[1])
  65.     print('use <Ctrl-(C or break)> to stop')
  66.     httpd.serve_forever()
  67.     





$ python view.py

と実行して、http://localhost:8000にアクセスします。

731_02.png


適当な文字列を入力してボタンをクリックすると、応答が得られました。

731_03.png


なんとかPython単独でwebアプリケーションが作成できそうです。



【参考URL】

SimpleHTTPServer — 簡潔な HTTP リクエストハンドラ
BaseHTTPServer – web サーバを実装するベースクラス

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/01/30(月) 23:53:09|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Python Windows で serve_foreverの実行がCtrl + Cで停止しない

例えばこんなプログラム。


  1. # -*- coding:utf-8 -*-
  2. import BaseHTTPServer
  3. import SimpleHTTPServer
  4. server_address = ('', 8000)
  5. handler = SimpleHTTPServer.SimpleHTTPRequestHandler
  6. httpd = BaseHTTPServer.HTTPServer(server_address, handler)
  7. httpd.serve_forever()




実行後、ブラウザで「http://localhost:8000/」にアクセスすると、
実行しているディレクトリの内容が表示されます。


Windowsで実行時、プログラムをCtrl + Cで停止しようとしても止まってくれない。

Stopping python using ctrl+c

ここを参考に、Ctrl + Breakで停止できました。


テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/01/26(木) 00:01:36|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Python YouTubeの動画をダウンロード(pytube,Pafy)

PythonでYouTubeの動画をダウンロードする方法を調べたところ、
pytubeとPafyというライブラリが有名なようです。

両方触ってみます。




pytube



こちらを参考にしました。
PythonでYouTubeの動画を自動的に検索ダウンロードする

ソースはこちら。
https://github.com/NFicano/pytube

easy_installでインストールしました。


# easy_install pytube




サンプルはこのようになります。


  1. # -*- coding:utf-8 -*-
  2. from pytube import YouTube
  3. yt = YouTube('https://www.youtube.com/watch?v=0E00Zuayv9Q')
  4. # ダウンロードできる形式を表示
  5. for video in yt.get_videos():
  6.     print video
  7. print '-' * 10
  8. # ファイル名を表示
  9. print(yt.filename)
  10. print '-' * 10
  11. # ダウンロードしたい形式を選択
  12. video = yt.get('mp4', '720p')
  13. # ダウンロードするファイル名を指定
  14. yt.set_filename('download_pytube')
  15. # ダウンロード実行
  16. video.download('./')




実行結果


# python sample.py
<Video: MPEG-4 Visual (.3gp) - 144p - Simple>
<Video: MPEG-4 Visual (.3gp) - 240p - Simple>
<Video: H.264 (.mp4) - 360p - Baseline>
<Video: H.264 (.mp4) - 720p - High>
<Video: VP8 (.webm) - 360p - N/A>
----------
PPAP(Pen-Pineapple-Apple-Pen Official)ペンパイナッポーアッポーペン/PIKOTARO(ピコ太郎)
----------




set_filenameでファイル名を指定していない場合は、元のファイル名
(yt.filenameで取得できた名称)で保存されました。



プログラムを記載しなくても、pytubeというコマンドに引数を指定することで
動画のダウンロードが行えます。


-e 動画形式[mp4]
-r 動画サイズ[720p]
-f ファイル名[down.mp4]
-p ダウンロードフォルダ[./Download]




mp4,720p,ファイル名down.mp4でダウンロードする場合はこんな感じになります。
※ファイルの拡張子は自動的に付与されるようです。


# pytube -e mp4 -r 720p -f down https://www.youtube.com/watch?v=0E00Zuayv9Q








Pafy



こちらを参考にしました。
pythonでyoutubeをナニするPafyがすごくべんり

ソースはこちら。
https://github.com/mps-youtube/pafy

easy_install でインストールしました。


# easy_install pafy




インストール後、importすると警告が表示されました。


>>> import pafy
WARNING:root:pafy: youtube-dl not found; falling back to internal backend.
This is not as well maintained as the youtube-dl backend.
To hide this message, set the environmental variable PAFY_BACKEND to "internal".




youtube-dlも合わせてインストールしておきました。


# easy_install youtube-dl





pytubeと同様のコードはこちら。


  1. # -*- coding:utf-8 -*-
  2. import pafy
  3. video = pafy.new('https://www.youtube.com/watch?v=0E00Zuayv9Q')
  4. # ダウンロードできる形式を表示
  5. for s in video.streams:
  6.     #print(s.resolution, s.extension, s.get_filesize(), s.url)
  7.     print(s.resolution, s.extension)
  8. print '-' * 10
  9. # ファイル名を表示
  10. print(video.title)
  11. print '-' * 10
  12. # 指定した形式で、一番高画質なものを選択
  13. best = video.getbest(preftype="mp4")
  14. print(best.resolution, best.extension)
  15. # ダウンロード
  16. best.download(filepath="./")




pytubeと同様、ytdlコマンドで操作が可能です。

とにかく一番よい画質の動画をダウンロードしたい場合


# ytdl -b "https://www.youtube.com/watch?v=0E00Zuayv9Q"





形式を指定してダウンロードしたい場合は一旦ストリームの情報を取得
※引数はyoutbueのURLのvパラメーター


# ytdl 0E00Zuayv9Q
Stream Type    Format Quality         Size            
------ ----    ------ -------         ----            
1     normal 3gp    [176x144]        0 MB        
2     normal 3gp    [320x180]        1 MB        
3     normal webm [640x360]        5 MB        
4     normal mp4    [640x360]        4 MB        
5     normal mp4    [1280x720]     10 MB        
6     audio m4a    [128k]         1 MB




ストリームの番号を指定してダウンロードします。
以下の指定で、4番(640x360のmp4)をダウンロード。


# ytdl -n4 0E00Zuayv9Q





【参考URL】

PythonでYouTubeの動画を自動的に検索ダウンロードする

https://github.com/NFicano/pytube

pythonでyoutubeをナニするPafyがすごくべんり

https://github.com/mps-youtube/pafy


テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/01/23(月) 23:55:46|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

OpenCV 3.2をDebian 8にインストールする

OpenCV
2017.1.22時点で最新版の3.2をDebian 8にインストールしてみます。



インストールスクリプト



ソースからビルドしてインストールします。
・・・が依存しているライブラリが多く、インストールは結構面倒なようです。

調べてみると、親切な方がインストールスクリプトを公開してくださっています。
http://milq.github.io/install-opencv-ubuntu-debian/

これを使わせていただくことにしました。


まず、実行に必要なライブラリをインストール。


# apt-get install sudo wget




apt版のopencvがインストールされている場合は、事前に削除しておきます。


# apt-get autoremove libopencv-dev python-opencv




インストールスクリプトをダウンロードして実行。


# cd /usr/local/src/
# wget --no-check-certificate https://raw.githubusercontent.com/milq/scripts-ubuntu-debian/master/install-opencv.sh
# chmod +x install-opencv.sh
# ./install-opencv.sh



これでインストール完了です。
※私の環境では、インストールに20分程度必要でした




Pythonから呼び出しとバージョン確認



Python2からcv2をインポート。
バージョンを確認してみます。


# python
Python 2.7.9 (default, Jun 29 2016, 13:08:31)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'3.2.0'




Python3も同様に試してみます。


# python3
Python 3.4.2 (default, Oct 8 2014, 10:45:20)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'3.2.0'




ちゃんとインポートできていますね。


テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/01/22(日) 22:40:15|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
次のページ