标签归档:python

linux下使用imagemagick批量生成缩略图的python脚本

linux下使用imagemagick批量生成缩略图的python脚本。程序用了递归,可以查找目录下所有的图片按照一定的规则生成指定宽度的缩略图。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#批量resize当前目录下的图片,linux测试过。
#使用imagemagick

import os, sys

iswindows = 'win32' in sys.platform.lower() or 'win64' in sys.platform.lower()
isosx     = 'darwin' in sys.platform.lower()

def convert(dirname, size='400*400'):

    for filename in os.listdir(dirname):

        if "thumbs" in filename or "cache" in filename:
                continue
        filename = os.path.join(dirname, filename)

        if os.path.isdir(filename):
                convert(filename, size)
        elif filename.lower().endswith("jpg"):
                tname=filename.rsplit('/',1)
                thumb_filename= "%s%s%s" % (tname[0],"/thumbs/thumbs_",tname[1])
                cmd = "/usr/local/imagemagick/bin/convert \"%s\" -resize %s \"%s\"" % (filename, size, thumb_filename)
                print "process.", filename
                #print cmd
                os.system(cmd)
if __name__ == "__main__":

    if len(sys.argv) >= 2:
        size = sys.argv[1]
    else:
        size = "400"
	#convert 当前目录下的所有图片
    convert('.', size)

怎么给python添加新的lib path

python读取类库的顺序是,当前目录,pythonpath,path和安装目录。可以动态的设置pythonpath如下:

Python 2.6.3 (r263rc1:75186, Oct  2 2009, 20:40:30) [MSC v.1500 32 bit (Intel)]
on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', 'C:\\Python26', 'C:\\Windows\\system32\\python26.zip', 'C:\\Python26\\DLLs',
 'C:\\Python26\\lib', 'C:\\Python26\\lib\\plat-win', 'C:\\Python26\\lib\\lib-tk'
, 'C:\\Python26\\lib\\site-packages']
>>> sys.path.append('c:\\path')
>>> sys.path
['', 'C:\\Python26', 'C:\\Windows\\system32\\python26.zip', 'C:\\Python26\\DLLs',
 'C:\\Python26\\lib', 'C:\\Python26\\lib\\plat-win', 'C:\\Python26\\lib\\lib-tk'
, 'C:\\Python26\\lib\\site-packages', 'c:\\path']
>>>

还有就是修改环境变量。增加一个PYTHONPATH
windows比较讨厌的是有空格问题。
在系统变量里面增加一个变量PYTHONPATH
值是:

C:\\Program Files (x86)\\Google\\google_appengine;C:\\Program Files (x86)\\Google\\google_appengine\\lib\\antlr3;C:\\Program Files (x86)\\Google\\google_appengine\\lib\\django;C:\\Program Files (x86)\\Google\\google_appengine\\lib\\webob;C:\\Program Files (x86)\\Google\\google_appengine\\lib\\yaml\\lib;C:\\Program Files (x86)\\Google\\google_appengine;

只是gae执行起来还是有点问题,保存modle的时候,说没有app id。咳。
———–
python 2.6 开始,好像支持在site-packages目录下建xxx.pth的文件,把要include的lib path写进去即可。这个方便,易于维护。不错
更多可以看这个 http://docs.python.org/library/site.html

python版本的jquery

jquery在做html内容提取,分析的时候很方便。而python做类似的工作就麻烦一点,原来我都是用正则表达式或者HtmlParser的。
两者用着都不是太爽,今天发现了一个好东西 pyquery ,一个类似jquery的python库。
摘抄一段使用说明

>>> from pyquery import PyQuery as pq
>>> from lxml import etree
>>> d = pq("<html></html>")
>>> d = pq(etree.fromstring("<html></html>"))
>>> d = pq(url='http://google.com/')
>>> d = pq(filename=path_to_html_file)

Now d is like the $ in jquery:

>>> d("#hello")
[<p#hello.hello>]
>>> p = d("#hello")
>>> p.html()
'Hello world !'
>>> p.html("you know <a href='http://python.org/'>Python</a> rocks")
[<p#hello.hello>]
>>> p.html()
'you know <a href="http://python.org/">Python</a> rocks'
>>> p.text()
'you know Python rocks'

简单吧,安装也很简单
下载
http://pypi.python.org/packages/source/p/pyquery/pyquery-0.3.tar.gz
解压缩
python setup.py install
就可以了,可能要安装ezsetup
现在的版本是0.3,还有一些jquery的东西没有实现,比如:radio,:password,以及一些ajax的功能,但是已经够用了,强烈推荐。
赶紧试试吧。

还有一个BeautifulSoup,也推荐一下

django学习笔记

最近在看django,觉得这种快速开发的framework还是不错的。
但是也有他们存在的问题,尤其是刚开始不久的。兼容性是个大问题。一样的代码,升级了就不能用。
在做django管理试验的时候就遇到了问题,老板本的就不说了,我用的1.0.2是要做如下操作才可以。
urls.py
去掉

from django.contrib import admin
admin.autodiscover()
(r'^admin/(.*)', admin.site.root),

前面的注释
setting.py
INSTALLED_APPS
添加
‘django.contrib.admin’,
要建立一个admin.py,内容如下:

from django.contrib import admin
from jobs.models import Job
class JobAdmin(admin.ModelAdmin):
    pass
admin.site.register(Job, JobAdmin)

其中Job是model的类名字

还有,需要修改
models.py里的
__str__ 为 __unicode__
不然会出现
Caught an exception while rendering: ‘ascii’ codec can’t encode characters in position 0-2: ordinal not in range(128)

python的settimeout

有时候写python关于网络的程序。比如用urllib2等module发http请求的时候,发现有时候会有死掉的情况,就是程序没任何反应,也不是cpu,内存没资源的问题。具体情况还没搞明白那里出的问题,但是找到一个解决办法。就是设置socket time out,即:如果一个请求超过一定的时间没有完成,就终止,再次发起请求。
这个是从2.3有的功能用法如下:
settimeout( value)
Set a timeout on blocking socket operations. The value argument can be a nonnegative float expressing seconds, or None. If a float is given, subsequent socket operations will raise an timeout exception if the timeout period value has elapsed before the operation has completed. Setting a timeout of None disables timeouts on socket operations. s.settimeout(0.0) is equivalent to s.setblocking(0); s.settimeout(None) is equivalent to s.setblocking(1). New in version 2.3.

就是settimeout()里面填一个数值。小心别太小,别正常的请求也不能完成。

转贴一个Python HTMLParser的使用例子

原文
http://crquan.blogbus.com/logs/8269701.html

#!/usr/bin/env python

import sys
import urllib
import HTMLParser
 
class CustomParser(HTMLParser.HTMLParser):
    selected = ('table', 'h1', 'font', 'ul', 'li', 'tr', 'td', 'a')
    
    def reset(self):
        HTMLParser.HTMLParser.reset(self)
        self._level_stack = []
    def handle_starttag(self, tag, attrs):
        if tag in CustomParser.selected:
            self._level_stack.append(tag)
    def handle_endtag(self, tag):
        if self._level_stack \
        and tag in CustomParser.selected \
        and tag == self._level_stack[-1]:
            self._level_stack.pop()
    def handle_data(self, data):
        if "/".join(self._level_stack) in (
            'table/tr/td',
            'table/tr/td/h1/font',
            'table/tr/td/ul/li'):
            print self._level_stack, data
        
if len(sys.argv) > 1:
    params = urllib.urlencode({'ip': sys.argv[1], 'action': 2})
else:
    params = None
 
content = unicode(urllib.urlopen('http://www.ip138.com/ips8.asp',params).read(), 'GB2312')
 
parser = CustomParser()
parser.feed(content)
parser.close()

python读有文件结束符的txt文本文件

一直用python读文件都是文本文件。用的方法是:

lines=open('ft.txt')

但是前两天读一个几百兆的大文件的时候,遇到了奇怪的问题,觉得是内容没有读完。定位最后读到的行,用emeditor打开,发现有一个怪字符“”。编码是“\x001a”,一查,原来是文件结束符号。
一直郁闷,奇怪为啥文本文件里面有文件结束符,试了好多办法,都不行,最后经limodou指点,原来这种情况要当成二进制文件来读。

lines=open('ft.txt','rb')

文件内容如下:

abcdefg

两种不同情况的结果如下:

>>> f=open('ft.txt')
>>> f.read()
'abc'
>>> f=open('ft.txt','rb')
>>> f.read()
'abc\x1adefg'

python非贪婪、多行匹配正则表达式例子

一些regular的tips:

1 非贪婪flag

 >>> re.findall(r"a(\d+?)", "a23b")
        ['2']
>>> re.findall(r"a(\d+)", "a23b")
        ['23']

注意比较这种情况:

      >>> re.findall(r"a(\d+)b", "a23b")
        ['23']
>>> re.findall(r"a(\d+?)b", "a23b")
        ['23']

2 如果你要多行匹配,那么加上re.S和re.M标志
re.S:.将会匹配换行符,默认.不会匹配换行符

       >>> re.findall(r"a(\d+)b.+a(\d+)b", "a23b\na34b")
        []
>>> re.findall(r"a(\d+)b.+a(\d+)b", "a23b\na34b", re.S)
        [('23', '34')]
>>>

re.M:^$标志将会匹配每一行,默认^和$只会匹配第一行

 >>> re.findall(r"^a(\d+)b", "a23b\na34b")
        ['23']
>>> re.findall(r"^a(\d+)b", "a23b\na34b", re.M)
        ['23', '34']

但是,如果没有^标志,

>>> re.findall(r"a(\d+)b", "a23b\na23b")
        ['23', '23']

可见,是无需re.M

python正则表达式学习

出处
python 中的re 模块

正则表达式

就个人而言,主要用它来做一些复杂字符串分析,提取想要的信息
学习原则:够用就行,需要的时候在深入

现总结如下:

正则表达式中特殊的符号:

“.” 表任意字符
“^ ” 表string起始
“$” 表string 结束
“*” “+” “?” 跟在字符后面表示,0个——多个, 1个——多个, 0个或者1个
*?, +?, ?? 符合条件的情况下,匹配的尽可能少//限制*,+,?匹配的贪婪性
{m} 匹配此前的字符,重复m次
{m,n} m到n次,m,n可以省略

举个例子 ‘a.*b’ 表示a开始,b结束的任意字符串
a{5} 匹配连续5个a

[] 表一系列字符 [abcd] 表a,b,c,d [^a] 表示非a
| A|B 表示A或者B , AB为任意的正则表达式 另外|是非贪婪的如果A匹配,则不找B
(…) 这个括号的作用要结合实例才能理解, 用于提取信息

\d [0-9]
\D 非 \d
\s 表示空字符
\S 非空字符
\w [a-zA-Z0-9_]
\W 非 \w

一:re的几个函数

1: compile(pattern, [flags])
根据正则表达式字符串 pattern 和可选的flags 生成正则表达式 对象

生成正则表达式 对象(见二)

其中flags有下面的定义:
I 表示大小写忽略
L 使一些特殊字符集,依赖于当前环境
M 多行模式 使 ^ $ 匹配除了string开始结束外,还匹配一行的开始和结束
S “.“ 匹配包括‘\n’在内的任意字符,否则 . 不包括‘\n’
U Make \w, \W, \b, \B, \d, \D, \s and \S dependent on the Unicode character properties database
X 这个主要是表示,为了写正则表达式,更可毒,会忽略一些空格和#后面的注释

其中S比较常用,
应用形式如下
import re
re.compile(……,re.S)

2: match(pattern,string,[,flags])
让string匹配,pattern,后面分flag同compile的参数一样
返回MatchObject 对象(见三)

3: split( pattern, string[, maxsplit = 0])
用pattern 把string 分开
>>> re.split(‘\W+’, ‘Words, words, words.’)
[‘Words’, ‘words’, ‘words’, ”]
括号‘()’在pattern内有特殊作用,请查手册

4:findall( pattern, string[, flags])
比较常用,
从string内查找不重叠的符合pattern的表达式,然后返回list列表

5:sub( pattern, repl, string[, count])
repl可以时候字符串,也可以式函数
当repl是字符串的时候,
就是把string 内符合pattern的子串,用repl替换了

当repl是函数的时候,对每一个在string内的,不重叠的,匹配pattern
的子串,调用repl(substring),然后用返回值替换substring

>>> re.sub(r’def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):’,
… r’static PyObject*\npy_\1(void)\n{‘,
… ‘def myfunc():’)
‘static PyObject*\npy_myfunc(void)\n{‘

>>> def dashrepl(matchobj):
… if matchobj.group(0) == ‘-‘: return ‘ ‘
… else: return ‘-‘
>>> re.sub(‘-{1,2}’, dashrepl, ‘pro—-gram-files’)
‘pro–gram files’

二:正则表达式对象 (Regular Expression Objects )

产生方式:通过 re.compile(pattern,[flags])回

match( string[, pos[, endpos]]) ;返回string[pos,endpos]匹配
pattern的MatchObject(见三)

split( string[, maxsplit = 0])
findall( string[, pos[, endpos]])
sub( repl, string[, count = 0])
这几个函数和re模块内的相同,只不过是调用形式有点差别

re.几个函数和 正则表达式对象的几个函数,功能相同,但同一程序如果
多次用的这些函数功能,正则表达式对象的几个函数效率高些

三:matchobject

通过 re.match(……) 和 re.compile(……).match返回

该对象有如下方法和属性:

方法:
group( [group1, …])
groups( [default])
groupdict( [default])
start( [group])
end( [group])

说明这几个函数的最好方法,就是举个例子

matchObj = re.compile(r”(?P\d+)\.(\d*)”)
m = matchObj.match(‘3.14sss’)
#m = re.match(r”(?P\d+)\.(\d*)”, ‘3.14sss’)

print m.group()
print m.group(0)
print m.group(1)
print m.group(2)
print m.group(1,2)

print m.group(0,1,2)
print m.groups()
print m.groupdict()

print m.start(2)
print m.string

输出如下:
3.14
3.14
3
14
(‘3′, ’14’)
(‘3.14’, ‘3’, ’14’)
(‘3′, ’14’)
{‘int’: ‘3’}
2
3.14sss

所以group() 和group(0)返回,匹配的整个表达式的字符串
另外group(i) 就是正则表达式中用第i个“()” 括起来的匹配内容
(‘3.14’, ‘3’, ’14’)最能说明问题了。

更进一步的学习,请看手册

python中关于文件路径的简单操作

出处
python中关于文件路径的简单操作

几个主要的函数:

1: os.listdir(path) //path为目录

功能相当于在path目录下执行dir命令,返回为list类型
举例:
print os.listdir(‘..’)
输出:
[a,b,c,d]

2: os.path.walk(path,visit,arg)

path :是将要遍历的目录
visit :是一个函数指针,函数圆形为:
callback(arg,dir,fileList)
其中arg为为传给walk的arg , dir是path下的一个目录,fileList为dir下的文件和目录组成的list
arg:传给visit用的,对walk没有什么作用

举例:
def callback(arg,directory, files):
print directory,
print files,
print arg
print '--------------------'

os.path.walk('.',callback, '123456')

输出:
. ['path0704.py', 'temp', '\xc2\xb7\xbe\xb6\xcf\xe0\xb9\xd8\xd1\xa7\xcf\xb0.txt'] 123456
--------------------
.\temp ['temp.h', 'temp1'] 123456
--------------------
.\temp\temp1 ['abc.bmp'] 123456

如果想找到某个目录下所有文件,只需要在callback里面,在fileList中找出文件,即可

除此之外,还有一个函数可以用那就是os.walk,看10

3:os.path.split(path)
path 为一个路径,

输出,把path分成两部分,具体看实例:
print os.path.split("abc/de.txt")
('abc', 'de.txt')
os.path.split("abc")
('', 'abc')
print os.path.split("de/abc/de")
('de/abc', 'de')

4: os.path.splitext(filename)
把文件名分成文件名称和扩展名
os.path.splitext(abc/abcd.txt)
('abc/abcd', '.txt')

5: os.path.dirname(path)
把目录名提出来
print os.path.dirname("abc")
#输出为空
print os.path.dirname('abc\def')
abc

6: os.path.basename(filename)
取得主文件名
print os.path.basename('abc')
abc
print os.path.basename('abc.txt')
abc
print os.path.basename('bcd/abc')
abc #这个需要注意不包括目录名称
print os.path.basename('.')
.

7:os.mkdir(path, [mode])
path为目录名: 这里有个要求,只能创建一级目录
比如path为 abc/def 则当前目录下必须存在abc 否则失败

8: os.makedirs(path [,mode])
可以创建多级目录

9:os.remove(path)删除一个文件,一定是一个文件
os.removedirs(path) 删除一个目录下所有东西
os.rmdir(path) 删除一个目录,而且一定要空,否则os.errer

10:os.walk(path)
遍历path,返回一个对象,他的每个部分都是一个三元组
(‘目录x’,[目录x下的目录list],目录x下面的文件)

举例:
a = os.walk('.')
for i in a:
print i
输出:
('.', ['abc', 'temp'], ['path0704.py', '\xc2\xb7\xbe\xb6\xcf\xe0\xb9\xd8\xd1\xa7\xcf\xb0.txt'])
('.\\abc', [], ['\xd0\xc2\xbd\xa8 BMP \xcd\xbc\xcf\xf1.bmp'])
('.\\temp', ['temp1'], ['temp.h'])
('.\\temp\\temp1', [], ['abc.bmp'])

11:shutil.copy(src,dst)
把文件src内容拷贝到文件dst中。,目标区域必须可以写,如果dst存在,则dst被覆盖

上面的函数基本够用
其它文件移动操作还请看:shutil模块:High-level file operations