16.1 理论基础
web应用:
遵循客户端/服务器架构。客户端是浏览器,服务端是web服务器。
web客户端与服务器:
交互使用HTTP协议(超文本传输协议),属于无状态协议。
web服务器持续运行,但客户端的活动是以单个事件划分的。客户端由于每个请求缺乏上下文,因此有些URL中含有很长很长的变量值,这些将作为请求的一部分,以提供一些状态信息。另一种方式是使用“cookie”,即保存在客户端的客户状态信息。
HTTPS:
在传输敏感数据过程中,要对数据进行加密,即在普通套接字上添加一个额外的安全层,称为安全套接字层(SSL),用来创建一个加密传输数据的套接字。
正向代理服务器:
主要针对客户端。它可以只让一部分计算机访问网络,也可以监控网络数据传输,还可以缓存web数据(此举主要体现在在重复访问同一网页时,后次访问无需加载到web服务端,提高速度)
反向代理服务器:
主要针对服务端。与以上相反,扮演服务端的角色(如缓存服务器数据、负载平衡等)
16.2 web编程相关模块汇总
具体如下:
Web应用程序
方法 | 解释 |
---|---|
cgi | 从标准网关接口(CGI)获取数据 |
cgitb | 处理CGI返回数据 |
htmllib | 老HTML解析器,用于解析简单的HTML文件;HTML-Parser类扩展自sgmllib.SGMLParser |
HTMLparser | 新的HTML、XHTML解析器,不基于SGML |
htmlentitydefs | 一些HTML普通实体定义 |
Cookie | 用于HTTP状态管理的服务器端cookie |
cookielib | HTTP客户端的cookie处理类 |
webbrowser | 控制器:向浏览器加载Web文档 |
sgmllib | 解析简单的SGML文件 |
robotparser | 解析robots.txt文件,对URL做“可获得性”分析 |
httplib | 用来创建HTTP客户端 |
urllib | 通过URL或相关工具访问服务器。新版本urllib.open()已删除 |
urllib2 | 用于打开URL的类和函数。常用有urllib2.open() |
urlparse | 用于解析URL字符串的工具 |
XML处理
方法 | 解释 |
---|---|
xmllib | 原来的简单XML解析器(已废弃) |
xml | 包含许多不同解析器的XML包(见下文) |
xml.sax | 简单的API,适用于兼容SAX2的XML(SAX)解析器 |
xml.dom | 文档对象模型(DOM)XML解析器 |
xml.etree | 树形的XML解析器,基于Element灵活容器对象 |
xml.parsers.expat | 非验证型Expat XML解析器的接口 |
xmlrpclib | 通过HTTP提供XML远程过程调用(RPC)客户端 |
SimpleXMLRPCServer | Python XML-RPC服务器的基本框架 |
DocXMLRPCServer | 自描述XML-RPC服务器的框架 |
Web服务器
方法 | 解释 |
---|---|
BaseHTTPServer | 用来开发Web服务器的抽象类 |
SimpleHTTPServer | 处理最简单的HTTP请求(HEAD和GET) |
CGIHTTPServer | 和SimpleHTTPServer一样处理Web文件,还能处理CGI(HTTP POST)请求 |
wsgiref | 定义Web服务器和Python Web应用程序间标准接口的包 |
第三方开发包(非标准库)
方法 | 解释 |
---|---|
HTMLgen | 协助CGI把Python对象转换成可用的HTML |
BeautifulSoup | HTML、XML解析器及转换器 |
Mechanize | 基于万维网的Web浏览包 |
16.3 python web客户端工具
统一资源定位符(URL)用来在web上定位一个文档,或者调用CGI程序(通用网关接口。一段程序,运行在服务器上)来为客户端生成一个文档。
URL的各个组件:
方法 | 解释 |
---|---|
pro_sch | 网络协议或者下载规划 |
net_loc | 服务器位置(可能包含用户信息) |
path | 文件或CGI应用程序路径 |
param | 可选参数 |
query | 连接符(&)连接一系列的键值对 |
frag | 拆分文档中的特殊锚 |
net_loc可以进一步拆分,如下:
方法 | 解释 |
---|---|
user | 用户名或登录 |
passwd | 用户密码 |
host | 运行Web服务器的计算机名称或地址(必需的) |
port | 端口号(如果不是默认的80) |
urlparse模块
用于处理URL字符串
方法 | 解释 |
---|---|
urlparse(urlstr,defProtSch=None,allowFrag=None) | 将urlstr解析成各个组件,如果在urlstr中没有给定协议或者方案,则使用defProtSch;allowFrag决定是否允许有URL片段 |
urlunparse(urltup) | 将URL数据(urltup)的一个元组拼成一个URL字符串 |
urljoin(baseurl,newurl,allowFrag=None) | 将URL的根域名和url路径拼合成一个完整的URL;allowFrag的作用和urlpase()相同 |
urllib模块
方法 | 解释 |
---|---|
urlretrieve(urlstr,localfile=None,downloadStatusHook=None) | 将URL urlstr中的文件下载到localfile或临时文件中(如果没有指定本地文件);如果函数正在执行,downloadStatusHook将会获得下载的统计信息 |
quote(urldata,safe=’/’) | 对urldata在URL里无法使用的字符进行编码,safe中的字符无须编码 |
quote_plus(urldata,safe=’/’) | 除了将空格编译成加(+)号(而非%20)之外,其他功能与quote()相似 |
unquote(urldata) | 将urldata中编码过的字符解码 |
unquote_plus(urldata) | 除了将加号转换成空格,其他功能与unquote()相同 |
urlencode(dict) | 将dict的键值对通过quote_plus()编译成有效的CGI查询字符串,用quote_plus()对这个字符串进行编码 |
urllib2.open()
自python2.6之后,urllib.open()就已经不存在了,取而代之的是urllib2.open()
语法如下:
方法 | 解释 |
---|---|
urlopen(urlstr,postQueryData=None) | 打开URL地址,如果是POST请求,则通过postQueryData发送请求的数据 |
urlopen()文件类型对象的方法:
方法 | 解释 |
---|---|
f.read([bytes]) | 从f中读出所有或bytes个字节 |
f.readline() | 从f中读取一行 |
f.readlines() | 从f中读出所有行,作为列表返回 |
f.close() | 关闭f的URL连接 |
f.fileno() | 返回f的文件句柄 |
f.info() | 获得f的MIME头文件 |
f.geturl() | 返回f的真正URL |
代码实例:http验证
#-*-coding:utf-8-*-
import urllib2 #导入模块
LOGIN = 'Lalala' #用户名
PASSWD = "wutianxualalala" #密码
URL = 'http://www.wutianxu.com' #正确的网址
REALM ='Secure Archive'
#基础认证处理器方法,理解就是url并未改变,只是安装了某个东西,可以打开所有URL
def handler_version(url):
from urlparse import urlparse as up
hdlr = urllib2.HTTPBasicAuthHandler() #基本处理器类实例化
hdlr.add_password('Archives',up(url)[1],LOGIN,PASSWD) #添加认证信息
opener = urllib2.build_opener(hdlr) #建立一个URL-opener
urllib2.install_opener(opener) #安装
return url
#认证头方法,在url字符串中加入认证头,实际等同于改变url字符串
def request_version(url):
from base64 import encodestring
req = urllib2.Request(url) #request对象
b64str = encodestring('%s:%s' % (LOGIN, PASSWD))[:-1]
req.add_header("Authorization", "Basic %s" % b64str) #添加base64编码认证头信息
return req
for funcType in ('handler','request'):
print "*** Using %s:" % funcType.upper()
url = eval('%s_version' % funcType)(URL)
f = urllib2.urlopen(url)
print f.readline()
f.close()
urllib和urllib2的区别
1、urllib2可以接受一个Request对象,并以此可以来设置一个URL的headers,但是urllib只接收一个URL。这意味着,你不能伪装你的用户代理字符串等。
2、urllib模块可以提供进行urlencode的方法,该方法用于GET查询字符串的生成,urllib2的不具有这样的功能。这就是urllib与urllib2经常在一起使用的原因。
总之,可以理解为urllib2是urllib的超集,但它们又各有用途,不可被另一方取代。
16.4 爬虫实例
常规情况下爬虫
# -*- coding:utf-8 -*-
#下载贴吧中所有图片
import re
import urllib
import time
def gethtml(url):
page = urllib.urlopen(url) #打开url
html = page.read() #读取页面源代码
return html #返回页面源代码
def getimg(html):
reg = r'src="(.*?\.jpg)"' #正则。注意单引号要在外围
imgre = re.compile(reg) #为了让其更快,对其做编译
imglist=re.findall(imgre,html) #返回所有匹配结果,组成列表
x=0
for imgurl in imglist: #遍历
urllib.urlretrieve(imgurl,'%s.jpg' % x) #遍历列表重命名
x+=1
time.sleep(1) #睡眠。防止被防火墙拦截
html = gethtml("https://tieba.baidu.com/p/54394") #要抓取的页面
print getimg(html)