由于经常要查询C++相关的资料,翻书太麻烦,MSDN太大,去网上查询又太慢。于是决定将www.cplusplus.com整个打包成CHM,以便查询用。
将网站down下来之后,发现要做成CHM还是有不少后期工作要做,比如:应该把页面右上方的Login去掉。。。
正好学了Python一直没有派上大的用场,咱露它一小手吧。
第一个问题就是遍历目录的问题,网站下面有好几十个目录,以前写C++的经验告诉我,这得用一个递归函数来遍历。但在Python中,一个walk函数搞定一切,Fantastic!
举个例子:
E盘根目录下有文件夹a
a
├──aa
│ ├──aaa
│ ├──aa.txt
│ └──ab.txt
├──ab
│ ├──aba
│ └──ab.txt
├──a.txt
└──b.txt
在Python中对目录a进行walk后:
>>> import os >>> a=os.walk(r'e:/a') >>> for i in a: ... print i ... ('e://a', ['aa', 'ab'], ['a.txt', 'b.txt']) ('e://a//aa', ['aaa'], ['aa.txt', 'ab.txt']) ('e://a//aa//aaa', [], []) ('e://a//ab', ['aba'], ['ab.txt']) ('e://a//ab//aba', [], [])
其返回值是一个Generator,每次迭代的结果是一个Tuple t,由三个元素组成,
t[0]为当前所遍历的目录名
t[1]为当前目录下的所有子目录
t[2]为当前目录下的所有文件名
这使得遍历目录相当轻松。
修改页面内容的脚本如下:(略去了实现细节)
def deco_NeedTempFile(func): '''decorate the func which need a temporary file 其实这里完全可以不用装饰器,只是为了体验一下 如何向被装饰函数中添加参数 ''' import os import tempfile tmpf = tempfile.NamedTemporaryFile(delete=False) tmpf.close() def new_func(*args, **argkw): '''append tmpf to the parameter tuple then call it 这里又是Python的一个新颖的语法知识,变参 C++中操纵变参那叫一个复杂,而Python中用 *args表示一个Tuple,其中是非关键字参数 **argkw表示一个Dictionary,其中是关键字参数 例如我定义一个def f(kw=-1,*args, **argskw) 那么调用f(1,2,ar=2)将会使得 kw=1, args=(2,), argskw={'ar':2} 调用f(1,(2,3),ar=2)将会使得args=((2,3),) 要想使(2,3)解包,得调用f(1,*(2,3),ar=2),则args=(2,3) 同理若f(1,*(2,3),**{'a':1,'b':3}),则argskw={'a':1,'b':3} ''' arg=list(args) arg.append(tmpf) return func(*tuple(arg), **argkw) new_func.func_name = func.func_name new_func.__doc = func.__doc__ return new_func def RemoveLogin(origin): '''Remove the 'InitJS()' from the string origin ''' LOGIN = 'onLoad="InitJS()"' if LOGIN in origin: origin=origin.replace(LOGIN, '') return origin; def MakeOutsideLinkRed(origin): '''Make hypertext which link outside ''' kw = ('Articles', 'Forums') for s in kw: if s in origin and '<tr><td><a href="' in origin: re = '<tr><td><span class=outside><a href="http://www.cplusplus.com/'/ +s.lower()+'/" mce_href="http://www.cplusplus.com/'/ +s.lower()+'/"><b>' + s + '</b></a></span></td></tr>/n' return re return origin def AddTipAfterHead(origin): '''Point out whether it is Local page ''' H1 = '<h1>' XXLARGE = '<span style="font-size:xx-large" mce_style="font-size:xx-large">' if XXLARGE in origin: split = origin.find('</b>') elif H1 in origin: split = origin.find('</h1>') else: return origin re = origin[0:split] + ' <font color=red>[in CHM]</font><font color=white> by thy38</font>'/ + origin[split:] return re def MakeSearchEngineOutside(origin): if 'action="/query/search.cgi"' in origin: split = origin.find('/query/search.cgi') re = origin[0:split] + 'http://www.cplusplus.com' + origin[split:] return re return origin @deco_NeedTempFile def ModifyAllDefault(d, tmpf): '''Find all default.htm in directory d and remove it LOGIN ''' DEFAULT = 'default.htm' import os #由于迭代器遍历一次就回不了头了,所以我将它转换成tuple #这样就可以多次遍历了 allfiles=tuple(os.walk(d)) totalFileNum = sum(len(a[-1]) for a in allfiles) current=0 for i in allfiles: if DEFAULT in i[-1]: fo = open(i[0]+'//'+DEFAULT, 'r') #以'w'打开文件相当于清空内容 tmpf = open(tmpf.name, 'w') firstTime=True willBeBox=False for x in fo: x=RemoveLogin(x) x=MakeOutsideLinkRed(x) x=AddTipAfterHead(x) x=MakeSearchEngineOutside(x) tmpf.write(x) fo.close() os.remove(fo.name) #tmpf如果不想close,则必须调用flush,将缓冲区的内容 #立即写入文件,否则下面copyfile的内容将不完整 tmpf.close() ## import shutil ## shutil.copyfile(tmpf.name, fo.name) ##通过学习知道,上面shutil的copyfile比较慢 ##现改成用os.rename os.rename(tmpf.name, fo.name) current += 1 print current,'/',totalFileNum,'-->"'+fo.name+'" is done!' def main(): ModifyAllDefault(r'e:/CppReference') #ModifyAllDefault('e:/a') if __name__ == '__main__': main()
输出结果:
Command line: D:/programs/Python26/python.exe D:/Projects/Python/MODIFY~1.PY
Working directory: D:/Projects/Python
Timeout: 0 ms
1 / 2135 -->"e:/CppReference/www.cplusplus.com/default.htm" is done!
2 / 2135 -->"e:/CppReference/www.cplusplus.com/articles/default.htm" is done!
3 / 2135 -->"e:/CppReference/www.cplusplus.com/doc/default.htm" is done!
......
1194 / 2135 -->"e:/CppReference/www.cplusplus.com/reference/string/string/swap/default.htm" is done!
1195 / 2135 -->"e:/CppReference/www.cplusplus.com/reference/string/swap/default.htm" is done!
1196 / 2135 -->"e:/CppReference/www.cplusplus.com/src/default.htm" is done!
Process "Python Interpreter" terminated, ExitCode: 00000000
一个小程序让我学到了很多东西,由于是自用的,也没有错误处理,也没有异常。所以
我一定会回来的!