第三方模块都会在https://pypi.python.org/pypi注册.
1.PIL(随机验证码)
windows版PIL:http://pythonware.com/products/pil/
import Image
import ImageFilter
im = Image.open('C:\\forpython\\test.jpeg')
#图片缩放
# w,h = im.size
# im.thumbnail((w/2,h/2))
# im.save('c:\\forpython\\test_1.jpeg','jpeg')
#图片模糊
im2 = im.filter(ImageFilter.BLUR)
im2.save('C:\\forpython\\test_2.jpeg','jpeg')
生成随机验证码案例
#PIL官网是32位的,在win10下安装会出问题,我直接下载pillow,https://pypi.python.org/pypi/Pillow/4.1.1
from PIL import Image,ImageDraw,ImageFont,ImageFilter
import random
#随机字母
def rndChar():
return chr(random.randint(65,90))
#随机颜色1
def rndColor():
return(random.randint(64,255),random.randint(64,255),random.randint(64,255))
#随机颜色2
def rndColor2():
return(random.randint(32,127),random.randint(32,127),random.randint(32,127))
#240*60
width = 60 * 4
height = 60
#创建背景对象 Image.new(颜色类型,大小,具体颜色【白色】)
image = Image.new('RGB',(width,height),(255,255,255))
#创建Font字体对象 ImageFont.truetype(字体类型,大小)
font =ImageFont.truetype('C:\Windows\Fonts\Arial.ttf',36)#pillow4.1之后,字体类型需要具体路径
#创建Draw对象
draw = ImageDraw.Draw(image)
#填充每个对象
for x in range(width):
for y in range(height):
draw.point((x,y),fill=rndColor()) #对image对象每个像素进行添随机色
#输出文字
for t in range(4):
draw.text((60*t+15,10),rndChar(),font=font,fill=rndColor2()) #(位置,随机字母,字体,随机颜色)
#模糊
image = image.filter(ImageFilter.BLUR)#image对自己模糊后再赋给自己
image.save('d:\\forpython\\CAPTCHA.jpg','jpeg')
2.图形界面(弹窗)
信息弹窗
from Tkinter import *
#Frame是所有widget的父容器,widget翻译是窗口小部件
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self,master)
self.pack() #这里为什么要这个不懂。难道在init中有创建一个widget?
self.createWidgets() #创建一个窗口
def createWidgets(self):
self.helloLabel=Label(self,text='Hello,world!')
self.helloLabel.pack()#pack()把widget加入到父容器中
self.quitButton = Button(self,text='Quit',command=self.quit)
self.quitButton.pack()
#创建对象
app =Application()
#设置窗口标题
app.master.title('HI')
#主消息循环,没有这个不会弹窗
app.mainloop()
弹窗中需要输入文字
from Tkinter import *
import tkMessageBox
#Frame是所有widget的父容器,widget翻译是窗口小部件
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self,master)
self.pack() #这里为什么要这个不懂。难道在父类中的init中有创建一个widget?
self.createWidgets() #创建一个窗口
def createWidgets(self):
self.helloLabel=Label(self,text='welcome guys!')
self.helloLabel.pack()#pack()把widget加入到父容器中
self.nameInput = Entry(self)
self.nameInput.pack()
self.quitButton = Button(self,text='go',command=self.hello)#调用hello方法
self.quitButton.pack()
def hello(self):
name = self.nameInput.get() or 'World'
tkMessageBox.showinfo('Message','Hello,%s' % name)
#创建对象
app =Application()
#设置窗口标题
app.master.title('HI')
#主消息循环,没有这个不会弹窗
app.mainloop()
3.TCP编程(安全通信,保证接收到)
#导入socket库
import socket
#创建一个socket:
#socket.AF_INET指定使用IPv4协议,AF_INET6表示使用IPV6
#socket.SOCK_STREAM指定使用 面向流 的TCP协议
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#建立连接 括号中是tuple(IP,端口)
s.connect(('www.sina.com.cn',80))
# 发送数据:要求返回首页内容(没理解) windows下\r\n表示回车符
s.send('GET / HTTP/1.1\r\nHost: www.sina.com.cn\r\nConnection: close\r\n\r\n')
buffer = []
while True:
d = s.recv(1024)
if d:
buffer.append(d)
else:
break #关闭循环
s.close() #关闭接收端口
data = ''.join(buffer)
#接收到的数据包括http头和网页本身
header,html = data.split('\r\n\r\n',1) #遇到\r\n\r\n这个标识位,切1次.即使再遇到\r\n\r\n也不会切了.
print header
#把接收到的数据(网页内容)写入文件:
with open('sina.html','wb') as f:
f.write(html)
客户端-服务器案例(服务器)
import socket
import threading
import time
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#设立监听端口,127.0.0.1表示本机ip地址,端口9999,不得小于1024
s.bind(('127.0.0.1',9999))
#监听端口,传入参数指定等待连接的最大数量
s.listen(5)
print 'Waiting for connection...'
#由于需要先声明本函数,所以置于前面
def tcplink(sock,addr):
print 'Accept new connection from %s:%s' % addr #addr是一个tuple,返回两个数
sock.send('Welcome!')
while True:
data = sock.recv(1024)#每次最多接受1k字节
time.sleep(1) #延迟1秒
if data == 'exit' or not data:
break
sock.send('hello,%s!' % data)
sock.close()
print 'Connection from %s:%s closed' % addr
#accept()等待返回客户端的连接
while True:
#接受一个新连接
# sock 返回的是一个指向socket对象的变量地址如: <socket._socketobject object at 0x7faa50d134b0>
# addr 返回的是一个tuple(元组),分别是ip和client的端口,如: ('127.0.0.1', 55372)
sock,addr = s.accept()
#创建一个新线程,执行tcplink方法,
t = threading.Thread(target=tcplink,args=(sock,addr))
#启动线程
t.start()
客户端-服务器案例(客户端)
#如果遇到socket.error,因为还没打开服务器的socket
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('127.0.0.1',9999))
print s.recv(1024)#在发送数据前接收一个1k数据并打印出来
for data in ['HJC','KING','SONG']:
s.send(data)
print s.recv(1024)
s.send('exit')
s.close()#有接收就有关闭
4.UDP(非安全通信,就是发了有收不到)
服务器
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)#留意是DGRAM不是STREAM
s.bind(('127.0.0.1', 9999)) #TCP和UDP同一时间使用相同端口9999也不冲突
print 'bind UDP on 9999'
while True:
data,addr=s.recvfrom(1024) #recvfrom返回数据data和addr(地址IP和端口)
print 'received from %s:%s' % attr
s.sendto('hello.%s!'% data,attr)#snedto发送是指定用UDP发送,data和attr不能用括号包起来
客户端
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for data in ['Michael', 'Tracy', 'Sarah']:
# 发送数据:
s.sendto(data, ('127.0.0.1', 9999))
# 接收数据:
print s.recv(1024)
s.close()
5.smtp(发email)
(huangjicong19@163.com发,404811959@qq.com和huangjicong19@tom.com收)
文本邮件
#! /usr/bin/env python
#-*- coding: utf-8 -*-
# from email import encoders ##用于base64编码,附件上用
from email.header import Header #用于添加email头
from email.mime.text import MIMEText #用于添加email内容
#parseaddr可以解析出名字和<>中的email地址,format(格式化)是parseaddr的反作用
from email.utils import parseaddr,formataddr
import smtplib #搭建smtp协议用的
#格式化邮件头
def _format_addr(s):#s:你大哥<huangjicong19@163.com>
name,addr=parseaddr(s)#解析出标题和地址,name:你大哥,addr:huangjicong19@163.com
#发件人: 昵称<地址>。通常昵称是中文,中文的编码包括,unicode,gbk,utf-8,所以不知道输入的是哪一种编码,而我们务必要将其变为utf-8,不然到时候收取邮件时解码就麻烦了.
#formataddr案例:>>>formatattr(('a','b')),返回a<b>
return formataddr(( \
#加上encode()返回是个str,如果没有encode(),header返回的是个instance类型[原因是header没有继承objcet],
Header(name,'utf-8').encode(), \
#如果地址是unicode,让其变成utf-8编码
addr.encode('utf-8') if isinstance(addr,unicode) else addr))
# 手动输入的方法如下4行注释,这里为了方便,暂时不用
# from_addr = raw_input('From: ')
# password = raw_input('Password: ')
# to_addr = raw_input('To: ')
# smtp_server = raw_input('SMTP server: ')
from_addr = 'huangjicong19@163.com' #*from_addr是ascii码.没有中文的字符串是ascii码,有中文的变成utf-8码
password = '123321'
to_addr = '404811959@qq.com'
to_addr2 = 'huangjicong19@tom.com'
smtp_server = 'smtp.163.com'
#创建msg实例对象
#第一个参数是邮件正文,第二个参数是MIME的subtype,传入'plain',最终的MIME就是'text/plain''最后一定要用utf-8编码保证多语言兼容性
msg = MIMEText('你大哥我的女朋友超级漂亮...','plain','utf-8')
#设置发件方:你大哥<huangjicong19@163.com>
#用Header('你大哥<%s>' % from_addr,'utf-8') 的话,在手机微信邮箱提醒上昵称变回了huangjicong19,但在邮箱客户端还是你大哥。
msg['From'] = _format_addr('你大哥<%s>' % from_addr)
#设置收件方:小弟<40481159@qq.com>
msg['To'] = _format_addr(u'小弟<%s>' % to_addr)
#设置邮件主题:大哥给你来报喜...
msg['Subject'] = Header('大哥给你来报喜...','utf-8')#.encode()#如果不是utf-8编写括号中的字符串,请用encode()
# 设置SMTP服务器地址,就是邮箱的代理商
server = smtplib.SMTP(smtp_server,25) #邮箱端口一般为25
#打印和SMTP服务器交互的所有信息
server.set_debuglevel(1)
#登录SMTP服务器
server.login(from_addr,password)
#发送邮件,多人邮件直接在【】里加,用逗号隔开
server.sendmail(from_addr,[to_addr,to_addr2],msg.as_string())
#停止连接服务
server.quit()
html邮件
#就是在文本邮件基础上改一下MIMeText中'plain'变成'html',内容变成网页代码
msg = MIMEText('<html><body><h1>你大哥我的女朋友超级漂亮...</h1>'+
'<p>不信就自己查bing,<a href="http://www.bing.com">必应</a>,'+
'嘿嘿嘿...</p></body></html>','html','utf-8')
发附件
#! /usr/bin/env python
#-*- coding: utf-8 -*-
from email.mime.multipart import MIMEMultipart #用来生成包含多个部分的邮件体的MIME对象。
from email.mime.base import MIMEBase #所有MIME类的基类,是email.message.Message类的子类。
from email import encoders #用于base64编码,附件上用
from email.header import Header #用于添加email头
from email.mime.text import MIMEText #用于添加email内容
#parseaddr可以解析出名字和<>中的email地址,format(格式化)是parseaddr的反作用
from email.utils import parseaddr,formataddr
import smtplib #搭建smtp协议用的
#格式化邮件头
def _format_addr(s):#s:你大哥<huangjicong19@163.com>
name,addr=parseaddr(s)#解析出标题和地址,name:你大哥,addr:huangjicong19@163.com
#发件人: 昵称<地址>。通常昵称是中文,中文的编码包括,unicode,gbk,utf-8,所以不知道输入的是哪一种编码,而我们务必要将其变为utf-8,不然到时候收取邮件时解码就麻烦了.
#formataddr案例:>>>formatattr(('a','b')),返回a<b>
return formataddr(( \
#加上encode()返回是个str,如果没有encode(),header返回的是个instance类型[原因是header没有继承objcet],
Header(name,'utf-8').encode(), \
#如果地址是unicode,让其变成utf-8编码
addr.encode('utf-8') if isinstance(addr,unicode) else addr))
# 手动输入的方法如下4行注释,这里为了方便,暂时不用
# from_addr = raw_input('From: ')
# password = raw_input('Password: ')
# to_addr = raw_input('To: ')
# smtp_server = raw_input('SMTP server: ')
from_addr = 'huangjicong19@163.com' #*from_addr是ascii码.没有中文的字符串是ascii码,有中文的变成utf-8码
password = '123321'
to_addr2 = '493684419@qq.com'
to_addr = 'huangjicong19@tom.com'
smtp_server = 'smtp.163.com'
#创建msg实例对象
msg = MIMEMultipart()
#设置发件方:你大哥<huangjicong19@163.com>
#用Header('你大哥<%s>' % from_addr,'utf-8') 的话,在手机微信邮箱提醒上昵称变回了huangjicong19,但在邮箱客户端还是你大哥。
msg['From'] = _format_addr('你大哥<%s>' % from_addr)
#设置收件方:小弟<40481159@qq.com>,msg['To']接受的是字符串不是list,多个邮箱用逗号分开即可。
msg['To'] = _format_addr(u'小弟<%s>' % to_addr)
#设置邮件主题:大哥给你来报喜...
msg['Subject'] = Header('大哥给你来报喜...','utf-8')#.encode() #如果不是utf-8编写括号中的字符串,请用encode()
#邮件正文
msg.attach(MIMEText('啦啦啦','plain','utf-8'))
with open( 'D:\\forpython\dong.jpg','rb') as f:
mime = MIMEBase('image','jpg',filename='man.jpg')
#添加必要的头信息:Msg.add_header(_name, _value, **_params): 添加邮件头字段。
mime.add_header('Content-Disposition','attachment',filename='man.jpg')
mime.add_header('Content-ID','<0>')
mime.add_header('X-Attachment-Id','0')
#把附件的内容读进来:
mime.set_payload(f.read())
#用base64编码
encoders.encode_base64(mime)
#添加到MIMEMultipart
msg.attach(mime)
# 设置SMTP服务器地址,就是邮箱的代理商
server = smtplib.SMTP(smtp_server,25) #邮箱端口一般为25
#打印和SMTP服务器交互的所有信息
server.set_debuglevel(1)
#登录SMTP服务器
server.login(from_addr,password)
#发送邮件
server.sendmail(from_addr,[to_addr,to_addr2],msg.as_string())
#停止连接服务
server.quit()
邮件正文中显示图片
# 在附件的基础上将附件的图片显示在邮件正文中,附件就不显示了
msg.attach(MIMEText('<html><body><h1>Hello</h1><p><img src="cid:0"></p></body></html>','html','utf-8'))
如果不能发送html,就发送文本
#就是在MIMEMultipart引出参数alternative(本词翻译是2选1)
msg = MIMEMultipart('alternative')
msg['From'] = ...
msg['To'] = ...
msg['Subject'] = ...
msg.attach(MIMEText('hello', 'plain', 'utf-8'))
msg.attach(MIMEText('<html><body><h1>Hello</h1></body></html>', 'html', 'utf-8'))
# 正常发送msg对象...
加密SMTP
server = smtplib.SMTP(smtp_server,25) #邮箱端口一般为25
# 加密SMTP:在创建SMTP后,就上这句
#没有这个,邮件在上传到服务器是会容易被窃听的。
server.starttls()
邮件对象关系
Message
+- MIMEBase #基准
+- MIMEMultipart #包括文本,图片,附件
+- MIMENonMultipart
+- MIMEMessage #文本
+- MIMEText
+- MIMEImage #图片