status

草稿

清风

完成度80%

1. 用Python完成常见任务

为何要学习Python?到google可以搜索到一大堆理由。 我的理由是其字符串处理能力,和随心所欲的脚本语言写法,写Java总有一种很严肃很认真的感觉,而Python则很简便,有一种想法到哪,程序就到哪里的感觉

今天学习几个简单的部分:

1.1. 文件操作

1.1.1. 读文件

   1 for line in open("/tmp/1.txt","r")  :
   2   print line

1.1.2. 写文件

   1 f = open("/tmp/1.txt","w")#可读可写模式  
   2 f.write("123")#写入字符串  
   3 f.close()#关闭文件

1.2. Python的文本处理

任务:读取tomcat的日志文件,并且把日期开头的内容显示出来,例如:xxxx-xx-xx

   1 import re
   2 regx = "\d\d\d\d-\d\d-\d+"
   3 for str in open("c:\stdout.log","r"):
   4     if re.search(regx,str):
   5         pintr str

一个用来测试Python正则表达式的工具: http://kodos.sourceforge.net/ 图形界面,简单易用,适合学习Python的正则表达式

1.2.1. 什么是正则表达式

样本规则表达式
ABC([d-w]*\d\d?)+XYZ

对于要匹配这个表达式的字符串,它必须以 "ABC" 开头、以 "XYZ" 结尾 -- 但它的中间必须要有什么呢?中间子表达式是 ([d-w]*\d\d?),而且后面跟了“一或多”运算符。所以,字符串的中间必须包括一个(或者两个,或者一千个)与括号中的子表达式匹配的字符或字符串。字符串 "ABCXYZ" 不匹配,因为它的中间没有必要的字符。

不过这个内部子表达式是什么呢?它以 d-w 范围内的零或多个字母开头。一定要注意:零字母是有效匹配,虽然使用英语单词 "some"(一些)来描述它,可能会感到很别扭。接着,字符串必须恰好有一个数字;然后有零或一个附加数字。(第一个数字字符类没有循环运算符,所以它只出现一次。第二个数字字符类有 "?" 运算符。)总而言之,这将翻译成“一个或两个数字”。以下是一些与规则表达式匹配的字符串:

匹配样本表达式的字符串

ABC1234567890XYZ 
ABCd12e1f37g3XYZ 
ABC1XYZ

还有一些表达式与规则表达式不匹配(想一想,它们为什么不匹配):

不匹配样本表达式的字符串

ABC123456789dXYZ 
ABCdefghijklmnopqrstuvwXYZ 
ABcd12e1f37g3XYZ 
ABC12345%67890XYZ 
ABCD12E1F37G3XYZ

需要一些练习才能习惯创建和理解规则表达式。但是,一旦掌握了规则表达式,您就具有了强大的表达能力。也就是说,转而使用规则表达式解决问题通常会很容易,而这类问题实际上可以使用更简单(而且更快速)的工具,如 string,来解决。 

1.3. Python的网络操作

1.3.1. Python和XML-RPC

1.3.1.1. 何为XML-RPC?

XML-RPC 是 XML Web 服务的鼻祖。它是一个用于远程过程调用(remote procedure call,RPC)的简单规范,这种调用使用 HTTP 作为传输协议,并使用 XML 词汇表作为消息有效负载。由于 XML-RPC 非常简单(整个规范打印出来还不到十页纸),它已经变得非常流行,现在大多数语言都有了标准的或已经可用的 XML-RPC 实现。这些语言中包括 Python,它在版本 2.2 中就开始捆绑 xmlrpclib(Fredrik Lundh 开发的 XML-RPC 实现)了。

1.3.1.2. 任务:尝试Python的XML-RPC远程调用

首先,我们打算将CMS(Context Manager System)系统进行Python的改造,第一件事,先向外公开版本的变化,可供远程调用。

   1 import SimpleXMLRPCServer
   2 
   3 #定义自己的CMS类  
   4 class MyCMS:
   5     def getVersion(self):#向外公开版本的方法  
   6         return "Powerd By Python 0.1a"
   7 
   8 cms = MyCMS()
   9 server = SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", 8888))
  10 server.register_instance(cms)
  11 
  12 print "Listening on port 8888"
  13 server.serve_forever()#服务器执行,并监听8888端口

客户端调用代码,获得最新的版本信息

   1 import xmlrpclib
   2 
   3 server = xmlrpclib.ServerProxy("http://localhost:8888";)
   4 
   5 version = server.getVersion()
   6 
   7 print "version:"+version

1.3.1.3. 总结

比同等的JAVA实现代码量明显减少,使精力能够更多的集中到系统本身中来 JAVA的一个XmlRpc实现:http://ws.apache.org/xmlrpc/ JAVA调用代码如下:

   1 XmlRpcClient xmlrpc = null;  
   2 try  
   3 {  
   4     xmlrpc = new XmlRpcClient("http://localhost:8888/";);  
   5 }  
   6 catch (MalformedURLException e)  
   7 {  
   8     e.printStackTrace();  
   9 }  
  10 Vector params = new Vector();  
  11 try  
  12 {  
  13     String result = (String) xmlrpc.execute("getVersion", params);  
  14     System.out.println(result);  
  15 }  
  16 catch (XmlRpcException e1)  
  17 {  
  18     e1.printStackTrace();  
  19 }  
  20 catch (IOException e1)  
  21 {  
  22     e1.printStackTrace();  
  23 }  

1.3.1.4. 参考资料

想了解更多,请到这里: http://www.python.org/doc/current/lib/module-xmlrpclib.html http://www.python.org/doc/current/lib/module-SimpleXMLRPCServer.html

1.3.2. 任务:抓取FarideaBBS首页的所有图片

主要应用技术:正则表达式&urllib

第一步,模拟HTTP连接,连接FarideaBBS,获取Html源代码

   1 import urllib
   2 def farideaHttp():
   3     page = urllib.urlopen("../Boards.asp";)
   4     body = page.readlines()
   5     page.close()
   6 
   7     return body

第二步分析Html源代码,建立正则表达式: 今天先建立一个简单的表达式,不考虑图片链接是否有http头

   1 regx = r"""<img\s*src\s*="?(\S+)"""

函数代码如下:

   1 def anyHtml(line):
   2     import re
   3     regx = r"""<img\s*src\s*="?(\S+)"?"""
   4     match_obj = re.search(regx,line)
   5     if match_obj!=None:
   6         all_groups = match_obj.groups()
   7         for img in all_groups:print img#这个img就是图片的链接了

调用代码如下:

   1 lines = farideaHttp()#读取全部内容  
   2 for line in lines:
   3     anyHtml(line)

1.3.3. 任务:从新浪抓取天气预报

首先访问http://weather.sina.com.cn/cgi-bin/figureWeather/simpleSearch.cgi来看一下新浪天气预报的样式。OK,一天的基本天气在这里就都有了,我们要做的就是把他变为自己的

首先我们要为自己的爬虫起一个名字,就叫QingFengbot吧:),版本0.1,然后让我们看一下其他浏览器是如何定义自己的USER_AGENT的: IE:

Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)

Mozilla:

Mozilla/5.0 (Windows; U; Windows NT 5.0; zh-CN; rv:1.7.5) Gecko/20041124 Firefox/1.0

那么,如何实现呢,让我们用代码交流: 建立一个qingfengbot.py,这个机器人的所有代码就都放在这里

   1 import urllib
   2 import re
   3 
   4 class MyUserAgent(urllib.FancyURLopener):
   5     def __init__(self, *args):
   6         self.version = "QingFengbot/0.1(Python;QingFengbot 0.1;zh-CN)"#定义自己的user_agent  
   7         urllib.FancyURLopener.__init__(self, *args)
   8 
   9 def httpclient(url):
  10     urllib._urlopener = MyUserAgent()
  11 
  12     page = urllib.urlopen(url)
  13     body = page.read()#read? readlines?  
  14     page.close()
  15 
  16     return body

目前里面仅仅封装了一个方法httpclient,用来连接一个web地址,然后返回这个地址的html,在这里究竟应当返回read还是readlines,我还得继续研究,目前感觉返回read外面好处理一些。

   1 import qingfengbot
   2 print qingfengbot.httpclient("http://www.faridea.com/bbs/Boards.asp")

1.4. Python的数据库操作

1.4.1. 什么是dbapi

python用来统一数据库操作的规范,详情见这里 http://www.python.org/peps/pep-0249.html

1.4.2. python操作postgresql

推荐模块: http://www.initd.org/tracker/psycopg/wiki/PsycopgTwo

   1 import psycopg2 as pgdb
   2 conn = pgdb.connect(host='localhost',databse='qingfeng',user='qingfeng',password='123')
   3 cur = conn.cursor()
   4 cur.execute("select * from dream")
   5 print cur.rowcount

1.5. Python的多线程

有一段代码是这样,有如下操作:

   1 s = "Mary had a little lamb"
   2 s = s.upper()
   3 s = "Mary had a little lamb"
   4 s = s.lower()
   5 s = "Mary had a little lamb"
   6 s = s.replace('a','A')

把一个字符串分别进行转换为大写、小写、替换小写a字符为大写A 很明显这个算法,可以将三个操作拆分为三个函数,变为一个多线程算法

   1 def upper():
   2 def lower():
   3 def replace():

然后放到线程中执行:

   1 threads=[]
   2 threads.append(upper())
   3 threads.append(lower())
   4 threads.append(replace())

1.6. Python操作RSS

1.7. 其他

1.7.1. 生成随机数

   1 import random
   2 rnd = random.randint(1,500)#生成1-500之间的随机数

1.8. 常用函数

1.8.1. abs(x)

abs()返回一个数字的绝对值。如果给出复数,返回值就是该复数的模。

>>>print abs(-100)
100
>>>print abs(1+2j)
2.2360679775

1.8.2. callable(object)

callable()函数用于测试对象是否可调用,如果可以则返回1(真);否则返回0(假)。可调用对象包括函数、方法、代码对象、类和已经定义了“调用”方法的类实例。

>>> a="123"
>>> print callable(a)
0
>>> print callable(chr)
1

1.8.3. cmp(x,y)

cmp()函数比较x和y两个对象,并根据比较结果返回一个整数,如果x<y,则返回-1;如果x>y,则返回1,如果x==y则返回0。

>>>a=1
>>>b=2
>>>c=2
>>> print cmp(a,b)
-1
>>> print cmp(b,a)
1
>>> print cmp(b,c)
0

1.8.4. divmod(x,y)

divmod(x,y)函数完成除法运算,返回商和余数。

>>> divmod(10,3)
(3, 1)
>>> divmod(9,3)
(3, 0)

1.8.5. isinstance(object,class-or-type-or-tuple) -> bool

测试对象类型

>>> a='isinstance test'
>>> b=1234
>>> isinstance(a,str)
True
>>> isinstance(a,int)
False
>>> isinstance(b,str)
False
>>> isinstance(b,int)
True

1.8.6. len(object) -> integer

len()函数返回字符串和序列的长度。

>>> len("aa")
2
>>> len([1,2])
2

1.8.7. pow(x,y[,z])

pow()函数返回以x为底,y为指数的幂。如果给出z值,该函数就计算x的y次幂值被z取模的值。

>>> print pow(2,4)
16
>>> print pow(2,4,2)
0
>>> print pow(2.4,3)
13.824

1.8.8. range([lower,]stop[,step])

range()函数可按参数生成连续的有序整数列表。

>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1,10)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1,10,2)
[1, 3, 5, 7, 9]

1.8.9. round(x[,n])

round()函数返回浮点数x的四舍五入值,如给出n值,则代表舍入到小数点后的位数。

>>> round(3.333)
3.0
>>> round(3)
3.0
>>> round(5.9)
6.0

1.8.10. type(obj)

type()函数可返回对象的数据类型。

>>> type(a)
<type 'list'>
>>> type(copy)
<type 'module'>
>>> type(1)
<type 'int'>

1.8.11. xrange([lower,]stop[,step])

xrange()函数与range()类似,但xrnage()并不创建列表,而是返回一个xrange对象,它的行为与列表相似,但是只在需要时才计算列表值,当列表很大时,这个特性能为我们节省内存。

>>> a=xrange(10)
>>> print a[0]
0
>>> print a[1]
1
>>> print a[2]
2

1.9. 小结

1.10. 练习


::-- qingfeng [2007-04-14 08:42:18]

Name Password4deL ;) :( X-( B-)
ZoomQuiet   辛苦! 不过最好给个分类索引先,比如说 RSS操作明显是XML 一类的?
2007-04-14 16:55:55
Felix Peng   呵呵,感谢清风的努力!
2007-04-15 23:08:28
评注编辑入口