1.urllib包简介
urllib包主要模块有:
1.urllib.request -----用于打开 URL网址;
2.urllib.error ---------定义了常见的urllib.request会引发的异常;
3.urllib.parse---------用于解析 URL;
具体方法:
urllib.request.urlopen( url,data,proxies ) :用于打开 url
参数如下:
url:要进行操作的 URL地址
data:可选项。向URL 传递的数据。
proxies:可选项。使用的代理地址
import urllib.request
url = ‘http://www.baidu.com’ #网页为百度首页
respone = urllib.request.urlopen(url) #打开url地址,并返回一个 HTTPRespone
实例
html = respone.read().decode(‘utf-8’) #调用实例的 read()方法,并用 utf-8进行解码处理。就得出完整的百度的HTML文件
print(html)
部分打印结果:
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta content="always" name="referrer">
<meta name="theme-color" content="#2932e1">
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
<link rel="search" type="application/opensearchdescription+xml" href="/content-search.xml" title="百度搜索" />
<link rel="icon" sizes="any" mask href="//www.baidu.com/img/baidu.svg">
urllib.request.urlretrieve(url,filename,reporthook,data) :用于将 URL的HTML文件下载并保存为本地文件
参数如下:
url:要下载的网页
filename:保存在主机的路径,可选项。
reporthook:一个回调函数,可选项。
data:发送的数据,一般用于 post,可选项。
2. http包简介
http包提供了 HTTP协议的一些功能,主要模块有:
http.client — 底层的 HTTP 协议的一些功能,可以为 urllib.request 模块所用
http.server — 提供了基于 socketserver模块的基本 HTTP服务器类
http.cookies — cookies 的管理工具
http.client :
HttpClient不是一个浏览器。它是一个客户端的HTTP通信实现库。HttpClient的目标是发送和接收HTTP报文。
两个主要类(用于客户端):
HTTPConnection :基于HTTP协议的客户端,指定 URL(网址) 后,可以 发送请求报文 和 接收响应报文
HTTPRespone :基于 HTTP 协议的服务端回应。一旦用 HTTPConnection 成功连接,可以调用相关方法返回该实例(HTTPRequest实例)。
(1)HTTPConnection 的方法:
构造方法: HTTPConnection( host,port,[timeout] ) 返回一个HTTPConnection 实例
host:表示主机域名或 ip 地址
port:表示端口
timeout:阻塞操作将会在给定时间后超时。可选项
发送请求报文方法:HTTPConnection.request( method,url,body =None,headers = {} )
method:发送的操作,一般为 GET 或者 POST
url :进行操作的 url
body :所发送的数据
headers:发送的 HTTP头部,是一个字典类型
***获取响应报文方法:HTTPConnection.getrespone( )
关闭与服务器的连接: HTTPConne.close()
发送一个头部:HTTPConnection.putheader( header,args[ ] ) #头部以一个字典方式发送
发送一个空白行到服务器,标志头部Header的结束:HTTPConnection.endheaders( )
发送数据到服务器:HTTPConnection.send( data ) ,应该在endheaders()之后 和 getrespone()之前调用。 ***
(2)HTTPRespone:
HTTPRespone对象:一旦用 HTTPConnection 成功连接,可以调用HTTPConnection.getrespone()返回该实例(HTTPRequest实例)。
HTTPRespone.getheader(name) :返回头部中的 name 字段对应的值
HTTPRespone.getheaders( ) :以元组的方式返回整个头部的信息
HTTPRespone.read() :返回响应报文中的body部分,也即正文部分
HTTPRespone.status #返回状态码
HTTPRespone.version #返回 HTTP协议版本
http 包应用实例 。
from http.client import HTTPConnection
con = HTTPConnection('www.baidu.com',80)
con.request('GET','/') #发送请求报文
res = con.getresponse() #获取响应报文对象
print(res.status) #200 (表示状态码)
print(res.reason) #OK (表示状态码对应的意义)
print(res.read().decode('utf-8')) #打印www.baidu.com的html
ftplib模块
函数释义
Python中默认安装的ftplib模块定义了FTP类,其中函数有限,可用来实现简单的ftp客户端,用于上传或下载文件,函数列举如下
ftp登陆连接
from ftplib import FTP #加载ftp模块
ftp=FTP() #设置变量
ftp.set_debuglevel(2) #打开调试级别2,显示详细信息
ftp.connect("IP","port") #连接的ftp sever和端口
ftp.login("user","password") #连接的用户名,密码
print ftp.getwelcome() #打印出欢迎信息
ftp.cmd("xxx/xxx") #进入远程目录
bufsize=1024 #设置的缓冲区大小
filename="filename.txt" #需要下载的文件
file_handle=open(filename,"wb").write #以写模式在本地打开文件
ftp.retrbinaly("RETR filename.txt",file_handle,bufsize) #接收服务器上文件并写入本地文件
ftp.set_debuglevel(0) #关闭调试模式
ftp.quit() #退出ftp
ftp相关命令操作
ftp.cwd(pathname) #设置FTP当前操作的路径
ftp.dir() #显示目录下所有目录信息
ftp.nlst() #获取目录下的文件
ftp.mkd(pathname) #新建远程目录
ftp.pwd() #返回当前所在位置
ftp.rmd(dirname) #删除远程目录
ftp.delete(filename) #删除远程文件
ftp.rename(fromname, toname)#将fromname修改名称为toname。
ftp.storbinaly("STOR filename.txt",file_handel,bufsize) #上传目标文件
ftp.retrbinary("RETR filename.txt",file_handel,bufsize) #下载FTP文件
FTP.quit()与FTP.close()的区别
FTP.quit():发送QUIT命令给服务器并关闭掉连接。这是一个比较“缓和”的关闭连接方式,但是如果服务器对QUIT命令返回错误时,会抛出异常。
FTP.close():单方面的关闭掉连接,不应该用在已经关闭的连接之后,例如不应用在FTP.quit()之后。
FTP.quit()与FTP.close()的区别
FTP.quit():发送QUIT命令给服务器并关闭掉连接。这是一个比较“缓和”的关闭连接方式,但是如果服务器对QUIT命令返回错误时,会抛出异常。
FTP.close():单方面的关闭掉连接,不应该用在已经关闭的连接之后,例如不应用在FTP.quit()之后。
例1:下载、上传文件
#coding: utf-8
from ftplib import FTP
import time
import tarfile
#!/usr/bin/python
#-*- coding: utf-8 -*-
from ftplib import FTP
def ftpconnect(host, username, password):
ftp = FTP()
#ftp.set_debuglevel(2) #打开调试级别2,显示详细信息
ftp.connect(host, 21) #连接
ftp.login(username, password) #登录,如果匿名登录则用空串代替即可
return ftp
def downloadfile(ftp, remotepath, localpath):
bufsize = 1024 #设置缓冲块大小
fp = open(localpath,'wb') #以写模式在本地打开文件
ftp.retrbinary('RETR ' + remotepath, fp.write, bufsize) #接收服务器上文件并写入本地文件
ftp.set_debuglevel(0) #关闭调试
fp.close() #关闭文件
def uploadfile(ftp, remotepath, localpath):
bufsize = 1024
fp = open(localpath, 'rb')
ftp.storbinary('STOR '+ remotepath , fp, bufsize) #上传文件
ftp.set_debuglevel(0)
fp.close()
if __name__ == "__main__":
ftp = ftpconnect("******", "***", "***")
downloadfile(ftp, "***", "***")
uploadfile(ftp, "***", "***")
ftp.quit()
例2:上传、下载文件/目录
#coding:utf-8
from ctypes import *
import os
import sys
import ftplib
class myFtp:
ftp = ftplib.FTP()
bIsDir = False
path = ""
def __init__(self, host, port='21'):
#self.ftp.set_debuglevel(2) #打开调试级别2,显示详细信息
#self.ftp.set_pasv(0) #0主动模式 1 #被动模式
self.ftp.connect( host, port )
def Login(self, user, passwd):
self.ftp.login( user, passwd )
print self.ftp.welcome
def DownLoadFile(self, LocalFile, RemoteFile):
file_handler = open( LocalFile, 'wb' )
self.ftp.retrbinary( "RETR %s" %( RemoteFile ), file_handler.write )
file_handler.close()
return True
def UpLoadFile(self, LocalFile, RemoteFile):
if os.path.isfile( LocalFile ) == False:
return False
file_handler = open(LocalFile, "rb")
self.ftp.storbinary('STOR %s'%RemoteFile, file_handler, 4096)
file_handler.close()
return True
def UpLoadFileTree(self, LocalDir, RemoteDir):
if os.path.isdir(LocalDir) == False:
return False
print "LocalDir:", LocalDir
LocalNames = os.listdir(LocalDir)
print "list:", LocalNames
print RemoteDir
self.ftp.cwd( RemoteDir )
for Local in LocalNames:
src = os.path.join( LocalDir, Local)
if os.path.isdir( src ): self.UpLoadFileTree( src, Local )
else:
self.UpLoadFile( src, Local )
self.ftp.cwd( ".." )
return
def DownLoadFileTree(self, LocalDir, RemoteDir):
print "remoteDir:", RemoteDir
if os.path.isdir( LocalDir ) == False:
os.makedirs( LocalDir )
self.ftp.cwd( RemoteDir )
RemoteNames = self.ftp.nlst()
print "RemoteNames", RemoteNames
print self.ftp.nlst("/del1")
for file in RemoteNames:
Local = os.path.join( LocalDir, file )
if self.isDir( file ):
self.DownLoadFileTree( Local, file )
else:
self.DownLoadFile( Local, file )
self.ftp.cwd( ".." )
return
def show(self, list):
result = list.lower().split( " " )
if self.path in result and "<dir>" in result:
self.bIsDir = True
def isDir(self, path):
self.bIsDir = False
self.path = path
#this ues callback function ,that will change bIsDir value
self.ftp.retrlines( 'LIST', self.show )
return self.bIsDir
def close(self):
self.ftp.quit()
if __name__ == "__main__":
ftp = myFtp('*****')
ftp.Login('***','***')
ftp.DownLoadFileTree('del', '/del1')#ok
ftp.UpLoadFileTree('del', "/del1" )
ftp.close()
print "ok!"
用poplib模块和smtplib模块收发电子邮件
poplib模块接收邮件
python的poplib模块是用来从pop3收取邮件的,也可以说它是处理邮件的第一步。
POP3协议并不复杂,它也是采用的一问一答式的方式,你向服务器发送一个命令,服务器必然会回复一个信息。pop3命令码如下:
命令 poplib方法 参数 状态 描述
-----------------------------------------------------------------------------------------------
USER user username 认可 用户名,此命令与下面的pass命令若成功,将导致状态转换
PASS pass_ password 认可 用户密码
APOP apop Name,Digest 认可 Digest是MD5消息摘要
-----------------------------------------------------------------------------------------------
STAT stat None 处理 请求服务器发回关于邮箱的统计资料,如邮件总数和总字节数
UIDL uidl [Msg#] 处理 返回邮件的唯一标识符,POP3会话的每个标识符都将是唯一的
LIST list [Msg#] 处理 返回邮件数量和每个邮件的大小
RETR retr [Msg#] 处理 返回由参数标识的邮件的全部文本
DELE dele [Msg#] 处理 服务器将由参数标识的邮件标记为删除,由quit命令执行
RSET rset None 处理 服务器将重置所有标记为删除的邮件,用于撤消DELE命令
TOP top [Msg#] 处理 服务器将返回由参数标识的邮件前n行内容,n必须是正整数
NOOP noop None 处理 服务器返回一个肯定的响应
----------------------------------------------------------------------------------------------
QUIT quit None 更新
python的poplib也针对这些命令分别提供了对应的方法,上面在第二列里已经标出来。收取邮件的过程一般是:
- 连接pop3服务器 (poplib.POP3.init)
- 发送用户名和密码进行验证 (poplib.POP3.user poplib.POP3.pass_)
- 获取邮箱中信件信息 (poplib.POP3.stat)
- 收取邮件 (poplib.POP3.retr)
- 删除邮件 (poplib.POP3.dele)
- 退出 (poplib.POP3.quit)
注意的是,上面我在括号里写的是使用什么方法来完成这个操作,在实际的代码中不能那样写,应该是创建poplib.POP3的对象,然后,调用这个对象的方法。比如:
poplib.POP3.quit
应该理解为
a = poplib.POP3(host)
a.quit()
下面看看实际的代码:
-*- encoding: gb2312 -*-
import os, sys, string
import poplib
# pop3服务器地址
host = "pop3.163.com"
# 用户名
username = "xxxxxx@163.com"
# 密码
password = "xxxxxxx"
# 创建一个pop3对象,这个时候实际上已经连接上服务器了
pp = poplib.POP3(host)
# 设置调试模式,可以看到与服务器的交互信息 pp.set_debuglevel(1)
# 向服务器发送用户名
pp.user(username)
# 向服务器发送密码
pp.pass_(password)
# 获取服务器上信件信息,返回是一个列表,第一项是一共有多上封邮件,第二项是共有多少字节
ret = pp.stat() print ret
# 需要取出所有信件的头部,信件id是从1开始的。
for i in range(1, ret[0]+1):
# 取出信件头部。注意:top指定的行数是以信件头为基数的,也就是说当取0行,
# 其实是返回头部信息,取1行其实是返回头部信息之外再多1行。
mlist = pp.top(i, 0)
print 'line: ', len(mlist[1])
# 列出服务器上邮件信息,这个会对每一封邮件都输出id和大小。不象stat输出的是总的统计信息
ret = pp.list()
print ret
# 取第一封邮件完整信息,在返回值里,是按行存储在down[1]的列表里的。down[0]是返回的状态信息
down = pp.retr(1)
print 'lines:', len(down)
# 输出邮件
for line in down[1]:
print line
# 退出
pp.quit()
在有些地方,有安全邮件这一说,其实是对pop3做了ssl加密。这样的,poplib一样可以处理,只不过不是用POP3这个类,而是用POP3_SSL, 他们的方法都一样。因此支持ssl在上面代码中,替换创建pop3对象的一行为:
pp = poplib.POP3_SSL(host)
smtplib: 用python发送SSL/TLS安全邮件
python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了简单的封装。
smtp协议的基本命令包括:
- HELO 向服务器标识用户身份
- MAIL 初始化邮件传输 mail from:
- RCPT 标识单个的邮件接收人;常在MAIL命令后面,可有多个rcpt to:
- DATA 在单个或多个RCPT命令后,表示所有的邮件接收人已标识,并初始化数据传输,以.结束
- VRFY 用于验证指定的用户/邮箱是否存在;由于安全方面的原因,服务器常禁止此命令
- EXPN 验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用
- HELP 查询服务器支持什么命令
- NOOP 无操作,服务器应响应OK
- QUIT 结束会话
- RSET 重置会话,当前传输被取消
- MAIL FROM 指定发送者地址
- RCPT TO 指明的接收者地址
一般smtp会话有两种方式,一种是邮件直接投递,就是说,比如你要发邮件給zzz@163.com,那就直接连接163.com的邮件服务器,把信投給zzz@163.com; 另一种是验证过后的发信,它的过程是,比如你要发邮件給zzz@163.com,你不是直接投到163.com,而是通过自己在sina.com的另一个邮箱来发。这样就要先连接sina.com的smtp服务器,然后认证,之后在把要发到163.com的信件投到sina.com上,sina.com会帮你把信投递到163.com。
第一种方式的命令流程基本是这样:
- helo
- mail from
- rcpt to
- data
- quit
但是第一种发送方式一般有限制的,就是rcpt to指定的这个邮件接收者必须在这个服务器上存在,否则是不会接收的。
先看看代码:
-*- encoding: gb2312 -*-
import os, sys, string
import smtplib
# 邮件服务器地址
mailserver = "smtp.163.com"
# smtp会话过程中的mail from地址
from_addr = "asfgysg@zxsdf.com"
# smtp会话过程中的rcpt to地址
to_addr = "zhaoweikid@163.com"
# 信件内容 msg = "test mail"
svr = smtplib.SMTP(mailserver)
# 设置为调试模式,就是在会话过程中会有输出信息
svr.set_debuglevel(1)
# helo命令,docmd方法包括了获取对方服务器返回信息
svr.docmd("HELO server")
# mail from, 发送邮件发送者
svr.docmd("MAIL FROM: <%s>" % from_addr)
# rcpt to, 邮件接收者
svr.docmd("RCPT TO: <%s>" % to_addr)
# data命令,开始发送数据
svr.docmd("DATA")
# 发送正文数据
svr.send(msg)
# 比如以 . 作为正文发送结束的标记,用send发送的,所以要用getreply获取返回信息
svr.send(" . ")
svr.getreply()
# 发送结束,退出
svr.quit()