web应用也遵循客户服务器架构
浏览器就是一个基本的web客户端,她实现两个基本功能,一个是从web服务器下载文件,另一个是渲染文件
同浏览器具有类似功能以实现简单的web客户端的模块式urllib以及urllib2(可以打开需要登录的网页)等模块
另外还有一些负载的web客户端,它不仅下载web文件,还执行其它复杂的任务,一个典型的例子就是爬虫
python实现爬虫也有一些框架模块:如Scrapy
使用python创建一个简单web客户端
你要弄清楚浏览器只是web客户端的一种,而且功能有限,任何通过web的请求的应用程序都是web客户端
比如curl以及python的urllib
为什么是urllib呢而不是httplib呢?往下阅读
什么是URL???构成很重要
URL用来在Web 上定位一个文档,或者调用一个CGI 程序来为你的客户端产生一个文档。
CGI产生文档就是像一些web框架吧,特别是python的
web客户端其实也算是 文件传输,最为直接方式就是直接使用url来定位和获得文件了,其实大部分客户端都是靠这个
所以应该首先 了解一下url的构成
python的URL模块介绍:urllib及urlparse
Python 支持两种不同的模块,分别以不同的功能和兼容性来处理URL。一种是urlparse,一种
是urllib。
其中urlparse就是用来进行url解析与合成的。利用它你也可以学习url的构成哦,关于它的用法你可以help一下
urllib是一个高层次的模块,urllib 模块提供了所有你需要的功能,除非你计划写一个更加低层的网络客户端。urllib 提供
了了一个高级的Web 交流库,支持Web 协议,HTTP, FTP 和Gopher 协议,同时也支持对本地文件的
访问。urllib 模块的特殊功能是利用上述协议下载数据(从因特网、局域网、主机上下载)。使用这
个模块可以避免使用httplib, ftplib 和gopherlib 这些模块,除非你想用更低层的功能
urllib的主要功能就是从url来下载文件,想要了解这个模块的功能可以从下面几个函数入手
urlopen()
urllib.urlretrieve()
urllib.quote() and urllib.quote_plus()
urllib.unquote() 和 urllib.unquote_plus()
urllib.urlencode()
urllib2
如果你打算访问更加复杂的URL 或者想要处理更复杂的情况如基于数字的权限验证,重定位,
coockie 等问题,我们建议你使用urllib2 模块
这对于登陆来抓取数据是特别有用的
urllib3
urllib2的升级版
Requests
该模块建立在urllib3上面的,提供了比较友好的借口,尽量使用它,以减少代码量
参考:
wget和python绑定
wget是一个linux命令行工具,专注下载功能,有关下载任务合适使用它的python绑定
curl和pycurl
curl是一个基础的,先进的命令行工具(提供的功能类似于Request),也提供了各种语言的绑定
高级web客户端
浏览器实现的其实是一个简单的web客户端,基本的web客户端从服务器下载文件,urllib以及urllib2以及上面介绍的这些模块就是实现类似的功能
那么高级的web客户端就不只是下载那么简单
高级Web 客户端的一个例子就是网络爬虫(aka 蜘蛛和机器人)。这些程序可以基于不同目的在
因特网上探索和下载页面,其中包括:
- 为 Google 和Yahoo 这类大型的搜索引擎建索引
- 脱机浏览—将文档下载到本地,重新设定超链接,为本地浏览器创建镜像。(这个需求就是通常所说的下载整个在线的帮助文档)
- 下载并保存历史记录或框架
- Web 页的缓存,节省再次访问Web 站点的下载时间。
这里给出一个爬虫的实现
1 #!/usr/bin/env python
2
3 from sys import argv
4 from os import makedirs, unlink, sep
5 from os.path import isdir, exists, dirname, splitext
6 from string import replace, find, lower
7 from htmllib import HTMLParser
8 from urllib import urlretrieve
9 from urlparse import urlparse, urljoin
10 from formatter import DumbWriter, AbstractFormatter
11 from cStringIO import StringIO
12
13 class Retriever(object): # download Web pages
14
15 def __init__(self, url):
16 self.url = url
17 self.file = self.filename(url)
18
19 def filename(self, url, deffile='index.htm'):
20 parsedurl = urlparse(url, 'http:', 0) # parse path
21 path = parsedurl[1] + parsedurl[2]
22 ext = splitext(path)
23 if ext[1] == '':
24 if path[-1] == '/':
25 path += deffile
26 else:
27 path += '/' + deffile
28 ldir = dirname(path) # local directory
29 if sep != '/': # os-indep. path separator
30 ldir = replace(ldir, ',', sep)
31 if not isdir(ldir): # create archive dir if nec.
32 if exists(ldir): unlink(ldir)
33 makedirs(ldir)
34 return path
35
36 def download(self): # download Web page
37 try:
38 retval = urllib.urlretrieve(self.url, self.file)
39 except IOError:
40 retval = ('*** ERROR: invalid URL "%s"' % \
41 self.url, )
42 return retval
43
44 def parseAndGetLinks(self): # pars HTML, save links
45 self.parser = HTMLParser(AbstractFormatter( \
46 DumbWriter(StringIO())))
47 self.parser.feed(open(self.file).read())
48 self.parser.close()
49 return self.parse.anchorlist
50
51 class Crawler(object): # manage entire crawling process
52
53 count = 0 # static downloaded page counter
54
55 def __init__(self, url):
56 self.q = [url]
57 self.seen = []
58 self.dom = urlparse(url)[1]
59
60 def getPage(self, url):
61 r = Retriever(url)
62 retval = r.download()
63 if retval[0] == '*': # error situation, do not parse
64 print retval, '... skipping parse'
65 return
66 Crawler.count = Crawler.count + 1
67 print '\n(', Crawler.count, ')'
68 print 'URL:', url
69 print 'FILE:', retval[0]
70 self.seen.append(url)
71
72 links = r.parseAndGetLinks() # get and process links
73 for eachLink in links:
74 if eachLink[:4] != 'http' and \
75 find(eachLink, '://') == -1:
76 eachLink = urljoin(url, eachLink)
77 print '* ', eachLink,
78
79 if find(lower(eachLink), 'mailto:') != -1:
80 print '... discarded, mailto link'
81 continue
82
83 if eachLink not in self.seen:
84 if find(eachLink, self.dom) == -1:
85 print '... discarded, not in domain'
86 else:
87 if eachLink not in self.q:
88 self.q.append(eachLink)
89 print '... new, added to Q'
90 else:
91 print '... discarded, already in Q'
92 else:
93 print '... discarded, already processed'
94
95 def go(self): # process links in queue
96 while self.q:
97 url = self.q.pop()
98 self.getPage(url)
99
100 def main():
101 if len(argv) > 1:
102 url = argv[1]
103 else:
104 try:
105 url = raw_input('Enter starting URL: ')
106 except (KeyboardInterrupt, EOFError):
107 url = ''
108
109 if not url: return
110 robot = Crawler(url)
111 robot.go()
112
113 if __name__ == '__main__':
114 main()
实际上这里也有一些爬虫的库,不多介绍