一些有用的Python库
Update @ 2011-03-06, 15:02:57
你有没有使用过的觉得不错的Python库?请到这里跟大家分享:常用的 Python 库:请投票
——————————————————-
今天整理C盘,看到python还是2.6,就给更新到了2.7,再更新所有的site-packages过程中,搜到了这个网页:
http://wiki.python.org/moin/UsefulModules
网页中列出了一堆有用的库,其中有一些我曾经用过或者比较感兴趣的,选了一些混合我现在常用的lib列在下面:
Easy Install: easy_install 安装工具,下面提到的多数lib都能用easy_install lib_name进行安装
SQLAlchemy, SQLObject, Mysql-Python(Win32安装包):数据库访问,发芽网后台用到了Mysql-Python
CTypes - 直接调用dll中的函数,经常用来做Windows API的调用
WxPython - Python UI库,Ulipad就是基于这个
Ascii_table:在命令行界面中输出漂亮的表格
Python Imaging Library (PIL) :图片处理,发芽网的Captcha用到了这个
PyAudio:WAV文件读写,录音,用这个写过一个录音工具,还不错
HTTPLib2:非常好用的http工具,做cookie、put请求、header、错误处理等等很方便,可以做网络爬虫或者访问webservice的脚本
Psyco :只要简单的写下如下两句话,就能让你的python脚本快很多,在需要很多计算的脚本里很好用,求解华容道时试过,速度改进的不错,虽然最后还是没有达到要求,改用C++写了一个:
import psyco psyco.full()
PyObjC: Python写ObjectiveC/cocoa程序作为一个遗憾放在这儿吧,要是支持iOS就好了
PyWin32 :针对win32常用的系统api做了很好的封装,用这个写过一个彩色命令行脚本
NumPy, SciPy, Matplotlib:科学计算的三神器,更多参见这里。有本在线的书:用Python做科学计算,旅居日本的hyry写的,值得一看
Py2exe: 把你的python脚本转成exe可执行程序,曾经用过,仅支持到python2.5所以最近没用过了
Django:使用最多的Python web framework,发芽网也是基于Django
lxml:XML文件处理的利器。最近两年有点儿烦HTML,改用json了
iPython: 更加好用的Python命令行交互环境
python-openid:Python下做OpenID,都得用这个,发芽网的OpenID支持也是基于这个做的
Python urllib2的使用点滴: cookie, https, put, 500/403的处理
Update @ 2011-03-06, 13:46:08
刚刚发现了一个比urllib2更好用的库httplib2,可以比较简单的解决本文遇到的一些问题
http://code.google.com/p/httplib2/
————————————————————
最近用urllib2写了一个公司内部用的脚本
这个脚本要访问一个webservice,访问之前先要用https登陆拿到cookie再到另一个地方获取一个临时用的id
https登陆,获取cookie
首先是https登陆,这段很好写,以前写过校内网发帖机,轻车熟路,用cookielib的CookieJar加上HTTPCookieProcessor搞定,代码如下(其中那个超简单的lambda hack简直绝了:
# -*- coding: utf-8 -*-
import urllib, urllib2, sys, cookielib, re, os, json
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
url_login = 'https://xxx.yahoo.com/login/'
body = (('username', '半瓶墨水'),
('password', '密码'),
('action', 'login'),)
print 'login to get cookies'
opener.open(url_login, urllib.urlencode(body))
处理HTTP 403/500 Exception
但是后面用cookie去拿id的时候,就老是告诉我403错误,然后opener就抛异常,想问题想到头大,后来发现这个服务访问成功不是返回200,而是403,所以看到403的时候不要管他,直接看body内容就行了,日,不知道为什么这么设计。
怎么办呢?查了一下urllib2的文档,发现可以继承一下HTTPCookieProcessor,自己做了一个NoExceptionCookieProcesser,后来的过程中发现webservice有时候返回400和500的时候body中包含有用的信息,一并处理了:
# -*- coding: utf-8 -*-
import urllib, urllib2, sys, cookielib, re, os, json
#suppress the 403/400/500 exception and return the body
class NoExceptionCookieProcesser(urllib2.HTTPCookieProcessor):
def http_error_403(self, req, fp, code, msg, hdrs):
return fp
def http_error_400(self, req, fp, code, msg, hdrs):
return fp
def http_error_500(self, req, fp, code, msg, hdrs):
return fp
cj = cookielib.CookieJar()
opener = urllib2.build_opener(NoExceptionCookieProcesser(cj))
url_login = 'https://xxx.yahoo.com/login/'
body = (('username', '半瓶墨水'),
('password', '密码'),
('action', 'login'),)
print 'login to get cookies'
opener.open(url_login, urllib.urlencode(body))
urllib2中用PUT进行请求
然后又发现一个问题,webservice在提交的时候要求用PUT方式,并且只接受json,urllib2默认只支持GET和POST,Google了一下,发现可以创建Request对象,然后更改它的请求方法(get_method)以及header,搞定:
request = urllib2.Request(url_ws, data="blablabla")
request.add_header('Content-Type', 'application/json')
request.add_header('Accept', 'application/json')
request.get_method = lambda: 'PUT'
result = opener.open(request).read().strip()
参考:http://stackoverflow.com/questions/111945/is-there-any-way-to-do-http-put-in-python
tagwin - windows命令行利器 - 利用标签在文件夹中快速跳转
Update @ Tuesday, March 1, 2011, 18:26:54: Fix 一些小问题,最新版是1.1
前两天看到了Dreamers’s blog:Bash 小技巧:给目录加上书签,快速切换目录(bashmarks),感觉用批处理脚本实现应该不难
套用Dreamer的一段话(略改):
当我们在命令行下面做开发的时候,很大一部分时间都浪费在了目录切换上面,相信不少人每天敲 “cd” 都敲得想吐。如果目录层次多一点,Tab 键也会饱受摧残。虽然Windows命令行有内置的 “cd -”, “pushd” 和 “popd” 命令,但用起来都不是很顺手。
如果能用几行简单的 Batch 脚本巧妙地给目录加上了书签,这样你就可以给最常用的那几个工作目录加上书签,不需要每次都敲 cd 了。还可以在各个常用的文件夹之间来回快速切换。
当天晚上回来就实现了第一版,感觉很是不错,由于一直没有时间写博,留到今天才拿出来跟大家分享
使用方法:
1. 点击此处下载: http://www.2maomao.com/blog/wp-content/uploads/tagwin-dglt-11.zip
(或者尝试 这个链接)
2. 解压所有文件到系统PATH包含的任意目录下
3. 打开命令行,进入要加标签的目录
t abc —> 给当前目录加标签为abc
g abc —> 切换到标签为abc的目录
d abc —> 删除标签abc
l ———–> 列出所有标签
在你解压缩的那个目录找到dglt.list文件,里面是所有的标签,也可以通过编辑这个文件来管理
另外在Google Code建了一个项目用来保存最新的代码,有兴趣的可以去看看代码:
http://code.google.com/p/tagwin-dglt/
使用演示:
D:\projects>t proj proj D:\projects D:\projects>cd py\django\fayaa D:\projects\py\django\fayaa>t fayaa fayaa D:\projects\py\django\fayaa D:\projects\py\django\fayaa>pushd g:\relax\movie G:\relax\movie>t movie movie G:\relax\movie G:\relax\movie>g proj D:\projects>g fayaa D:\projects\py\django\fayaa>g movie G:\relax\movie>l Tagged Folders -------------- proj D:\projects fayaa D:\projects\py\django\fayaa movie G:\relax\movie
把Picasa加星标的图片一次性导出
年前买了个千万级的照相机,再加上不加节制的使用,200G的硬盘开始不够用了,为了节省空间,决定把多数照片放在一个不是很常用的地方+刻盘,只把选择出来的照片留下
为了达到这个目标,现在安装的Faststone Image Viewer就不是很好用,安装的光影看看更是管理图片的废材。最后Google了一下,发现最好用的还是Picasa。
下载了最新版,又花了过年的三四天的精选了照片,最后想把照片导出的时候遇到问题了,一共四五十个文件夹,Picasa并没有提供一次性导出的功能,只能一个文件夹一个文件夹的导出。最后还是决定写个脚本来搞定,研究了一下,发现每个目录下都有个.picasa.ini文件,格式十分简单,比如这个:
[IMG_0152.JPG] faces=rect64(78f63255a1427ae3),155499df12e3d390 backuphash=4191 star=yes
其中的star=yes代表该照片已加星标。这就简单了,半小时写,十分钟导出,搞定!
脚本如下,注意脚本运行完以后生成了一个叫做copystar_go.bat的批处理文件,执行它才是真正的导出,这本来是调试用的,后来发现可以手工控制删掉一些不需要的导出操作(用Vim很快的),就没改回来,不多说,上代码:
# -*- coding: utf-8 -*-
#
#Purpose: export all picasa stared photos under a folder and it's subfolders
# because Picasa doesn't support - it only can export one folder once
#
# Reach me via: realfun AT gmail DOT com
#
# http://2maomao.com/blog/py-script-export-all-stared-photos-in-picasa/
# http://www.google.com/profiles/realfun
# 2011-02-22, 22:26:28
from os import walk
from os.path import join
#damn python encoding hack
import sys
reload(sys)
sys.setdefaultencoding("gb2312")
PICASA = '.picasa.ini'
PICASA_OLD = 'Picasa.ini'
TARGET = 'G:\\ipad\\sync\\temp\\'
def get_stars(dir, picasa):
stars = []
last = None
for line in open(join(dir, picasa)).readlines():
line = line.rstrip("\n")
if line.startswith("[") and line.endswith("]"):
last = line[1:-1].decode("utf-8")
elif line.startswith("star=yes"):
stars.append(last)
return stars
out = open("copystar_go.bat", "wb")
for root, dirs, files in walk("."):
picasa = None
if PICASA in files:
picasa = PICASA
elif PICASA_OLD in files:
picasa = PICASA_OLD
if picasa:
stars = get_stars(root, picasa)
for star in stars:
line = 'robocopy "%s" "%s" "%s"\r' % (root, join(TARGET, root), star)
print >>out, line
SRT subtitle splitter,字幕分割程序,in Python
Verycd终于顶不住了
这周末整理了一下从Verycd上面拖下来的一百多G电影,发现教父1/2/3依然没有看过,想要看看才发现没字幕,射手影音也没下载到,只好到射手网上面去找,找到了几个都是一个字幕到底的;于是Google字母分割工具,一边找一边感叹下载站的没落,连国外的下载站也开始搞中国这一套欺骗点击的骗术。
找了半天,没找到一个可用的,有那么几个软件,用起来完全达不到自己的要求;
研究了一下srt的格式,自己写了段python脚本,居然花了一个小时,不过总算搞定了,代码如下:
# -*- coding: utf-8 -*-
#Author: 半瓶墨水 # 2011-02-20, 13:59:14
#Email : realfun AT gmail DOT com
#Usage : split srt files
#Examples:
# 将"教父.srt"分两段,起始时间向前错位29秒
# 第一段长1小时45分48秒,依次为第二段第三段,剩下的为第四段
# srt.py 教父.srt offset=00:00:29 00:42:55 00:46:24 00:42:39
# *NOTICE* Serial number is not handled
#
#写这段代码主要是因为,从Verycd上面下的教父没找到对应的字幕;Verycd is Gone
import sys, os
def srttime2int(st):
""”
>>> srttime2int("-00:01:19")
-79000
>>> srttime2int("00:01:19")
79000
>>> srttime2int("10:21:29")
37289000
>>> srttime2int("00:01:19,601")
79601
>>> srttime2int("10:21:29,601")
37289601
""”
flag = False
if st[0] == '-':
flag = True
st = st[1:]
value = ((int(st[0:2])*60+int(st[3:5]))*60+(int(st[6:8])))*1000+int(st[9:12] or 0)
return flag and -value or value
def int2srttime(i):
""”
>>> int2srttime(-79601)
'-00:01:19,601'
>>> int2srttime(79601)
'00:01:19,601'
>>> int2srttime(37289601)
'10:21:29,601'
""”
flag = False
if i<0:
i = -i
flag = True
srttime = "%02d:%02d:%02d,%03d" % (i/3600000, i%3600000/60000, i%60000/1000, i%1000)
return flag and '-' + srttime or srttime
def srt_split():
if len(sys.argv) < 3:
print "\n\n\tplease read source code for usage\n\n"
sys.exit(0)
filename = sys.argv[1]
splits = sys.argv[2:]
offset = 0
if splits[0].startswith("offset="):
offset = srttime2int(splits[0][len("offset="):])
splits = splits[1:]
splits.append("24:00:00") #assume no more than 24 hours
splits = [srttime2int(s) for s in splits]
lines = open(filename, "rb").read().splitlines()
f = open("001.srt", "wb")
newlines = []
count = 0
limit = splits[0] + offset
for line in lines:
#00:01:16,564 –> 00:01:18,532
if len(line)>=29 and line[13:16] == "–>":
start = srttime2int(line[:12])
end = srttime2int(line[17:])
if start > limit:
f.writelines(newlines)
f.close()
newlines = []
offset += splits[count]
count += 1
limit += splits[count]
f = open("%03d.srt" % (count+1), "wb")
line = int2srttime(start - offset) + " –> " + int2srttime(end - offset)
newlines.append(line + "\r\n")
f.writelines(newlines)
f.close()
if __name__ == "__main__":
import doctest
doctest.testmod()
srt_split()


