【python】requests

requestsを使うとWebデータの操作ができる。特に使われるのはWebスクレイピングやWebAPIを使ったデータ取得
requestsはHTTPライブラリ。自分とWebサーバとのHTML等の受信を送受信するためのプロトコルで、HTTPにはデータの参照や更新などのメソッドが用意されている。
PythonにはHTTPライブラリの標準モジュールとしてurllib.requestがあるが、requestsを使用した方が楽にプログラミンができる。

urllib.requestの場合

import urllib.request

url = 'https://httpbin.org/get'

r = urllib.request.Request(url)

with urllib.request.urlopen(r) as response:
	body = response.read()
	print(body.decode('utf-8'))

requestsの場合

import requests

url = 'https://httpbin.org/get'

r = requests.get(url)

print(r.text)

WebAPIからのデータ取得

import requests

url = 'https://zipcloud.ibsnet.co.jp/api/search'
params = {'zipcode':'7830060'}

r = requests.get(url,params=params)

print(r.text)

requestsを使うことにより直感的な記述が可能になる。

【python】pycryptodome

pycryptodomeとは?
L pycryptodomeはデータの暗号化・復号化を可能にするpythonライブラリ
L pycryptoの方が知名度があるが後継のようなもの

$ pip install pycryptodome

pycryptodomeは次の三つの処理がある
– 秘密鍵・公開鍵の作成
– 公開鍵を使ったデータの復号化
– 秘密鍵を使ったデータの復号化

from Crypto.PublicKey import RSA

key = RSA.generate(2048)
private_key = key.export_key()
file_out = open("private.pem", "wb")
file_out.write(private_key)
file_out.close()

public_key = key.publickey().export_key()
file_out = open("public.pem", "wb")
file_out.write(public_key)
file_out.close()

公開鍵を使ったデータの暗号化

from Crypto.PublicKey import RSA
from Crypto.Random import get_random_bytes
from Crypto.Cipher import AES, PKCS1_OAEP

data = "日本語で書かれた秘密のメッセージ".encode("utf-8")
file_out = open("encrypted_data.txt", "wb")

recipient_key = RSA.import_key(open("public.pem").read())
session_key = get_random_bytes(16)

# セッションキーをRSA公開鍵で暗号化
cipher_rsa = PKCS1_OAEP.new(recipient_key)
enc_session_key = cipher_rsa.encrypt(session_key)

# データをAESセッションキーで暗号化
cipher_aes = AES.new(session_key, AES.MODE_EAX)
ciphertext, tag = cipher_aes.encrypt_and_digest(data)
[file_out.write(x) for x in (enc_session_key, cipher_aes.nonce, tag, ciphertext)]
file_out.close()

なるほど、深いな…

[画像認識] MNISTによる手書き文字の認識

手書き文字認識はMNISTのデータセットを使って、keras, kaggleからデータを取り込むことができる。

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

mnist = tf.keras.datasets.mnist.load_data()
train, test = mnist
(x_train, y_train),(x_test, y_test) = mnist

print(x_train.shape)
print(y_train.shape)
print(x_test.shape)
print(y_test.shape)

(60000, 28, 28) // 28x28pxのデータが60000枚
(60000,)
(10000, 28, 28) // 28x28pxのデータが10000枚
(10000,)

データセットを画像で確認

print(x_train[0])

plt.imshow(x_train[0])
plt.savefig('image.jpg',dpi=100)

### モデルの作成

x_train = x_train / 255.0  # 0-1の間に抑えるよう正規化する
x_test = x_test / 255.0

# Sequential(系列)モデル構築 インスタンスにリストを追加する
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Input((28, 28))) # 入力層は28x28
model.add(tf.keras.layers.Flatten()) # 一元配列1, 784 に変換

# 入力層から情報を受け継いで計算を行う中間層
model.add(tf.keras.layers.Dense(128)) # 128個に全結合
model.add(tf.keras.layers.Activation(tf.keras.activations.relu)) # 中間層の活性化関数の設定, reluは0以下は0、0以上は入力値を出力
model.add(tf.keras.layers.Dropout(0.2)) # 過学習を防ぐため20%ドロップアウト

# 出力
model.add(tf.keras.layers.Dense(10)) # 出力層0~9の10個
model.add(tf.keras.layers.Activation(tf.keras.activations.softmax)) # softmax関数は出力値の合計が100%になる

# コンパイル
model.compile(
	optimizer=tf.keras.optimizers.Adam(), # optimizerは逆伝播モジュール 手本と出力を比較して重みw, バイアスbを修正, AdamはAdaptive Moment Estimationの略でmomentumSGDとRMSpropを合わせたアルゴリズム
	loss=tf.keras.losses.sparse_categorical_crossentropy, # 誤差関数モジュール 正解値と予想値のズレを計算
	metrics=[tf.keras.metrics.sparse_categorical_accuracy] # 評価関数
)

# fitで学習 epochsで5回
model.fit(x_train, y_train, epochs=5)

print(model.evaluate(x_test, y_test))

plt.imshow(x_test[0])
plt.savefig('data/test_img.jpg',dpi=100)

# predict
pred = model.predict(x_test[0][np.newaxis]) # numpyのnewaxis
print(np.argmax(pred)) # 一番大きい要素


img = Image.open("data/handwriting.jpg").convert('L')
img.thumbnail((28, 28))
img = np.array(img)
pred = model.predict(img[np.newaxis]) # numpyのnewaxis
print(np.argmax(pred)) # 一番大きい要素


[0.0724998340010643, 0.9782000184059143]
7
3

ほう

[tesseract] 免許証の文字を読み込みたい : tesseract_layoutの検証

免許証画像は以下を使用する

tesseract_layoutの値を1から10まで変更して検証する

### tesseract_layout=1
$ python3 main.py
(mm| 日 本 花 子 軌和61年 5月

]1 日生

人誠| 東京都生代田区霞が関2ー 1一2
け| 令和01年05807H 12345

### tesseract_layout=2
$ python3 main.py
Traceback (most recent call last):
File “main.py”, line 9, in
txt = tools[0].image_to_string(
File “/home/vagrant/.local/lib/python3.8/site-packages/pyocr/tesseract.py”, line 386, in image_to_string
raise TesseractError(
pyocr.error.TesseractError: (-1, “Unable to find output file (tested [‘/tmp/tmpuiijvfgx/output.txt’])”)

### tesseract_layout=3
$ python3 main.py
(mm| 日 本 花 子 軌和61年 5月

]1 日生

人誠| 東京都生代田区霞が関2ー 1一2
信和01年05』07H 12345

### tesseract_layout=4
$ python3 main.py
(名| 日 本 花 子 昭和61年 5月 1日生

人誠| 東京都生代田区霞が関2ー 1一2
交付| 令和O1年05』07H 12345

2024箇(06$06有O1Hまで勧

%の 眼鏡等
条件等

見 本
き引第 012345678900 号

0
を人 ト民捧人構誠還| 〇〇OOO
=層衣2908』018導笛にに回較固 ま中

### tesseract_layout=5
$ python3 main.py
| |
に 5
中 M
加 9
9
避 Ok
ら 呈較っ
守 CN OS
| 較 抽| |睦旧旧計員
ー|。居 則遇|
| mp
– 還 RE 逢遇
| | 国~園 必g式還
玲|上 O、 は半較|
陸中 8
| 錠 [壮 加|
| 略叶RS sss
是 陸中
| 還|二 地
| 層間 ら5 8さき
EE ーーベ
[es = 絆|還> 証庄計
首日 EHP

### tesseract_layout=6
$ python3 main.py
(信所| 東京都寺代田区霞が関2-1一2

$和01キ05』07B 12345

天の 眼鏡等 に

条件等

見本 *

*引012345678900 呈 叶

に天上1 5404』01H話司にに放還 ま
に17108801間 汗天市生天 )
にafW29*08801 只間四時間 Sgms 583

### tesseract_layout=7
$ python3 main.py
で 敵 ーー an

### tesseract_layout=8
$ python3 main.py
で 敵

### tesseract_layout=9
$ python3 main.py
|

### tesseract_layout=10
$ python3 main.py
er

### 結論
tesseract_layout=4, lang=’jpn’ が一番まともな気がするけど、
なんでだろう?
きちんと精度高く読み取るにはGoogleのVison APIで実装するっぽいな…

[beautifulsoup4] aタグの中身を取得

# -*- coding: utf-8 -*-
from urllib.request import urlopen
from bs4 import BeautifulSoup
from pprint import pprint

URL = 'https://news.yahoo.co.jp/'
with urlopen(URL) as res:
	html = res.read().decode("utf-8")

soup = BeautifulSoup(html, 'html.parser')

titles = soup.select('.sc-esjQYD a')
titles = [t.contents[0] for t in titles]

pprint(titles)

$ python3 title.py
[‘東京で新たに409人の感染確認’,
‘総務相 NTTと会食有無答えず’,
‘変異株 仏で新規感染の7割に’,
‘変異株感染で死亡判明 大阪’,
‘うつぶせ寝で1歳死亡 和解’,
‘ワタミ、労基署から是正勧告’,
‘ワタナベマホト容疑者逮捕’,
‘森本選手「驚いたから」供述’]

で、これを適正開示でやる

$ python3 title.py
[’16:30 36320グリー 特別利益(投資有価証券売却益)の計上(見込み)に関するお知らせ’,
’16:30 37190J-ジェクシード 代表取締役の異動に関するお知らせ’,
’16:30 41740J-アピリッツ 2021年1月期決算短信〔日本基準〕(非連結)’,
’16:30 45990M-ステムリム レダセムチドの慢性肝疾患を対象とした医師主導治験(第2相試験)の第一例目投与に関するお知らせ’,
’16:30 50110ニチレキ 行使価額修正条項付新株予約権の大量行使に関するお知らせ’,
’16:30 67720コスモス電 ‘
// 省略

うーむ、、、cronでメール送信したい。

バッチで走らせる時間にリリースされた開示情報のみ送信したいなー
dateで分岐やな

[CentOS8] beautifulsoup4を使おう

$ python3 –version
Python 3.6.8
$ pip3 –version
pip 9.0.3 from /usr/lib/python3.6/site-packages (python 3.6)
$ sudo pip3 install beautifulsoup4
$ sudo pip3 install requests
$ sudo pip3 install lxml

# -*- coding: utf-8 -*-
import requests
from bs4 import BeautifulSoup

target_url = 'https://kakaku.com/pc/note-pc/itemlist.aspx?pdf_ob=0'
r = requests.get(target_url)
soup = BeautifulSoup(r.text, 'lxml')

for a in soup.find_all('a'):
      print(a.get('href'))

[tesseract4.1.1] Ubuntuにtesseract(Eng、日本語、簡体字中国語、繁体字中国語、スペイン語)を入れよう

1. PPA(パーソナル・パッケージ・アーカイブ)を追加
$ sudo add-apt-repository ppa:alex-p/tesseract-ocr
$ sudo apt-get update

2. Tesseractインストール
$ sudo apt install tesseract-ocr
$ sudo apt install libtesseract-dev

$ tesseract -v
tesseract 4.1.1-rc2-25-g9707
$ tesseract –list-langs
List of available languages (2):
eng
osd

3. 日本語、簡体字中国語、繁体字中国語、スペイン語をインストール
$ sudo apt install tesseract-ocr-jpn tesseract-ocr-chi-sim tesseract-ocr-chi-tra tesseract-ocr-spa
$ tesseract –list-langs
List of available languages (6):
chi_sim
chi_tra
eng
jpn
osd
spa

4. pyocr install
$ pip install pyocr

5. 中国語の画像を読み取る

$ tesseract chinabank.jpeg output -l chi_sim
中国平安
PINGAN

保险’ 银行. 投资

6. pythonで書く

from PIL import Image
import sys
import pyocr

tools = pyocr.get_available_tools()
langs = "chi_sim"

img = Image.open('images.jpeg')
txt = tools[0].image_to_string(
		img,
		lang=langs,
		builder=pyocr.builders.TextBuilder(tesseract_layout=6)
	)
print(txt)

$ python app.py
中国平安
PINGAN
保险; 银行.投资

さて、これをDjangoで実装したい。
思ったより考えるの難しいな。

PythonでCSVを出力したい

DjangoでCSVを出力したいのですが、まずはlocalでpythonで試します。

– encodingを付けないと文字化けするので注意が必要

import csv

file = open('new.csv', 'w', newline='', encoding='utf_8_sig')
w = csv.writer(file)
w.writerow([2191,'テラ',851])
w.writerows([[4563,'アンジェス',1435],[3911,'Aiming',693],[3776,'ブロードバンドタワー',384]])

file.close()

$ python test.py

writerowをforループで良さそうです。これをDjangoで実装します。

Pythonで今月、前月、来月、昨年、毎月あたりを取得する

### 今日
まず本日から

from datetime import datetime, date, timedelta

today = datetime.today()
print(datetime.strftime(today, '%Y-%m-%d'))

$ python test.py
2020-10-10

#### 今年、今月、来月、前月

from datetime import datetime, date, timedelta
from dateutil.relativedelta import relativedelta

today = datetime.today()
print(datetime.strftime(today, '%Y-%m-%d')) # 今日

print(today.year) # 今年
print(today.month) # 今月

next_month = today + relativedelta(months=1)

print(next_month.year) # 来月
print(next_month.month) # 来月

one_month_before = today - relativedelta(months=1)

print(one_month_before.year) # 前月
print(one_month_before.month) # 前月

$ python test.py
2020-10-10
2020
10
2020
11
2020
9

前月や翌月など月ごとの計算はtimedeltaではできないらいしいので、relativedeltaを使うと良いらしい。
月単位で計算できるrelativedeltaはかなり使えますね。

### Python学習でオススメの本
掌田 津耶乃の本は勉強になります。

Pythonでqrコードを作りたい

QRコード画像生成ライブラリ「qrcode」をインストールします。

$ pip install qrcode
$ pip install pillow

### テキストを画像にする

import qrcode

qr = qrcode.QRCode()
qr.add_data('test text')
qr.make()
img = qr.make_image()
img.save('qrcode.png')

### URLを画像にする

import qrcode

qr = qrcode.QRCode()
qr.add_data('https://www.google.com/')
qr.make()
img = qr.make_image()
img.save('qrcode.png')

アラ? 凄い簡単に出来ますね。。。簡単過ぎてビックリした。