群馬県高崎市でWebの製作や賃貸・不動産情報誌の作成(DTP)とかやってます。仕事絡みで、勉強したこととか、趣味で調べたこととかの個人的なメモみたいな記事を書いてます。

2010年02月09日

Google App Engine プログラミング入門

以前から興味があったけれど、なかなか手を出せなかったGoogle App Engine

とりあえず、勉強を始めようと思って書店にて一番薄い参考書を購入w

簡易リファレンスも付いてきて、これはお得! と思ったけれど……これが大失敗でした。
  
続きを読む
タグ :PythonGAE

Posted by 清水正行 at 15:53Comments(0)TrackBack(0)Python

2009年08月21日

zip()関数とリスト内包表記はとても便利

たとえば、以下のように外観写真や間取画像ファイルをidで管理している場合。

物件ID: 101
外観写真: pho-101.jpg
間取画像: mad-101.jpg

「idのリストを元に外観写真と間取画像をペアにしたリストを作りたい」ってことが頻繁にあるのだけれど、Pythonではzip()関数とリスト内包表記を使うと簡単に書けて便利。

>>> id = [101,102,103,104,105]
>>> zip(["pho-"+str(x)+".jpg" for x in id],["mad-"+str(x)+".jpg" for x in id])
[('pho-101.jpg', 'mad-101.jpg'),
('pho-102.jpg', 'mad-102.jpg'),
('pho-103.jpg', 'mad-103.jpg'),
('pho-104.jpg', 'mad-104.jpg'),
('pho-105.jpg', 'mad-105.jpg')]
>>>
  

Posted by 清水正行 at 17:35Comments(0)TrackBack(0)Python

2009年08月14日

TCPWatchを使って、リクエストの中身を確認

ネットワークがらみの使い捨てスクリプトなんかを書いていて、「これちゃんとリクエスト飛んでんのかな?」なんてとき、ちょこっと確認するのに便利。

http://hathawaymix.org/Software/TCPWatch

コマンドラインからTCPWatchを起動する。
c:>tcpwatch.py -p 127.0.0.1:3128


TCPWatchをset_proxyしてリクエストを飛ばす
>>>import urllib2
>>>req = urllib2.Request("http://www.google.co.jp")
>>>req.set_proxy("127.0.0.1:3128", "http")
>>>site = urllib2.urlopen(req)


  
タグ :PythonTCPWatch

Posted by 清水正行 at 10:44Comments(0)TrackBack(0)Python

2009年06月23日

Willcom D4でカメラのシャッター音を消す

嘘です。

ただ単に、D4付属のカメラアプリを使わないで、カメラから画像をキャプチャすれば、シャッター音もしないよ~ってだけ。

PythonのVideoCaptureモジュールで簡単に出来たのでメモ

必要なもの
Python 2.5.2
Python Imaging Library (PIL)
VideoCapture
(VideoCaptureは、ダウンロード→解凍→DLLsフォルダとLibをPythonの同名フォルダに上書き)

上から順にインストールしたら、IDLE(Python GUI)を起動して、Python Shellに以下を入力

>>> import VideoCapture
>>> cam = VideoCapture.Device()
>>> cam.saveSnapshot('c:/image.jpg')

これで、Cドライブの直下にカメラから入力された画像が保存されます。
ちょう~かんたん♪

でも、さすがにこれだと自分が何をとっているのかもわかりづらいので、もうちょっとアプリっぽく。

GUIを何で作ろうか迷ったんですが、カメラから(セーブしないで)画像を取得するのには、getImageを使うのだけど、その戻り値は「Returns a PIL Image instance.」(PILのimageクラスのインスタンス)なので、pygameを使うのが楽そうなので、ダウンロードしてインストール。
Pygame

PILとPygameの連携についてはここを参照


camera.py

import pygame
from pygame.locals import *
import VideoCapture
import sys

pygame.init()
screen = pygame.display.set_mode((640,480))
pygame.display.set_caption('camera')
pygame.display.flip()
cam = VideoCapture.Device()

while 1:
cap = cam.getImage()
data = cap.tostring()
size = cap.size
mode = 'RGB'

image = pygame.image.fromstring(data, size, mode)
screen.blit(image, (0,0))
pygame.display.flip()
for event in pygame.event.get():
if event.type == QUIT:
cam.saveSnapshot('c:\image.jpg')
del cam
sys.exit(0)


↓上記のソースを実行すると、こんな感じ


×ボタンを押してアプリを終了する際に、画像をCドライブ直下に保存しています。

PILのイメージクラスのインスタンスなんで、画像にエフェクトかけたりするのも楽チンです。

結構いろいろ遊べるんじゃないでしょうかね。

……重いけど。  

Posted by 清水正行 at 09:09Comments(0)TrackBack(0)Python

2009年06月18日

二つのディレクトリ内の差分を出力する

単に二つのフォルダの中を比較するのは、非常に簡単。

Pythonには、"集合"というデータ型があるので、それを使うと楽。
集合とは、重複しない要素を順不同で並べたもの。

#coding:utf-8

import os

dir1 = u".\\フォルダ1\\"
dir2 = u".\\フォルダ2\\"

files1 = os.listdir(dir1)
files2 = os.listdir(dir2)


files1 = [x.replace(dir1, "").lower() for x in files1]
files2 = [x.replace(dir2, "").lower() for x in files2]



for i in set(files1) - set(files2):
print dir1 + " only:" + i

for i in set(files2) - set(files1):
print dir2 + " only:" + i


set()で集合型に変換。
集合オブジェクトでは、和、交差、差、対称差、などの演算が行える。

a - b #aには存在するがbには存在しない要素
a | b #aまたはbに存在する要素
a & b #a、b、両方に存在する要素
a ^ b #a、b、両方に存在する要素以外の要素

文字列も集合型に変換できる。
a = "abcdefghijklmnopqrstuvwxyz"
b = "abcefhjkmnoqrtuwyz"

set(a) - set(b)
['d', 'g', 'i', 'l', 'p', 's', 'v', 'x']

set(a) | set(b)
['a', 'c', 'b', 'e', 'd', 'g', 'f', 'i', 'h', 'k', 'j', 'm', 'l', 'o', 'n', 'q', 'p', 's', 'r', 'u', 't', 'w', 'v', 'y', 'x', 'z']

set(a) & set (b)
['a', 'c', 'b', 'e', 'f', 'h', 'k', 'j', 'm', 'o', 'n', 'q', 'r', 'u', 't', 'w', 'y', 'z']

set(a) ^ set(b)
['d', 'g', 'i', 'l', 'p', 's', 'v', 'x']  
タグ :Python

Posted by 清水正行 at 09:09Comments(0)TrackBack(0)Python

2009年06月16日

画像を右に90度回転させつつ、JPG→JIF変換

元画像(JPG)から、Web用の画像(GIF)を作成したいが、元画像の数が1000を超えると変換作業も一苦労。グラフィックソフトのアクションやマクロなどでも可能なのだろうけど、変換作業のために重たいソフトをいちいち立ち上げるのも面倒なので、Pythonイメージングライブラリを使用して変換。
以下のソースを保存して、変換したい画像が納められているフォルダに入れ実行すれば、gifフォルダが作成され中に変換済みの画像が出力される。

import Image
import os
import glob

if os.path.isdir(os.getcwd()):
os.mkdir("gif")


for file in glob.glob("*.jpg"):
im = Image.open(file)
im2 = im.transpose(Image.ROTATE_270)
output = "./gif/" + file.replace("jpg", "gif")
im2.save(output,'gif')
  
タグ :PythonPIL

Posted by 清水正行 at 09:39Comments(0)TrackBack(0)Python

2009年05月26日

対話モードで覚えておくと便利な関数

import したモジュールのヘルプを見たいときは、help()
>>>import string
>>>help(string)

モジュールのヘルプが表示される。(英語だけど...)

あのメソッドなんだっけ? って時はdir()
>>> import urllib
>>> x = urllib.urlopen("http://www.google.ne.jp")
>>> dir(x)
['__doc__', '__init__', '__iter__', '__module__', '__repr__', 'close', 'fileno', 'fp', 'geturl', 'headers', 'info', 'next', 'read', 'readline', 'readlines', 'url']

モジュールで定義されている名前の一覧を表示してくれる。

変数の型を調べたいときはtype()
>>> a = 10
>>> type(a)
<type 'int'>
>>> a = "test"
>>> type(a)
<type 'str'>
>>> a = [1, 2, 3]
>>> type(a)
<type 'list'>
>>> a = (1, 2, 3)
>>> type(a)
<type 'tuple'>
>>> a = {1:1, 2:2, 3:3}
>>> type(a)
<type 'dict'>
>>> import urllib
>>> a = urllib
>>> type(a)
<type 'module'>
>>> a = urllib.urlopen
>>> type(a)
<type 'function'>
>>> a = urllib.urlopen("http://www.google.co.jp")
>>> type(a)
<type 'instance'>
  
タグ :Python

Posted by 清水正行 at 11:50Comments(0)TrackBack(0)Python

2009年05月17日

特殊フォルダのパスを得る

WScript.ShellオブジェクトではSpecialFoldersプロパティを得ることができる。

このプロパティはwindowsの特別なフォルダ(デスクトップやマイドキュメントなど)のパスを得ることができる。
>>> import win32com.client
>>> com = win32com.client.Dispatch("WScript.Shell")
>>> com.SpecialFolders("MyDocuments") #マイドキュメントのパスを取得
u'C:\\My Documents'
>>> com.SpecialFolders("Favorites") #「お気に入り」フォルダのパスを取得
u'C:\\WINDOWS\\Favorites'
>>> com.SpecialFolders("Recent") #「最近使ったファイル」のパスを取得
u'C:\\WINDOWS\\Recent'

windowsの使い捨てスクリプトを書くときに非常に便利。
  
タグ :Pythonwin32com

Posted by 清水正行 at 07:37Comments(0)TrackBack(0)Python

2009年05月06日

ファイルダウンロード

urllibのリファレンスに
urlretrieve( url[, filename[, reporthook[, data]) 

「URL で表されるネットワーク上のオブジェクトを、必要に応じてローカルなファイルにコピーします」ってあったので使ってみたのだけれど、コレ、404ファイルもダウンロード(?)してきちゃう。
指定したurlが間違っていても空ファイルが作られてしまう。困った。
とりあえず、吐き出すモンぜんぶ吐き出させて指定したurlのファイル有無を判定できるか調べてみる。
#!/bin/env python
# -*- coding: shift_jis -*-
import urllib

def feedback(count,size, total):
print "count :%d" % count
print "size :%d" % size
print "total :%d" % total

(file, header) = urllib.urlretrieve("http://www.google.co.jp/","test.html",feedback)
print file
print header

feedback ダウンロードのレポート(ブロックのカウントとサイズ、トータル)
file   指定したファイル名
header HTTP応答ヘッダ
応答ヘッダで判定すればいいのかな?
ググッてみつけたソースにこんなのがあった。
(tmp, headers) = urllib.urlretrieve("http://www.google.co.jp/","test.html")
if str(headers).count("Content-Length") == 0:
print "ERROR: File not found (404 error)"

headersの中のContent-Lengthの数を数えて、それが0だったら404エラーと判定しているみたい。
でも、これだとContent-Lengthさえ応答ヘッダに含まれていればやっぱり存在しないファイルでもダウンロードしてきちゃう orz
とりあえず試してみた
#!/bin/env python
# -*- coding: shift_jis -*-
import urllib

(tmp, headers) = urllib.urlretrieve("http://www.google.co.jp/aa/bb/cc.gif","test.gif")
print str(headers).count("Content-Length")
print headers
if str(headers).count("Content-Length") == 0:
print "ERROR: File not found (404 error)"
else:
print "OK"

ちゃんと"ERROR: File not found (404 error)"がでた。
でも、よく見るとgoogleの応答ヘッダには「Content-length: 1223」とある。
う~ん「Length」では「length」をカウントしないので404を出してしまう。やっぱり駄目ジャン。

……urllib2モジュールでは、ちゃんと404を検出するらしい。
>>> import urllib
>>> urllib.urlopen("http://www.google.co.jp/aa/bb/cc.gif")
>
>>> import urllib2
>>> urllib2.urlopen("http://www.google.co.jp/aa/bb/cc.gif")

Traceback (most recent call last):
File "", line 1, in -toplevel-
urllib2.urlopen("http://www.google.co.jp/aa/bb/cc.gif")
File "c:\Python23\lib\urllib2.py", line 129, in urlopen
return _opener.open(url, data)
File "c:\Python23\lib\urllib2.py", line 326, in open
'_open', req)
File "c:\Python23\lib\urllib2.py", line 306, in _call_chain
result = func(*args)
File "c:\Python23\lib\urllib2.py", line 901, in http_open
return self.do_open(httplib.HTTP, req)
File "c:\Python23\lib\urllib2.py", line 895, in do_open
return self.parent.error('http', req, fp, code, msg, hdrs)
File "c:\Python23\lib\urllib2.py", line 352, in error
return self._call_chain(*args)
File "c:\Python23\lib\urllib2.py", line 306, in _call_chain
result = func(*args)
File "c:\Python23\lib\urllib2.py", line 412, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
HTTPError: HTTP Error 404: Not Found
>>>

ちゃんと例外がでる、やっぱりurllib2を使ったほうがいいみたい。

  
タグ :Pythonurllib

Posted by 清水正行 at 17:31Comments(0)TrackBack(0)Python

2009年04月24日

被リンク数をチェックする

練習にYahoo! サイトエクスプローラーを使って、被リンク数を取得するスクリプトを書いてみました。ただ被リンクのあるURLだけ取得してくるのもなんなので、ついでに被リンクの多いドメインを降順で表示してみる。

Yahoo! サイトエクスプローラーの検索結果の解析にはBeautifulSoupを使用。

import urllib2
import BeautifulSoup


def Backlinkcheck(query, depth=0):
backlink = []
depth = (depth+1) * 10
if depth < 0 : depth=0


for i in range(0,depth,10):
yahooSearch = "https://siteexplorer.search.yahoo.co.jp/advsearch?&st=inlinks&si=il&uf=esd"
yahooSearch = yahooSearch + "&b=" + str(i) + "&p=" + query

html = urllib2.urlopen(yahooSearch)
soup = BeautifulSoup.BeautifulSoup(html)

for aTag in soup.body.table.findAll('a'):
backlink.append(aTag.string)

backlink.sort()
domein = [i.split("/")[0] for i in backlink]
domeinConut = []
for i in set(domein):
domeinConut.append((i, domein.count(i)))


print "Domein:"
domeinConut.sort( cmp=lambda x, y: cmp(x[1], y[1]), reverse=True )
for i, j in domeinConut:
print i + ":" + str(j)

print
print "BacklinkURL:"
for i in backlink:
print i

if __name__ == '__main__':
url = "http://hoge.hoge"
Backlinkcheck(url, 10)


Backlinkcheck(<チェック対象URL>,<ページ指定>)として使用。
Yahoo! サイトエクスプローラーは検索結果を1ページ(10件)しか表示してくれないらしいので、何ページまで取得するかを指定することにした。0から数えて指定してください。

補足:
for aTag in soup.body.table.findAll('a'):
backlink.append(aTag.string)
Yahoo! サイトエクスプローラーの検索結果はテーブルタグに囲われて返ってくるので、テーブルタグ内のaタグのみを対象にループを回してアンカーテキストを取得。


for i in set(domein):
domeinConut.append((i, domein.count(i)))
domeinリストの重複をset関数で削除しループさせ、重複したドメイン名のカウント数をタプルにし、2次元配列としてdomeinConutに追加している。domeinConutの内容は以下のようなリストになる。
domeinConut = [("ドメイン名",重複カウント数),("ドメイン名",重複カウント数),…]
なんかもっと上手い方法がありそうだけど、これしか思いつかなかった。

domeinConut.sort( cmp=lambda x, y: cmp(x[1], y[1]), reverse=True )
domeinConutリストをタプルの2番目の要素(重複カウント数)を対象に降順にソートしています。

  

Posted by 清水正行 at 15:38Comments(0)TrackBack(0)Python