2010年05月05日

名前空間のつまらないネタ


1. アンダーバーで始まるけど見える・・・
# module1.py

def func1():
print "this is func1."

# アンダーバーで始まる名前の変数、関数、クラスは
# 外部からは見えないけど・・・
def _func2():
print "this is _func2."

# __all__ に定義すればモジュールの外から見える。
#  特に意味も無いが。。。

__all__ = ['func1', '_func2']



2. グローバル変数を無理やり定義しちゃう
__builtins__.func = lambda x, y: x * y
__builtins__.foo = 'something'

print foo
print func(5, 8)

どこでも利用可能になる。
これは一般的に当然お勧めしないやり方。

どうしてもグローバル変数を使いたいのなら、
# my_globals.py 
foo = 'something'
============
import my_globals
print my_globals.foo

モジュールを使用するのが、まだクリーンな方法。
 

2010年05月03日

HTMLを解析(スクレイピング)する

HTML解析に使用するライブラリ

・BeautifulSoup.py
 Pure-Python で書かれている。大きなページだと処理速度は遅い。

・HTMLの解析は、やはり、XPathで行うのが簡単でラク。

XPath が使える主なHTML解析ライブラリには、
  lxmllibxml2
 の2つがある。

XPath 言語仕様

1. lxmlを使った例

finance.yahoo.comから、グーグルの最新株価を取得する
import urllib
import lxml.html

fd = urllib.urlopen('http://finance.yahoo.com/q?s=GOOG')
s = fd.read().decode('utf-8')
xRoot = lxml.html.fromstring(s)
path = '''string(
//tr[
th/text() = 'Last Trade:' or
th/text() = 'Index Value:'
]/td[1])'''


print xRoot.xpath(path)



・2. libxml2を使った例
import libxml2
doc = libxml2.htmlReadFile('http://www.yahoo.co.jp', 'utf-8'
libxml2.HTML_PARSE_RECOVER |
libxml2.HTML_PARSE_NOERROR |
libxml2.HTML_PARSE_NOWARNING
)
#全てのAタグのリンク先を表示する
nodes = doc.xpathEval("//a[@href]")
links = list([x.prop('href') for x in nodes])
doc.freeDoc()
print links

注意) libxml2 のPythonバインディングは、メモリ管理を手動で行う必要がある。freeDoc(), xpathFreeContext() を忘れると、すぐにメモリリークする。

def debugRun():
debugMemory(1)
try:
main() #メモリリークをテスト
finally:
cleanupParser()
print "Memory leak %d bytes" % (debugMemory(1))
dumpMemory()


現時点では、lxmlのほうが使いやすい。

URLから読み込むには

特定のURLからデータを読み込むスクリプトを書いてみます。
Pythonには、標準ライブラリの
  urllib,
  urllib2,
  httplib
 の3つにクラスと関数が用意されている。

1. urllib を使う方法
import urllib

url = "http://www.yahoo.co.jp/"
fd = urllib.urlopen(url)
header = fd.info()
print "Content Type is %s" % header["Content-Type"]
data = fd.read()
print data
fd.close()

ソケット接続に失敗すると、例外 IOError が発行される。
しかし、urllib.urlopen() は、サーバーのレスポンスが 404を返しても例外にはならない。


2. urllib2 を使う方法
 urllib2.urlopen() は、HTTP認証、クッキーなどがサポートされているほかは urllib.urlopen() と同じ。

サーバーがステータスコード 404を返したときには、例外 urllib2.HTTPError になる。
この例外のインスタンスには、read()メソッドがあって、
そのままエラーストリームにアクセスできる。
try:
fd = urllib2.urlopen(url)
#ストリームが正常に開かれた
data = fd.read()
except urllib2.HTTPError, e:
#404を返した
data = e.read()

リクエストヘッダーを付加して呼ぶ
req = urllib2.Request('http://www.example.com/')
req.add_header('Referer', 'http://www.python.org/')
req.add_header('User-Agent', 'Mozilla/5.0')
r = urllib2.urlopen(req)

・エラーストリームとは?
接続に失敗しても、サーバーがデータを送ってきた場合には、エラーストリームからデータを読み取ることができる。よくある例として、HTTP サーバがコード 404で応答したときにサーバーから対処策を指示する HTMLヘルプページが送信されることがある。

・参考
Java の HttpURLConnectionクラスの解説

2010年04月11日

Python で fc2ブログに投稿する

#encode: shift_jis
import xmlrpclib
import sys


def main():
server_url = 'http://blog.fc2.com/xmlrpc.php'
blog_id = 'myblog' #http://myblog.blogNum.fc2.com/
username = 'xxx@xxx.com' #mail
password = 'xxxxx'

server = xmlrpclib.Server(server_url)

entry_id = server.metaWeblog.newPost(
blog_id,
username,
password,
{
'title': u'記事の',
'description': '記事の内容',
},
xmlrpclib.True)
print entry_id


if __name__ == "__main__":
main()

2006年06月14日

日本語を扱う - 2. 文字列とユニコード文字列

Python には、文字列型とユニコード型の二つのタイプが存在します。この二つのタイプは、暗黙的に変換されることがあるので、型の違いがわからないと頻繁にエラー (UnicodeError) が出て悩むことが多いです。

ユニコード文字列の定数は、最初に u をつけます。
uni_str = u"あいうえお"
(スクリプトの最初にエンコードを書いておく必要)

・RAW文字列
 r"abc" のように、文字列定数の頭に r をつけるとRAW文字列になります。Pythonでの文字列は、CやJAVA言語と同様に ¥(円記号または逆スラッシュ)はエスケープシーケンスです。
Windowsでのパスのように、文字列の中で円記号そのものを含める必要がある場合は、¥¥のように二つ続けて書く必要があります。しかし、正規表現を書く場合など、円記号だらけで読みづらくなってしまいます。そこでRAW文字列を使うと読みやすくなります。
"c:\\windows\\"  # 通常の文字列
r"c:\windows\" # RAW文字列
ur"c:\windows\" # ユニコードRAW文字列

2006年06月13日

Pythonでゲームを作る - Pygame

 Pygameとは、PythonからSDLというマルチメディアライブラリへのアクセスを可能にするラッパーです。これを使うと、簡単に画像やサウンド等をPythonでのプログラミングに使えるようになります。
SDLとPythonは多くのプラットホーム(OS) に移植され対応しているので、pygameを使って書くとマルチプラットホーム対応のゲームが作れます。

Pythonを使えば、面倒なメモリ開放など気にしなくてもいいので楽です。

参考リンク
 ・Pygame
 ・Pygame チュートリアル
 ・PygameではじめるPython入門ツアー


#encoding: shift_jis
import sys
import pygame, pygame.font
import pygame.cursors
from pygame.locals import *


def main():
#initialize
pygame.init()
resolution = 800, 200
screen = pygame.display.set_mode(resolution)
pygame.mouse.set_cursor(*pygame.cursors.diamond)

fg = 250, 240, 230
bg = 5, 5, 5
wincolor = 40, 40, 90

# フォントの場所は各自調整してね。
if sys.platform == 'win32':
msgothic = r'c:\windows\fonts\msgothic.ttc'

else:
msgothic = '/usr/X11R6/lib/X11/fonts/TrueType/msgothic.ttc'

#fill background
screen.fill(wincolor)

#load font, prepare values
font = pygame.font.Font(msgothic, 60)
text = u'漢字フォント'

size = font.size(text)

#no AA, no transparancy, normal
ren = font.render(text, 0, fg, bg)
screen.blit(ren, (10, 10))

#no AA, transparancy, underline
font.set_underline(1)
ren = font.render(text, 0, fg)
screen.blit(ren, (10, 40 + size[1]))
font.set_underline(0)

#AA, no transparancy, bold
font.set_bold(1)
ren = font.render(text, 1, fg, bg)
screen.blit(ren, (30 + size[0], 10))
font.set_bold(0)

#AA, transparancy, italic
font.set_italic(1)
ren = font.render(text, 1, fg)
screen.blit(ren, (30 + size[0], 40 + size[1]))
font.set_italic(0)

#show the surface and await user quit

pygame.display.flip()
while 1:
#use event.wait to keep from polling 100% cpu
if pygame.event.wait().type in (QUIT, KEYDOWN, MOUSEBUTTONDOWN):
break

if __name__ == '__main__':
main()


このサンプルの実行結果


2006年03月24日

日本語を扱う - 1. はじめに

Pythonでも当然、日本語を処理することができます。バージョン2.4からはShift-JIS、EUC-JPなどのエンコードが標準ライブラリに用意されています。

ただし、日本語が含まれているPythonのスクリプトを実行すると、次のような警告が表示されてしまいます。

sys:1: DeprecationWarning: Non-ASCII character '\x82' in file
(ソースコードに Shift-JISで『あ』の文字が含まれていた場合)

これを回避するには、まずスクリプトの一行目または二行目に、このソースの文字コードを指定してやる必要があります。

例.
# encoding: shift_jis


CGIのスクリプトの場合は、先頭にPythonのパスを書く必要があるので、二行目に書いておきます。
#!/usr/local/bin/python
# encoding: shift_jis


2006年02月28日

ブログのトラックバックを送信するには

 ブログのトラックバックの仕組みがいまいち理解できなかったので調べてみました。意外にも簡単な仕組みでした。

・ブログ名 - blog_name
・記事への URL - url
・記事のタイトル - title
・本文の抜粋 - excerpt

これらのパラメータをPing送信先のURLにPOSTで送ればいいだけです。Pythonなら数行でできてしまいます。日本語が含まれているのなら、文字化けしないように UTF-8 でエンコードしてやります。

# encoding: shift_jis
import urllib

def sendTrackback(tr_url, blog_name, url, title, excerpt):
  post_data = urllib.urlencode({
     'title': title.encode("utf-8"), 
     'url': url, 
     'excerpt': excerpt.encode("utf-8"), 
     'blog_name': blog_name.encode("utf-8")
  })
  return urllib.urlopen(tr_url, post_data)

def main():
  tr_url = "TrackBack の URL をここに"

  # ブログ名
  blog_name = u"Python Tips"
  # 記事への URL
  url = "http://python-tips.seesaa.net/"
  # 記事のタイトル
  title = u"スクリプト言語 Python の「ツボ」"
  # 本文の抜粋
  excerpt = u"Python(パイソン)は Guido van Rossumによって.."

  f = sendTrackback(tr_url, blog_name, url, title, excerpt)
  # 応答を表示
  print f.read()
    
if __name__ == "__main__":
  main()

2006年02月26日

TeraPadを準備する

 Pythonでちょっとしたスクリプトを書く際に便利なのが、TeraPad というシンプルなエディタです。複数の文字コードと改行に対応しているので、Windowsで書いてLinuxで試す、といった場合に便利。

・TeraPad の「ツール」にPythonのインタプリタを登録する
 1. TeraPadの「ツール」メニューから「ツールの設定」を押す。
 2. 「追加」ボタンを押す。
 3. 「名前」の欄に「Python実行」と入力する。
 4. 「実行ファイル」欄は cmd と入力する。
 5. 「コマンドラインパラメータ」は /K CD %d && python %n とする。

これで「ツール」メニューからスクリプトを実行することができます。

2006年02月25日

ブログの更新を通知するPythonスクリプト

pingtest.py
# coding: shift_jis
import xmlrpclib

pingservers = """
http://ping.bloggers.jp/rpc/
http://www.blogpeople.net/servlet/weblogUpdates
http://ping.cocolog-nifty.com/xmlrpc
http://ping.myblog.jp/
http://blog.goo.ne.jp/XMLRPC
http://ping.exblog.jp/xmlrpc
http://www.blogoon.net/ping/
http://blogdb.jp/xmlrpc
"""

def weblogUpdatesPing(pingserver, blogname, blogurl):
  svr = xmlrpclib.Server(pingserver)
  return svr.weblogUpdates.ping(blogname, blogurl)


def main():
  for pingurl in pingservers.splitlines():
    if not pingurl:
      continue
    try:
      blogname = "Python Tips"

      blogurl = "http://python-tips.seesaa.net/"
      response = weblogUpdatesPing(pingurl, blogname, blogurl)
      if int(response['flerror']) != 0:
        raise Exception, response['message']

      print "%s - 成功" % pingurl
      print " ", response['message']
    except Exception, e:
      print "%s - 失敗 %s" % (pingurl, e)


if __name__ == "__main__":
  main()
このようなメッセージが返答されれば Ping成功。
http://blog.goo.ne.jp/XMLRPC - 成功
Thanks for the ping.
Pingサーバーごとに、「Thanks for the ping」のメッセージが異なったりしていて面白いです。
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。