#
代碼
參考:http://www.python.org/dev/peps/pep-0318/
def singleton(cls):
instances = {}
def getinstance():
if cls not in instances:
print "new"
instances[cls] = cls()
return instances[cls]
return getinstance
@singleton
class MyClass:
pass
x1=MyClass()
#print new
x2=MyClass()
>>> def chomppy(k):
if k=="": return ""
if k=="\n" or k=="\r\n" or k=="\r": return ""
if len(k)==1: return k #depends on above case being not true
if len(k)==2 and (k[-1]=='\n' or k[-1]=='\r'): return k[0]
#done with weird cases, now deal with average case
lastend=k[-2:] #get last two pieces
if lastend=='\r\n':
outstr=k[:-2]
return outstr
elif (lastend[1]=="\n" or lastend[1]=="\r"):
outstr=k[:-1]
return outstr
return k
>>> chomppy(’cow\n’)
‘cow’
>>> chomppy(”)
”
>>> chomppy(’hat’)
‘hat’
>>> chomppy(’cat\r\n’)
‘cat’
>>> chomppy(’\n’)
”
>>> chomppy(’\r\n’)
”
>>> chomppy(’cat\r’)
‘cat’
>>> chomppy(’\r’)
”
代碼可以直接運行,看結果
如果命令調試 python -m pdb pyaop.py
(Pdb)b pyaop:10
(Pdb)c
(Pdb)n .....自己來把
調試參考 : python pdb 基礎調試
源文件 : pyaop.py
#!/usr/bin/python
# -*- coding: utf8 -*-
# 參考:http://www.cnblogs.com/Alexander-Lee/archive/2008/12/06/pythonaop.html
"""
py aop 代理類 ( metaclass 特性 )
由于使用 __metaclass__ = <type 'type'>
pyaop 繼承 type
"""
class pyaop(type):
# before ; after 方法變量引用聲明
beforeop=lambda e : None
afterop=lambda e : None
#class方法(靜態方法)set
@classmethod
def setbefore(self,func):
pyaop.beforeop=func
@classmethod
def setafter(self,func):
pyaop.afterop=func
""" 使用調試
# python -m pdb pyaop.py
# 由下面 A類 < __metaclass__ = pyaop >
# 類初始 的 __new__ 指向 pyaop __new__
#
# (Pdb)b pyaop:36 (大概就是下面函數form types 的行號)
# (Pdb)a (可以看看調試中,各參數的值,注意dict為A的初始對象傳過來了)
# mcl = <class '__main__.pyaop'>
# name = A
# bases = (<type 'object'>,)
# dict = {'__module__': '__main__', 'foo': <function foo at 0x7fddced4>, '__metaclass__': <class '__main__.pyaop'>, 'foo2': <function foo2 at 0x7fddcf0c>}
# 本函數目的: 使用 新的另個對象掛載 被aop后的 A對象 方法
"""
def __new__(mcl,name,bases,dict):
from types import FunctionType
obj=object()
def aop(func):
def wrapper(*args, **kwds):
pyaop.beforeop(obj)
value = func(*args, **kwds)
pyaop.afterop(obj)
return value
return wrapper
#添加代理
for attr, value in dict.iteritems():
if isinstance(value, FunctionType):
dict[attr] = aop(value)
#掛載到 obj 上
obj=super(pyaop, mcl).__new__(mcl, name, bases, dict)
return obj
class A(object):
#被 aop 代理 聲明!
__metaclass__ = pyaop
def foo(self):
total = 0
for i in range(100000):
total = total+1
print total
def foo2(self):
from time import sleep
total = 0
for i in range(100000):
total = total+1
#sleep(0.0001)
print total
"""#####################################################################################
# 測試
#####################################################################################"""
def beforep(self):
print('before')
def afterp(self):
print('after')
if __name__ == "__main__":
pyaop.setbefore(beforep)
pyaop.setafter(afterp)
a=A()
a.foo()
a.foo2()
其他aop:
使用 @
def addspam(fn):
def new(*args):
print "spam, spam, spam"
return fn(*args)
return new
@addspam
def useful(a, b):
print a**2 + b**2
useful(3,4)
#結果
#spam, spam, spam
#25
晚綁定!
def attrs(**kwds):
def decorate(f):
for k in kwds:
setattr(f, k, kwds[k])
return f
return decorate
@attrs(versionadded="2.2",author="Guido van Rossum")
def mymethod(f):
return mymethod
x=mymethod(1)
x.versionadded
#2.2 !這是什么好東西!!
mkdir -p cgi/cgi-bin ;
gvim time.py
#!/usr/bin/env python
# -*- coding utf8 -*-
import cgitb
cgitb.enable()
import time
print "Content-type: text/html"
print
print time.strftime('%Y-%m-%d %X', time.localtime() )
form = cgi.FieldStorage()
# Get data from field 'name'
name = form.getvalue('name')
cgi 服務器建立
cd cgi
python -m CGIHTTPServer
到 firefox 中
http://127.0.0.1:8000/cgi-bin/time.py
2009-04-07 23:26:03
數據:
希望 抓取
div > p id='da' > a text
和 div > p id='da' > html
<div>
<p id="tt">
<a href=/tag/php>no no</a>
</p>
<p id='da'>
<a href=/tag/php>php</a>
<a href=/tag/python>python</a>
<a href=/tag/vim>vim</a>
<a href=/tag/windows>windows</a>
<a href=/tag/wingide>wingide</a>
</p>
</div>
<p id='da'>
<a href=/tag/wingide>hehe</a>
</p>
希望結果為
$ python t.py
a_text: ["'php'", "'python'", "'vim'", "'windows'", "'wingide'"]
div_html[0]:
<p id="da">
<a href="/tag/php">php</a>
<a href="/tag/python">python</a>
<a href="/tag/vim">vim</a>
<a href="/tag/windows">windows</a>
<a href="/tag/wingide">劉凱毅</a>
</p>
#說明
其實 SGMLParser 我感覺最關鍵的是
#/usr/lib/python2.5/sgmllib.py
# Internal -- finish parsing of <tag/data/ (same as <tag>data</tag>)
def finish_shorttag(self, tag, data):
#而 finish_starttag finish_endtag 抓取會調用 end_* start_* 什么的
self.finish_starttag(tag, [])
self.handle_data(data)
self.finish_endtag(tag)
代碼:
#!python
#coding=UTF-8
from sgmllib import SGMLParser
class TestSGMLParser(SGMLParser):
def reset(self, verbose=0):
SGMLParser.reset(self)
#提取 a text ; div html
self.a_text=[]
self.div_html=[]
#寄存變量
self.data_text = ""
self.data_html = ""
#業務邏輯表示變量
#抓取 div > p id="da" > a
#由于需要得到div p 的 html > test_div_p = 0 , 1 , 2
self.test_div=False
self.test_div_p=0
self.test_div_p_a=False
# 重寫 handle_data
# 寄存變量 填充值
def handle_data(self, data):
self.data_text = self.data_text + data
if self.test_div_p :
self.data_html = self.data_html +data
# 重寫 finish_starttag
# self.data_html 填充值
def finish_starttag(self, tag, attrs):
SGMLParser.finish_starttag(self, tag, attrs)
if self.test_div_p :
strattrs = "".join([' %s="%s"' % (key, value) for key, value in attrs])
self.data_html=self.data_html+"<%(tag)s%(strattrs)s>" % locals()
# 重寫 finish_endtag
# self.data_html 填充值
def finish_endtag(self, tag):
SGMLParser.finish_endtag(self, tag)
if self.test_div_p == 2 :
self.data_html=self.data_html+"</%(tag)s>" % locals()
elif self.test_div_p == 1 :
self.data_html=self.data_html+"</%(tag)s>" % locals()
self.test_div_p = 0
# self.test_div 狀態修改
def start_div(self, attrs):
self.test_div=True
# self.test_div 狀態修改
# self.div_html 填充
def end_div(self):
if self.test_div :
self.div_html.append(self.data_html)
self.test_div=False
# self.test_div_p 狀態修改 2 為可以填充
def start_p(self, attrs):
if self.test_div and attrs and 'id' in [ key for key, value in attrs ] and len([ value for key, value in attrs if key=='id' and value=='da'])>0 :
self.test_div_p=2
# self.test_div_p 狀態修改 1 為只能填充最后一次
def end_p(self):
if self.test_div_p == 2 :
self.test_div_p=1
# self.test_div_p_a 狀態修改
def start_a(self, attrs):
self.data_text = ""
if self.test_div_p :
self.test_div_p_a=True
# self.test_div_p_a 狀態修改
# self.a_text 填充
def end_a(self):
if self.test_div_p and self.test_div and self.test_div_p_a :
self.a_text.append(repr(self.data_text))
self.test_div_p_a=False
def close(self):
SGMLParser.close(self)
if __name__ == '__main__':
try:
f = open('google.html', 'r')
data = f.read()
x=TestSGMLParser()
x.feed(data)
x.close()
# 我這 gvim utf8 ; cygwin gbk ,轉碼 unicode( str , 'utf8').encode('gbk')
print "a_text: %s \n div_html[0]: \n %s"%(x.a_text[:-1], unicode(x.div_html[0], 'utf8').encode('gbk') )
except IOError, msg:
print file, ":", msg
頁面抓取
抓取 pycurl + 分析用 SGMLParser + 驗證碼用 pytesser
下面就差算法了,抓取的準備工作終于要完成了。
當手邊沒有IDE,面對著python調試犯愁時,你就可以參考下本文;(pdb 命令調試)
參考:http://docs.python.org/library/pdb.html
和 (pdb)help
首先你選擇運行的 py
python -m pdb myscript.py
(Pdb) 會自動停在第一行,等待調試,這時你可以看看 幫助
(Pdb) h
說明下這幾個關鍵 命令
>斷點設置
(Pdb)b 10 #斷點設置在本py的第10行
或(Pdb)b ots.py:20 #斷點設置到 ots.py第20行
刪除斷點(Pdb)b #查看斷點編號
(Pdb)cl 2 #刪除第2個斷點
>運行
(Pdb)n #單步運行
(Pdb)s #細點運行 也就是會下到,方法
(Pdb)c #跳到下個斷點
>查看
(Pdb)p param #查看當前 變量值
(Pdb)l #查看運行到某處代碼
(Pdb)a #查看全部棧內變量
>如果是在 命令行里的調試為:
import pdb
def tt():
pdb.set_trace()
for i in range(1, 5):
print i
>>> tt()
#這里支持 n p c 而已
> <stdin>(3)tt()
(Pdb) n
.
上面一般的調試工具大體上都能解決了,還有其他什么 調試時修改變量值,回到某斷點等 ,可以在 pdb 中 help 下 (其實我也不太明白)
望那位知道的,能一起補全這篇文章。
嘗試下使用 vim 以外 python 的工具
感覺 eric4 不錯
去官方下載 eric4
windows 傻瓜安裝
先安裝 pyqt
再 到 eric3 的安裝目錄 下 python install.py
debian 系統
root 權限
apt-get install python-qt4
apt-get install python-QScintilla2
python install.py
對應腳本運用:
1. shell 統籌管理 腳本的運行。合理結合 crontab , ps -ef ,kill 等命令。
2. perl 處理短小快 。
3. python 有比較復雜結構和邏輯的。
本文主要介紹 perl 的行級命令使用 ,力求 短 小 快  :
#最簡單的
$ perl -e 'print "Hello World\n"'
#處理文件 行
$ perl -n -e 'print $_' file1

#編碼轉換
#如果 有需要 在使用下 encode("UTF-8", decode("GBK",$_));在 linux 下默認 utf-8
perl -MEncode -ne 'print decode("GBK",$_);' file.txt


#正則使用
# if($_=~/.*\/(.*)$/){ print $1 ;} 這是perl 巨方便的地方 $1 xx
# next LINE 跳到下一個循環
$ perl -n -e 'next LINE unless /pattern/; print $_'
#去除換行 chomp
perl -e 'print split(/\n/,"asg\n");'
#像 awk 一樣 Begin End
$ perl -ne 'END { print $t } @w = /(\w+)/g; $t += @w' file.txt
#像 awk -F"x" 一樣 切割行
#-a 打開自動分離 (split) 模式
#@F 為 切割后的 數組
perl -F'\t' -ane '
if($F[1]=~/侃侃/ and $F[2]=~/愛情啊/){
print "$F[3]\t$F[4]\t$F[5]\n"
}
' all2_data.sort.st

實際處理:
perl -F'\|\|' -ane '
my $actor,$music ;
if ( $F[3] ){
$music=$F[2];
$actor=$F[3];
}else{
$music=$F[0];
$actor=$F[1];
}
$music =~ tr/[A-Z]/[a-z]/;
$music =~ s/\s*(.*)\s*\(.*\)/\1/g;
$actor =~ tr/[A-Z]/[a-z]/;
$actor =~ s/\s*(.*)\s*\(.*\)/\1/g;
print "$actor-$music\n";
' ring.utf8.txt |sort -u > ring.actor_music.sort.utf8.txt &
wc -l ring.actor_music.sort.utf8.txt
#像 sed 一樣替換
# -i 和 sed 一樣 perl 輸出會替換調 源 file.txt
$ perl -i -pe 's/\bPHP\b/Perl/g' file.txt
#外部 傳參
perl -ne'print "$ARGV[0]\t$ARGV[1]\n" ' file.txt 'par1' 'par2'
#結果 .. par1 par2 ..
# 查詢出 重復列 次數,并 列舉出來
cut -d" " -f 2 .collection_mobile.data |perl -ne '
END{
while (($key,$value)=each(%a)){print $key,"=",$value,"\n";};
}BEGIN{ %a =(); }
chomp;
$a{$_}+=1;
'
結果
Ring=532895
CRBT=68500
RingBoxes=880
Song=96765
#一些實際使用 :)
find . -name "*.mp3" | perl -pe 's/.\/\w+-(\w+)-.*/$1/' | sort | uniq
perl -F'\t' -ane 'if($F[1]=~/$ARGV[0]/ and $F[2]=~/$ARGV[1]/){print "$F[3]\t$F[4]\t$F[5]\n"}' all2_data.sort.st '侃侃' '愛情啊'
#與 find 合用 -e $ARGV[0] 批量 把 excel 倒成 文本 格式
find . -maxdepth 1 -name "*xls" -exec perl -e '
require("/home/xj_liukaiyi/src/perl/excel/excelUtil.pl");
my $file=$ARGV[0];
sub myRead{
my $str = "";
for $tmp(@_){
$str="$str$tmp\t";
}
$str="$str\n";
system "echo \"$str\" >> $file.data ";
}
&parse_excel("$file",0,\&myRead);
print "$file\n";
' {} \;
參考:
http://www.ibm.com/developerworks/cn/linux/sdk/perl/l-p101/index.html
http://bbs.chinaunix.net/viewthread.php?tid=499434
各位“蜘蛛俠”們大家可能在抓取頁面中的驗證碼而耿耿于懷,關于這點我想我目前可能能幫助下大家,在python中找到最接近與“殺手級別”的工具(源于開源,報與開源,好東西不干獨享)。
調下大家的積極性 ,上圖
python 包>> pytesser| http://code.google.com/p/pytesser/(其實 py包 使用很簡單的,關鍵在安裝)
1. 首先安裝 pil : easy_install --find-links http://www.pythonware.com/products/pil/ Imaging
2. pytesser 依賴包 tesseract-ocr| http://code.google.com/p/tesseract-ocr/
tesseract-ocr 依賴庫| http://tesseract-ocr.googlecode.com/files/tesseract-2.00.eng.tar.gz 解壓到 你安裝的 tesseract-ocr 的 識別學習庫下
re.search('(?ix)(?<=l)ike.*(?=s)','as Like as').group()
#結果 ike a
#說明
# 1. (?..) 匹配模式(就寫有用的)
# >i 使匹配對大小寫不敏感
# >x 正則中串中的空白符被忽略
# 比如 (?x)li k e 可以匹配 like
#2. (?<=l) 前驅匹配但不消費,
# 比如上面 (?<=l)(.*) 可以匹配 l(ike..)
#3. (?=s) 后驅匹配但不消費
# 比如上面 (?<=l)(.*)(?=s) 匹配 l(ike a)s
re.search('(?ix)(as)?(.*)(?(1)as)','As like as').group(2)
#結果 ' like '
#(as)? 條件
#(?(1)as) 如果條件1 為真 ,再匹配as
#
# 給 條件取名 (?P<name>....) (?(name)....)
#re.search('(?ix)(?P<rid>as)(.*)(?(rid)as)','As Like as').group(2)
# 結果 Like
詳細參考 python >>> help(re)
或 http://www.python.org/doc/2.5/lib/re-syntax.html
|