一些有用的Python库

作者:半瓶墨水 链接:http://www.2maomao.com/blog/useful-python-libs/

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支持也是基于这个做的

Pygements代码发芽网的高亮,用的就是这个库,略该,以适应直接复制粘贴的需求

nose:python下的测试驱动工具,曾经用过,很简洁。现在我用doctest更多一点

  • Share/Bookmark

Python urllib2的使用点滴: cookie, https, put, 500/403的处理

作者:半瓶墨水 链接:http://www.2maomao.com/blog/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简直绝了:

#! /usr/bin/env python
# -*- 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中包含有用的信息,一并处理了:

#! /usr/bin/env python
# -*- 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

  • Share/Bookmark

tagwin - windows命令行利器 - 利用标签在文件夹中快速跳转

作者:半瓶墨水 链接:http://www.2maomao.com/blog/win32-folder-tagging-scripts/

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
  • Share/Bookmark

把Picasa加星标的图片一次性导出

作者:半瓶墨水 链接:http://www.2maomao.com/blog/py-script-export-all-stared-photos-in-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很快的),就没改回来,不多说,上代码:

Python语言: Export all stared photos in Picasa once
#! /usr/bin/env python
# -*- 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

  • Share/Bookmark

SRT subtitle splitter,字幕分割程序,in Python

作者:半瓶墨水 链接:http://www.2maomao.com/blog/srt-subtitle-splitter-in-python/

Verycd终于顶不住了

这周末整理了一下从Verycd上面拖下来的一百多G电影,发现教父1/2/3依然没有看过,想要看看才发现没字幕,射手影音也没下载到,只好到射手网上面去找,找到了几个都是一个字幕到底的;于是Google字母分割工具,一边找一边感叹下载站的没落,连国外的下载站也开始搞中国这一套欺骗点击的骗术。

找了半天,没找到一个可用的,有那么几个软件,用起来完全达不到自己的要求;
研究了一下srt的格式,自己写了段python脚本,居然花了一个小时,不过总算搞定了,代码如下:

Python语言: SRT subtitle splitter,字幕分割程序
#! /usr/bin/env 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()

  • Share/Bookmark