このブログを検索

ラベル python3 の投稿を表示しています。 すべての投稿を表示
ラベル python3 の投稿を表示しています。 すべての投稿を表示

2020/06/06

さくらのVPSにcentos8をインストールして最初にしたこと

まず、さくらのVPSのコントロールパネルで、「パケットフィルタ」というファイアウォール的な設定があったのでSSH(カスタム)とWEBを開放したのだが、
これって、centosのfirewallのさらに外側の設定だよね?

二重管理になるから嫌だな.... 

でも、開放ポートを設定するようになっているから、
centosのFirewallで設定するようにするなら全開放にするってことか。
それもヤダな....

まあ、あとで考える。


さて、やったこと。

hostnameの変更

hostnamectlコマンド

sshd.confの設定変更
・ポート番号変更
・PermitRootLogin を noに

httpdのインストール(dnfで)


python3は最初から入っているのかと思ったら入ってなかった。
(たしかconohaは入ってた)

python3のインストール(dnfで)

python3とpip3を、それぞれ「python」「pip」で呼べるように変更

・sudo alternatives --config python を実行し、python3を選ぶ
・sudo update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1

コントロールパネルで、OS再インストールしたら「帯域制限中」と表示されていたのに気づいたのだがいつのまにか消えた。
OSをインストール直後はこうなるのかな。

2020/02/16

django

pythonのcgiでdbにアクセスできるようになった。
さあ、dbを使ってちょっとしたアプリケーションを作ってみたいが、
何をするにもサービスにログインする仕組みは必要だろう。
以前からログインの仕組みをやりたいと思っていた。
しらべるとdjangoを使った方法が紹介されていたので、
まずdjangoを使ってみる。

centos8, python3が前提


pip intall django

以下は適当な場所にフォルダを作り、そこで実行した。

プロジェクトの作成
# django-admin startprojects myproject

#cd myproject

アプリケーションの作成
#python manage.py startapp myapp

myapp/views.py を編集

from django.shortcuts import render

# Create your views here.

from django.http import HttpResponse

def index(request):
        return HttpResponse("Hello")


myproject/urls.py を編集、
import myapp.views を追加、
最後のところに作成したアプリケーションへのpathを追加

from django.contrib import admin
from django.urls import path
import myapp.views

urlpatterns = [
    path('admin/', admin.site.urls),
    path(r'', myapp.views.index, name='index')
]


myproject/myproject/settigs.py

にアクセスを許可するホスト名を追加する

ALLOWED_HOSTS = ['*']
で、なんでも許可

デフォルトは何も設定されていないので必ずエラーになる。

プロジェクトフォルダにある manage.pyを使って
migrate(設定の反映みたいなもの?)を実行

python manage.py migrate


アプリケーションを実行
xx.xx.xx.xxはサーバのグローバルIPアドレス
アドレスを指定しないと127.0.0.1になり、外部からアクセスできない。

python manage.py runserver xx.xx.xx.xx:8000


fierwall-cmdでtcp8000を開ける。

http://www.example.com:8000
にアクセス

Hello
と表示される。











2020/02/15

python3のcgiでpostgresqlのデータを参照する @CentOS8

pythonからpostgresqlを使うためのライブラリとして psycopg2というものがよく使われているようである。 

エラーが出ては足りないものをインストールした結果、 以下が必要であった。
dnf install postgresql-devel
dnf install gcc
dnf install python3-devel
pip install psycopg2

pythonでcgiが動くことはすでに確認済み。 
OSはCentOS8、pythonは3.6.8である。 

以下がpostgresqlのDBに登録されている内容を表示するcgiの例である。 

ローカル(cgiを実行しているサーバ)にある、 
monqy というデータベースの、 usersというテーブルに登録されているレコードの、 nameという項目の内容を、すべて表示する。
   
#!/usr/bin/python

import cgi
import psycopg2
import psycopg2.extras
import os

path = "localhost"
port = "5432"
dbname = "monqy"
user = "postgres"
password = "hogehoge"

pg_params = "host={} port={} dbname={} user={} password={}"
pg_params = pg_params.format(path,port,dbname,user,password)

sql = """select * from users"""

print('Content-Type: text/html; charset=utf-8')
print('')
print('')

connection = psycopg2.connect(pg_params)
cur = connection.cursor(cursor_factory=psycopg2.extras.DictCursor)
cur.execute(sql)

results = cur.fetchall()
for row in results:
        print(row['name'])
        print("
") cur.close connection.close print("")
この例ではDBの内容を辞書形式で取得することによって、項目名で値を取り出している。 

せっかくDBを使っているのに名前を使わないなんてわざわざライブラリを使う意味がないだろうから辞書形式で取得するのは必須だろう。

systemctl status を実行したら degrated と表示された @CentOS7

CentOS7の話

以前さくらのVPSでmysqlをインストールしてちょっと使ってみたことがあったのだが、
久しぶりにDBをいじってみたいと思い、mysqlが起動しているか確認するために

systemctl status

を実行したら、赤字で

State: degrated

と表示された。


うわ!と思い、検索すると起動に失敗したサービスがある場合にそうなるらしいことがわかった。

きっと使ってないしょうもないサービスだろうから無効にしようと思い、

systemctl --failed

を実行すると

● firewalld.service loaded failed failed firewalld - dynamic firewall daemon


firewalldが起動していなかった。

さすがにそれはマズいだろうとちょっと焦ってなんでだろうと調べた結果思い当たったのは、しばらく前にpythonのシンボリックリンクを3系向けに変更したことだった。

それを変更したのはpythonで書いたcgiが動かなくなったからだったのだが、
firewallが起動しないことの方が問題なのでとりあえずシンボリックリンクを2系向けに戻した。

firewalldは起動するようになり、cgiはエラーになった。

cgiの1行目(これなんて言うんだっけ)を

#!/bin/python3.6

に直す。

これでcgiも動くようになった。

pythonのデフォルトバージョンが2系になってしまったが、
コマンドでpythonを実行することはあまりないのでいいか.....

それにしてもpythonの2系・3系問題はウザいね.....

CentOS8はみんなpython3系になっているようなのでこういうことは起こらないみたい。

で、本来確認したかったmysqlは動いてなかった。

2019/06/22

さくらのVPSを1台解約するにあたって移行

2台もいらない。
低スペックの方を残す。

よく使うcgiと、メールと、twitter botと、それぐらいしか使わないから。

centos6からcentos7への移行となる。

途中で気づいたがpythonも2.7から3.6の移行となる。

python3系にするとyumでエラーになる。
yumは2系を前提としているからだ。

/bin/yum
を直すのは以前にもやった。

mod_sslをインストールしようとしたら、

Downloading packages:
  File "/usr/libexec/urlgrabber-ext-down", line 28
    except OSError, e:
                  ^
SyntaxError: invalid syntax

なんてエラーも出たので
/usr/libexec/urlgrabber-ext-down
も直す。

こんなことでいいのかな。

以前centos6でやったhttpsを使う設定をしていき、
最後にfirewallで443を開けるところまで来て、
そういえば7はiptableじゃない....

いまどうなってるかな...
firewall-cmd --list-all-zones

とやると、エラーになる。
これもpython2系にしないとダメだ。

どいつもこいつもpythonを使っていて、しかも2系なんだな...
3系にするのは先走りなのか...

サービスで開ける。

firewall-cmd --add-service=https --zone=public
firewall-cmd --add-service=https --zone=public --permanent
firewall-cmd --reload

終わり。


2019/04/18

python3のcgiでUnicodeEncodeError

腹立つなァ....

python3のcgiで日本語を表示させたらページが真っ白に。

ログを見たら、

UnicodeEncodeError: 'ascii' codec can't encode characters in position...

python2の時はちゃんと動いていたのに。


いろいろ調べた結果、
下記を追加して動いた。

#!/usr/bin/python
import sys #↓以下2行を追加 import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') print( "Content-Type: text/html") print() print('糞野郎')
(参考)
http://lab.knightstyle.info/%E7%A7%81%E3%81%8Cpython3%E3%81%A7unicodeencodeerror%E3%81%AA%E3%81%AE%E3%81%AF%E3%81%A9%E3%81%86%E8%80%83%E3%81%88%E3%81%A6%E3%82%82%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E6%96%87%E5%AD%97/

pip install mecab-python3 が失敗する

腹立つなァ....

検索してみるとみんな苦労しているようだが、
エラー内容もその対応も様々。



# pip install mecab-python3
Collecting mecab-python3
  Using cached https://files.pythonhosted.org/packages/ac/48/295efe525df40cbc2173748eb869290e81a57e835bc41f6d3834fc5dad5f/mecab-python3-0.996.1.tar.gz
Installing collected packages: mecab-python3
  Running setup.py install for mecab-python3 ... error
    Complete output from command /usr/bin/python3.6 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-hzcdo768/mecab-python3/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-record-5w7so2s3/install-record.txt --single-version-externally-managed --compile:
    /usr/lib64/python3.6/distutils/dist.py:261: UserWarning: Unknown distribution option: 'long_description_content_type'
      warnings.warn(msg)
    running install
    running build
    running build_py
    running build_ext
    building '_MeCab' extension
    swigging MeCab.i to MeCab_wrap.cpp
    swig -python -shadow -c++ -I/usr/local/include -o MeCab_wrap.cpp MeCab.i
    /usr/local/include/mecab.h:848: Warning(302): Identifier 'set_sentence' redefined by %extend (ignored),
    MeCab.i:88: Warning(302): %extend definition of 'set_sentence'.
    creating build
    creating build/temp.linux-x86_64-3.6
    gcc -pthread -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I/usr/local/include -I/usr/include/python3.6m -c MeCab_wrap.cpp -o build/temp.linux-x86_64-3.6/MeCab_wrap.o
    MeCab_wrap.cpp: In function ‘swig_module_info* SWIG_Python_GetModule()’:
    MeCab_wrap.cpp:2452: error: ‘PyCObject_Import’ was not declared in this scope
    MeCab_wrap.cpp: In function ‘void SWIG_Python_SetModule(swig_module_info*)’:
    MeCab_wrap.cpp:2521: error: ‘PyCObject_FromVoidPtr’ was not declared in this scope
    MeCab_wrap.cpp:2512: 警告: unused variable ‘swig_empty_runtime_method_table’
    MeCab_wrap.cpp: In function ‘swig_type_info* SWIG_Python_TypeQuery(const char*)’:
    MeCab_wrap.cpp:2544: error: ‘PyCObject_AsVoidPtr’ was not declared in this scope
    MeCab_wrap.cpp:2549: error: ‘PyCObject_FromVoidPtr’ was not declared in this scope
    error: command 'gcc' failed with exit status 1

    ----------------------------------------
Command "/usr/bin/python3.6 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-hzcdo768/mecab-python3/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-record-5w7so2s3/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-install-hzcdo768/mecab-python3/


ログを見てみる。

#### # pip install mecab-python3

実行したコマンド。
コマンドがないとかいうエラーはない。

#### Collecting mecab-python3
####
####   Using cached https://files.pythonhosted.org/packages/ac/48/295efe525df40cbc2173748eb869290e81a57e835bc41f6d3834fc5dad5f/mecab-python3-0.996.1.tar.gz


このtar.gzファイルをダウンロードしてインストールしているようだ。

#### Installing collected packages: mecab-python3
####
####   Running setup.py install for mecab-python3 ... error

で、setup.pyが error になっている。




####     Complete output from command /usr/bin/python3.6 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-hzcdo768/mecab-python3/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-record-5w7so2s3/install-record.txt --single-version-externally-managed --compile:

以下が setup.pyのエラーの詳細かな。

####
####     /usr/lib64/python3.6/distutils/dist.py:261: UserWarning: Unknown distribution option: 'long_description_content_type'

これはワーニング

####
####       warnings.warn(msg)
####
####     running install
####
####     running build
####
####     running build_py
####
####     running build_ext
####
####     building '_MeCab' extension
####
####     swigging MeCab.i to MeCab_wrap.cpp
####
####     swig -python -shadow -c++ -I/usr/local/include -o MeCab_wrap.cpp MeCab.i


「swigがインストールされていない」という人がいたが、swigはインストールされている。

####
####     /usr/local/include/mecab.h:848: Warning(302): Identifier 'set_sentence' redefined by %extend (ignored),

これもワーニング

####
####     MeCab.i:88: Warning(302): %extend definition of 'set_sentence'.

これもワーニング

####
####     creating build
####

buildを作成

####     creating build/temp.linux-x86_64-3.6
####
####     gcc -pthread -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I/usr/local/include -I/usr/include/python3.6m -c MeCab_wrap.cpp -o build/temp.linux-x86_64-3.6/MeCab_wrap.o

gccを呼び出し

####
####     MeCab_wrap.cpp: In function ‘swig_module_info* SWIG_Python_GetModule()’:
####
####     MeCab_wrap.cpp:2452: error: ‘PyCObject_Import’ was not declared in this scope


エラー。PyCObject_Import が宣言されていない。

####
####     MeCab_wrap.cpp: In function ‘void SWIG_Python_SetModule(swig_module_info*)’:
####
####     MeCab_wrap.cpp:2521: error: ‘PyCObject_FromVoidPtr’ was not declared in this scope

エラー。PyCObject_FromVoidPtr が宣言されていない。

####
####     MeCab_wrap.cpp:2512: 警告: unused variable ‘swig_empty_runtime_method_table’

警告。未使用の変数。

####
####     MeCab_wrap.cpp: In function ‘swig_type_info* SWIG_Python_TypeQuery(const char*)’:
####
####     MeCab_wrap.cpp:2544: error: ‘PyCObject_AsVoidPtr’ was not declared in this scope

エラー。PyCObject_FromVoidPtr が宣言されていない。

####
####     MeCab_wrap.cpp:2549: error: ‘PyCObject_FromVoidPtr’ was not declared in this scope

エラー。PyCObject_FromVoidPtr が宣言されていない。

####
####     error: command 'gcc' failed with exit status 1

gccが失敗した。

####
####
####
####     ----------------------------------------
####
#### Command "/usr/bin/python3.6 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-hzcdo768/mecab-python3/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-record-5w7so2s3/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-install-hzcdo768/mecab-python3/
####
####
####

違うエラーなのだが、「setup.pyがpython3に対応していない」という人がいる。
多分そんなところだろう。

setup.pyはどこにあるのか。
探すと...

/home/monqy/mecab/mecab/python/setup.py

これはmecab本体かな。

/home/monqy/mecab-python-0.996/setup.py

こっちか。

setup.pyを実行してみるとエラーになる。オプションが必要のようだ。

ログをもう一度見てみると

Complete output from command
/usr/bin/python3.6 -u -c "import setuptools, tokenize;

__file__='/tmp/pip-install-hzcdo768/mecab-python3/setup.py';

f=getattr(tokenize, 'open', open)(__file__);

code=f.read().replace('\r\n', '\n');

f.close();

exec(compile(code, __file__, 'exec'))"

install --record /tmp/pip-record-5w7so2s3/install-record.txt
--single-version-externally-managed
--compile:

多分、最初の方にあるURLからファイルをダウンロード、/tmpに展開し、
そこのsetup.pyを実行している。

/tmp/pip-install-hzcdo768/mecab-python3/

というフォルダはない。
インストールに失敗した後に消しているのだろう。


よーし、では、tar.gzを持ってきて、解凍→インストールしてみよう。

wget https://files.pythonhosted.org/packages/ac/48/295efe525df40cbc2173748eb869290e81a57e835bc41f6d3834fc5dad5f/mecab-python3-0.996.1.tar.gz


ダメ。

swigのバージョンが古いのだろうか。

# swig -version

SWIG Version 1.3.40


でもswigの新しいバージョンの入れ方がわからない。

twitterで、ある人がバージョン指定すればいけると。

pip install mecab-python3==0.7

...いけた。

# pip install mecab-python3==0.7
Collecting mecab-python3==0.7
  Downloading https://files.pythonhosted.org/packages/25/e9/bbf5fc790a2bedd96fbaf47a84afa060bfb0b3e0217e5f64b32bd4bbad69/mecab-python3-0.7.tar.gz (41kB)
    100% |????????????????????????????????| 51kB 2.4MB/s
Installing collected packages: mecab-python3
  Running setup.py install for mecab-python3 ... done
Successfully installed mecab-python3-0.7


とりあえずpythonからmecabが使えるようになった。

ふう。

2019/03/03

python3.6のCGIでGoogleニュースのヘッドラインを抽出するスクレイピング例


python3.6によるスクレイピング例

Googleニュースのヘッドラインのタイトルを抽出する。

beautifulsoupは使わず、正規表現でゴリゴリする。


-------
#!/usr/bin/python
# -*- coding: utf-8 -*-
import requests
import re
import sys
import cgi
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

my_title = 'what\'s hot'

def print_head(title):
    print('Content-type: text/html')
    print()
    print('<html><head>')
    print('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">')
    print('<title>'+title+'</title>')
    print('</head>')

def print_tail():
    print('</html>')

print_head(my_title)

print('<body>')

res = requests.get('https://news.google.com/?hl=ja&gl=JP&ceid=JP%3Aja')
res.raise_for_status()

print("From Google News JP status:" + str(res.status_code) + "<br><br>")

tmp = re.sub('\n','',res.text)
tmp = re.sub('<a href','\n<a href',tmp)
tmp = re.sub('\/a>','/a>\n',tmp)
tmplist = tmp.split('\n')

result = [ s for s in tmplist if re.match('<a href=\"\.\/articles.*?\/a>', s) or ( 'すべての記事' in s ) ]

for i in result:
    if 'すべての記事' in i:
        break
    s = re.sub(r'<a href.*?<span >(.*?)<\/span><\/a>',r'\1',i)
    print(s+"<br>")

print('</body>')

print_tail()

------

苦労したところ

import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

これを入れないと、抽出した結果をprintするときに下記のようなエラーになる。

UnicodeEncodeError: 'ascii' codec can't encode characters in position 343-391: ordinal not in range(128)

googleニュースのヘッドラインだけを抽出したかったのだが、
htmlソースを見ても特定の条件がみつからない。

'<a href=\"\.\/articles.*?\/a>',

で抽出すれば見出しのリンクが取れるのだが、ヘッドライン以外もすべて取れてしまう。

「すべての記事」というキーワードが区切りになっているので、
それが出てくるまで、という条件で抽出した。


これができればどこからでもなんでも取れる....








2019/03/02

python3のhello world cgi

最小限のpython cgi

-----
#!/usr/bin/python
# -*- coding: utf-8 -*-

my_title = 'greeting from python'
my_message = 'hello, world'

###

def print_head(title):
    print('Content-type: text/html')
    print()
    print('<html><head>')
    print('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">')
    print('<title>'+title+'</title>')
    print('</head>')

def print_body(message):
    print('<body>')
    print(message)
    print('</body>')

def print_tail():
    print('</html>')

###

print_head(my_title)

print_body(my_message)

print_tail()
-----


3系はprintにカッコをつけてつかう

インデントでスペースとタブを混在させてはいけない


python3をデフォルトにする@centos6

google analyticsがあるcgiがinternal server errorになっていることを報告してきて、
それを直している過程で、

perl (LWP)でやっているスクレイピングが時代遅れ

pythonの2系は時代遅れ

ということを悟ったので、3系(3.6)をインストールした。

2.6とか2.7とかいろいろ入ってしまったのできれいにしようと思ったのだが、
うまく消えないのでとりあえず3系がデフォルトで動くようにした。



# pip install beautifulsoup4
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
Requirement already satisfied: beautifulsoup4 in /usr/local/lib/python2.7/site-packages (4.7.1)
Requirement already satisfied: soupsieve>=1.2 in /usr/local/lib/python2.7/site-packages (from beautifulsoup4) (1.8)
Requirement already satisfied: backports.functools-lru-cache; python_version < "3" in /usr/local/lib/python2.7/site-packages (from soupsieve>=1.2->beautifulsoup4) (1.5)
#


beautifulsoupなる便利なものがあると聞いて使ってみようとしたら「まだ2.7なんか使ってんのかよ」と怒られた。


# python --version
Python 2.6.6


python

とだけやると、2.6.6が起動する。

python3.6

とやれば3系が動くようにはなっているが、面倒。

# python3.6
Python 3.6.7 (default, Dec  5 2018, 15:02:16)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-23)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

"python" はシンボリックリンクなので、
それを3系にリンクしなおせばよい。

# which python
/usr/bin/python

# which python3.6
/usr/bin/python3.6


pipも

# which pip3.6
/usr/bin/pip3.6

# which pip
/usr/local/bin/pip



# ln -s /usr/bin/python3.6 /usr/bin/python
ln: creating symbolic link `/usr/bin/python': ファイルが存在します

現在のリンクを消してから3系へのリンクを作る。

# unlink /usr/bin/python

# ln -s /usr/bin/python3.6 /usr/bin/python



# ln -s /usr/bin/pip3.6 /usr/local/bin/pip
ln: creating symbolic link `/usr/local/bin/pip': ファイルが存在します

pipも同様

# unlink /usr/local/bin/pip
# ln -s /usr/bin/pip3.6 /usr/local/bin/pip




# python
Python 3.6.7 (default, Dec  5 2018, 15:02:16)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-23)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>


# pip -V
pip 9.0.1 from /usr/lib/python3.6/site-packages (python 3.6)


pythonもpipも3系になった。