スキャナの画像を回転するなど
mogrify -rotate 180 hoge.jpg
mogrify は元のファイルを上書きするコマンド
回転角度は、右回り
向きを修正したり回転角度を修正したりするのに使える
マイナス90度回転するなら 360-90 = 270
mogrify -rotate 270 hoge.jpg
これでOK.
convert コマンドでも
convert コマンドでも同じこと
mogrify -rotate 270 hoge.jpg out.jpg
mogrify -rotate 180 hoge.jpg
mogrify は元のファイルを上書きするコマンド
向きを修正したり回転角度を修正したりするのに使える
マイナス90度回転するなら 360-90 = 270
mogrify -rotate 270 hoge.jpg
これでOK.
convert コマンドでも同じこと
mogrify -rotate 270 hoge.jpg out.jpg
## 画像を100枚取得してー for i in {1..100} ; wget https://www.a8.net/a8v2/jcaptcha ; done ## 10x10に敷き詰める montage jcaptcha.* -tile 10x10 -geometry 200x60+1+1 out.jpg
montage jcaptcha.*.jpg -tile 10x10 -geometry 200x60+1+1 out.jpg
簡単ですね
彼女のクレジットカードを作るために、アフィリエイトでもやろうかと思ってA8のパスワードリマインダーをかけたらこれがヒドイの
こういうのは、昔からのカウンタじゃないですか
https://www.a8.net/a8v2/jcaptcha
見て分かる通り、文字の幅が決まっている、フォントサイズが固定。これでは簡単に解析ができますね。っていうかこのキャプチャなら付ける意味が無い。飾りにすらなってない。
あー幅にゆらぎが無いですわ。せめてもう少し乱数調整を見なおしたほうが。。。
ベースラインも揃ってますわ・・・せめて上下にずれてたら、、、、
こんなもの、2006年の段階で、だめじゃんって高木先生も書いてる。
高木浩光@自宅の日記 - 飾りじゃないのよCAPTCHAは 〜前代未聞のCAPTCHAもどき, CAPTCHA機能の発注仕様をどうするか
余白が真っ白だから、 magick コマンドで1秒でサイズを統一できてしまう。
https://www.a8.net/a8v2/jcaptcha このURLにアクセスると、Cookieが発行される。Cookieなしでキャプチャ出てるくるのは簡単に突破しろと言ってるような。。。
パスワードの最大文字数決まってるの!!
パスワードの文字数に制限がある=パスワードを平文保存ってことですよね。
ハッシュ化してりゃ文字数制限なんてないものね。。。
ああ、これ以上何も言うまい。。
何も言わないつもりだったけど、運営母体は、東証一部銘柄だとわかった。
はいきた、「誤」安心のPマーク。ほんとうにPマークってなんのためにあるんでしょうね。
わかっててやってるのか、知らずにやってるのか。エンジニアの良心は無いのだろうか。
上場企業なんだったら、高木先生案件ですかね。
東証一部銘柄だったので、いろいろと追加。
WEBページの更新をチェックするのが面倒なので、チェッカーにする
curl でページ取得して、md5sum にかけて、ハッシュ値チェックする。
もっと簡単にlast-modified や modified Etag 使ってもいんだけど、汎用性考えたら、md5sumかな。
Cookieの処理あ、 chrome で curl コマンド取得すればいい。
osascript -e 'display notification "更新あったよ。"'
osascript で、簡単に通知が出せる。超楽ちん
#!/usr/bin/env ruby # cmd = "curl -s 'http://xxxx.example.gr.jp/score/index' "+ " -H 'DNT: 1' -H 'Accept-Encoding: gzip,deflate,sdch' -H 'Accept-Language: en,ja;q=0.8' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2138.3 Safari/537.36' "+ "-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Referer: http://score.2014su.nsc.gr.jp/score/detail/scenario_id/85' -H 'Cookie: EID=XXXXXXXXXXXX-1sEXIOa' -H 'Connection: keep-alive' "+ "-H 'Cache-Control: max-age=0' --compressed " +"| md5sum" last_id = `#{cmd}` loop{ ret = `#{cmd}` puts ret if last_id != ret `osascript -e 'display notification "更新あったよ。"'` end last_id = ret sleep 10 }
更新チェッカーとか、データのバックアップとかミラーとか、そういうのは10分位で書いてパパっと解決したいよね。
ソフトググってインストールしてる時間のほうが勿体ないとか言えるように
xpath 大好きっ娘 な takuya です。こんばんは。
xpath を扱うには、libxm2やlibxsltをruby やpython から使ってたんですが。phpのxpath は微妙だし。
コマンドラインから使おうと思ってコマンド書き始めてたら、すでにコマンドが用意されてるんですね。
xmllint コマンドというものがあります。引数に --xpath をつけるとxpathを使えます。
takuya@rena:~/Desktop$ echo "<a><b><c>cccc</c></b></a>" | xmllint --xpath "//c/text()" - cccc
osx の場合は、最初から入ってる
takuya@osx:~/Desktop$ which xmllint /usr/bin/xmllint
takuya@debian:~$ which xmllint /usr/bin/xmllint
どの環境でも使えるならとっても便利ですね!。
html を扱うときは --html
をつける
xmllint --html --xpath "//input" -
HTMLは厳格な仕様で書かれていることが少ないので、Warningが大量に出る。これはSTDERRに出るので無視できる。
xmllint --html --xpath "//input[@name='post_id']/@value" - 2>/dev/null
標準入力 STDIN から受けるときは、 - を末尾に置かないと動かなかったの
html を扱うときにフラグが必要になっていた。
xmllint はその名の通りlint なので、奥が深いプログラムですね。
OSX には、xpath というPerlで書かれてるコマンドがついてくる。
takuya@rena:~/Desktop$ echo "<a><b><c>cccc</c></b></a>" | xpath "//c/text()" Found 1 nodes: -- NODE -- cccc
このように簡単にXpathを使って試すことが出来る。便利!
takuya@rena:~/Desktop$ which xpath /usr/bin/xpath
実体は perl
takuya@rena:~/Desktop$ head /usr/bin/xpath -n 20 #!/usr/bin/perl =for comment The contents of this script should normally never run! The perl wrapper should pick the correct script in /usr/bin by appending the appropriate version. You can try appending the appropriate perl version number. See perlmacosx.pod for more information about multiple version support in Mac OS X. =cut use strict; use Config (); my @alt = grep {m,^$0\d+\.\d+(?:\.\d+)?$,} glob("$0*"); print STDERR <<"EOF-A"; perl version $Config::Config{version} can't run $0. Try the alternative(s): EOF-A if(scalar(@alt) > 0) {
うーん。便利だけど出力が気に入らないから、作ったほうが速いような。
Radikoの録音スクリプトがBashで書かれていて、どういう仕組みか気になったので、Pythonで描き直ししつつ、Pythonでシェル・スクリプトを代用するために、いろいろ調べみた。
https://gist.github.com/matchy2/3956266
radikoの録音スクリプトは、スクリプトの基本要素がいっぱい入っていて、すごく勉強になる。
プログラム書くときの基本がシッカリ入ってて勉強にはなかなかいいと思った。しかも、プログラムの実行結果が「音が再生される」という五感でわかりやすいプログラムなので、動いた時はやっぱり嬉しい。
Python以外でもRubyやNode、PHPなどでも書きなおしてみたらいいのじゃないのかな。
SSLのverify が出来なくてエラーで落ちてた
SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed
import ssl ssl._create_default_https_context = ssl._create_unverified_context
pythonって文字列に変数を埋め込むのには
name = "takuya" print " hello %s " % name
print " hello %(name)s " % { "name":"takuya" } ## %s の名前付きってことで %(varname)s
format を使うと実現できる。
name = "takuya" print " hello {name} ".format (**vars())
正直なところvars でガッツリ埋め込みもちょっと怖いんだけど。よく考えたら、PHPやRubyもガッツリ埋め込みだからいいか。
5. 組み込み型 — Python 2.7.x ドキュメント
import os os.remove("/tmp/my_temp_file")
簡単ですね。os モジュールにあるので、os.remove とモジュール名をつけるのがちょっと嫌だけど
15.1. os — 雑多なオペレーティングシステムインタフェース — Python 2.7ja1 documentation
python で http リクエストをPOSTする。
curl や wget をシェル・スクリプトで呼び出してもいいんだけど、urllib/urllib2 を使う方法も実現可能なのです。
import urllib import urllib2 response ={} url = "https://radiko.jp/v2/api/auth2_fms" headers ={ "pragma":"no-cache", } try : params = urllib.urlencode({'name':1, 'item_id':2}) req = urllib2.Request(url, params ,headers ) res = urllib2.urlopen(req) #print res.read() response["body"] = res.read() response["headers"] = res.info().dict except URLError, e: print e exit() print response["body"]
urllib は リクエストには使わないのですが、リクエストパラメータをURLエンコードするのに必須になるので使っている。
レスポンスのヘッダはres.info()で取れるのですが、dict形式にならないので、明示的に
res.info().dict
として取り出している。
POSTでリクエストだけ送って、本文は空っぽの場合は、改行を送ればいい。
req = urllib2.Request(url, "\r\n" ,headers )
あるファイルの一部分を取り出して、保存するには、ddするのが手っ取り早い
offset=223 length=1024 partialkey=`dd if=test.swf bs=1 skip=${offset} count=${length} 2> /dev/null `
ファイルをopen してseek して、read する。
offset = 223 length = 1024 f = open("test.swf", 'rb+') f.seek(offset) data = f.read(length)
ファイルの中身をseek するだけなので、結構簡単ですね。
コレを使います。
import subprocess import shlex ret = subprocess.check_output(shlex.split("date -I")).decode("UTF-8").strip() print(ret)
詳しく書いていきます。
subprocess はコマンド実行がちょっと面倒臭い。
import subprocess input_f = "player.swf" output_f = "radiko.png" cmd = "/usr/local/bin/swfextract -b 14 %s -o %s" % (input_f, output_f ) subprocess.call( cmd.strip().split(" ") )
subpcorcess.call は配列でコマンドとコマンドの引数を与える。 面倒なので、コマンド文字列を作ってから、split(" ") で文字列を分割して配列にしたら楽かも。
シェル経由で実行すると楽ちんですよね。
バッククォート演算子を使って文字列を囲うだけで出来る。
`wget -O index.html http://www.yahoo.co.jp `
call に shell=True のキーワード引数をつけるだけ。
import subprocess cmd = "ls -lt | head -n 5" subprocess.call( cmd, shell=True )
これで、シェル経由実行される
subprocess.call([cmd,arg1,arg2..], shell=True)は 旧来のos.system の実行と同じ
import os cmd = "ls -lt " os.system( cmd )
os.system はすでにサポートされなくなりつつあるので、subprocessを使う方がいいようです。
シェル経由で実行するとは、こういうこと。
sh -c "コマンド"
のように、sh -c をつけて実行していることに相当する。
コマンドの文字列をそのまま渡せるので、Shell=Trueを使う人が多いとは思います。
bash なら
ret=`ls -lt ` echo $ret
とするだけなのですが。
python のsubprocess モジュールで実行するには、check_outputを使う
import subprocess cmd = "ls -lt " ret = subprocess.check_output( cmd.split(" ") ) print ret
check_callを使う。
import subprocess cmd = "ls -lt " ret = subprocess.check_call( cmd.split(" ") ) print ret == 0
実行結果が正常終了なら0がかえってくる。
subprocessにシェル経由実行するように渡すと、パイプラインでもシッカリ処理してもらえる。
import subprcoess cmd = "ls -lt | head -n 5" subprocess.call( cmd , shell=True )
subprocess のPIPEとstdoutを使うと実現できる。
cmd1 = "ls -lt " cmd2 = "head -n 5 " p1 = subprocess.Popen(cmd1.strip().split(" "), stdout=subprocess.PIPE) p2 = subprocess.Popen(cmd2.strip().split(" "), stdin=p1.stdout) p1.stdout.close() output = p2.communicate()[0]
非シェル経由の場合コマンドの実行をパイプ経由で送るには、ちょっと面倒臭い手続きが必要になる。
最後の2行はおまじない
p1.stdout.close()
output = p2.communicate()[0]
これを書くことで、Python の実行を CTRL+C をで止めた時に、サブプロセスがちゃんと終了してくれる。書かないとゴーストで残る。時間のかかる処理をしていると怖い。
ただ、シェル経由しない実行は、コマンド・インジェクション対策などで使えるので重要なテクニックになると思う。
spawn という名前はイメージしやすかったけどなくなりました。
Python でURLにアクセスしてファイルを保存するには urlib2 を使うのが手っ取り早い
import os import urllib2 file_name = "yahoo.co.jp.html" url = "http://www.yahoo.co.jp" if os.path.exists( file_name ) : try : body = urllib2.urlopen( url ).read() f = open( file_name, "w" ) f.write(body) f.close() except URLError, e: print e exit() print "end"
python でwget を起動してもいいんだけど、ここは敢えて urllib2 を使ってまみした。
python でシェル・コマンド呼び出しは、ちょっとだけ面倒なので、ここはurllib2を使いました。
f = open( file_name, "w" ) f.write(body) f.close()
これだけですね。簡単。
file_name="yahoo.co.jp.html" url="http://www.yahoo.co.jp" if [ ! -f $file_name ]; then wget -q -O $file_name $url
python でスクリプトを作って引数を取りたいときに引数の個数を取得するには。
import sys if len(sys.argv) < 3 : print "引数が足りません" exit() print sys.argv
実際に実行してみた結果
takuya@rena:~/Desktop$ python test.py aaa 引数が足りません takuya@rena:~/Desktop$ python test.py aaa bbb ['test.py', 'aaa', 'bbb'] takuya@rena:~/Desktop$ python test.py aaa bbb ccc ['test.py', 'aaa', 'bbb', 'ccc']
例に漏れずARGV[0] は自分自身のファイル名を示すことになります。
if [ $# -ge 2 ]; then echo "引数が足りません" exit() fi