4
4
5
5
##urllib
6
6
7
- urllib模块用于读取来自网上(服务器上)的数据,比如不少人用python做爬虫程序,就可以使用这个模块。先看一个简单例子:
7
+ ` urllib ` 模块用于读取来自网上(服务器上)的数据,比如不少人用Python做爬虫程序,就可以使用这个模块。先看一个简单例子:
8
+
9
+ 在Python 2中,这样操作:
8
10
9
11
>>> import urllib
10
12
>>> itdiffer = urllib.urlopen("http://www.itdiffer.com")
11
13
12
- 这样就已经把我的网站[ www.itdiffer.com ] ( http://www.itdiffer.com ) 首页的内容拿过来了,得到了一个类似文件的对象。接下来的操作跟操作一个文件一样(如果忘记了文件怎么操作,可以参考:[ 《文件(1)] ( ./126.md ) )
14
+ 但是如果读者使用的是Python 3,必须换个姿势:
15
+
16
+ >>> import urllib.request
17
+ >>> itdiffer = urllib.request.urlopen("http://www.itdiffer.com")
18
+
19
+ 这样就已经把我的网站[ www.itdiffer.com ] ( http://www.itdiffer.com ) 首页的内容拿过来了,得到了一个类似文件的对象。接下来的操作跟操作一个文件一样。
13
20
14
- >>> print itdiffer.read()
21
+ >>> print itdiffer.read() #Python 3: print(itdiffer.read())
15
22
<!DOCTYPE HTML>
16
23
<html>
17
24
<head>
18
25
<title>I am Qiwsir</title>
19
26
....//因为内容太多,下面就省略了
20
27
21
- 就这么简单,完成了对一个网页的抓取。当然,如果你真的要做爬虫程序,还不是仅仅如此。这里不介绍爬虫程序如何编写,仅说明urllib模块的常用属性和方法。
28
+ 这样就完成了对网页的抓取。当然,如果你真的要做爬虫程序,还不是仅仅如此。这里不介绍爬虫程序如何编写,仅说明` urllib ` 模块的常用属性和方法。
29
+
30
+ Python 2:
22
31
23
32
>>> dir(urllib)
24
33
['ContentTooShortError', 'FancyURLopener', 'MAXFTPCACHE', 'URLopener', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__version__', '_asciire', '_ftperrors', '_have_ssl', '_hexdig', '_hextochr', '_hostprog', '_is_unicode', '_localhost', '_noheaders', '_nportprog', '_passwdprog', '_portprog', '_queryprog', '_safe_map', '_safe_quoters', '_tagprog', '_thishost', '_typeprog', '_urlopener', '_userprog', '_valueprog', 'addbase', 'addclosehook', 'addinfo', 'addinfourl', 'always_safe', 'base64', 'basejoin', 'c', 'ftpcache', 'ftperrors', 'ftpwrapper', 'getproxies', 'getproxies_environment', 'i', 'localhost', 'noheaders', 'os', 'pathname2url', 'proxy_bypass', 'proxy_bypass_environment', 'quote', 'quote_plus', 're', 'reporthook', 'socket', 'splitattr', 'splithost', 'splitnport', 'splitpasswd', 'splitport', 'splitquery', 'splittag', 'splittype', 'splituser', 'splitvalue', 'ssl', 'string', 'sys', 'test1', 'thishost', 'time', 'toBytes', 'unquote', 'unquote_plus', 'unwrap', 'url2pathname', 'urlcleanup', 'urlencode', 'urlopen', 'urlretrieve']
25
34
26
- 选几个常用的介绍,其它的如果读者用到,可以通过查看文档了解。
35
+ Python 3:
36
+
37
+ >>> dir(urllib.request)
38
+ ['AbstractBasicAuthHandler', 'AbstractDigestAuthHandler', 'AbstractHTTPHandler', 'BaseHandler', 'CacheFTPHandler', 'ContentTooShortError', 'DataHandler', 'FTPHandler', 'FancyURLopener', 'FileHandler', 'HTTPBasicAuthHandler', 'HTTPCookieProcessor', 'HTTPDefaultErrorHandler', 'HTTPDigestAuthHandler', 'HTTPError', 'HTTPErrorProcessor', 'HTTPHandler', 'HTTPPasswordMgr', 'HTTPPasswordMgrWithDefaultRealm', 'HTTPPasswordMgrWithPriorAuth', 'HTTPRedirectHandler', 'HTTPSHandler', 'MAXFTPCACHE', 'OpenerDirector', 'ProxyBasicAuthHandler', 'ProxyDigestAuthHandler', 'ProxyHandler', 'Request', 'URLError', 'URLopener', 'UnknownHandler', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__version__', '_cut_port_re', '_ftperrors', '_have_ssl', '_localhost', '_noheaders', '_opener', '_parse_proxy', '_proxy_bypass_macosx_sysconf', '_randombytes', '_safe_gethostbyname', '_thishost', '_url_tempfiles', 'addclosehook', 'addinfourl', 'base64', 'bisect', 'build_opener', 'collections', 'contextlib', 'email', 'ftpcache', 'ftperrors', 'ftpwrapper', 'getproxies', 'getproxies_environment', 'getproxies_registry', 'hashlib', 'http', 'install_opener', 'io', 'localhost', 'noheaders', 'os', 'parse_http_list', 'parse_keqv_list', 'pathname2url', 'posixpath', 'proxy_bypass', 'proxy_bypass_environment', 'proxy_bypass_registry', 'quote', 're', 'request_host', 'socket', 'splitattr', 'splithost', 'splitpasswd', 'splitport', 'splitquery', 'splittag', 'splittype', 'splituser', 'splitvalue', 'ssl', 'sys', 'tempfile', 'thishost', 'time', 'to_bytes', 'unquote', 'unquote_to_bytes', 'unwrap', 'url2pathname', 'urlcleanup', 'urljoin', 'urlopen', 'urlparse', 'urlretrieve', 'urlsplit', 'urlunparse', 'warnings']
39
+
40
+ 选几个常用的介绍,如果读者用到其它的,可以通过查看文档了解。
27
41
28
42
** urlopen()**
29
43
30
- urlopen()主要用于打开url文件,然后就获得指定url的数据,接下来就如同在本地操作文件那样来操作 。
44
+ ` urlopen() ` 主要用于打开url文件,然后就获得指定url的数据,然后就如同在操作文件那样来操作 。
31
45
32
- > Help on function urlopen in module urllib:
46
+ Help on function urlopen in module urllib:
33
47
34
- > urlopen(url, data=None, proxies=None)
35
- > Create a file-like object for the specified URL to read from.
48
+ urlopen(url, data=None, proxies=None)
49
+ Create a file-like object for the specified URL to read from.
36
50
51
+ 查看文档信息,在Python 2下使用` help(urllib.urlopen) ` ,在Python 3下使用` help(urllib.request.urlopen) ` 。两者查询结果略有差异,上述显示的是Python 2下的查询结果。
52
+
37
53
得到的对象被叫做类文件。从名字中也可以理解后面的操作了。先对参数说明一下:
38
54
39
55
- url:远程数据的路径,常常是网址
40
56
- data:如果使用post方式,这里就是所提交的数据
41
57
- proxies:设置代理
42
58
43
- 关于参数的详细说明,还可以参考[ python的官方文档] ( https://docs.python.org/2/library/urllib.html ) ,这里仅演示最常用的,如前面的例子那样。
44
-
45
- 当得到了类文件对象之后,就可以对它进行操作。变量itdiffer引用了得到的类文件对象,通过它查看:
46
-
47
- >>> dir(itdiffer)
48
- ['__doc__', '__init__', '__iter__', '__module__', '__repr__', 'close', 'code', 'fileno', 'fp', 'getcode', 'geturl', 'headers', 'info', 'next', 'read', 'readline', 'readlines', 'url']
49
-
50
- 读者从这个结果中也可以看出,这个类文件对象也是可迭代的。常用的方法:
59
+ 关于参数的详细说明,还可以参考[ Python的官方文档] ( https://docs.python.org/2/library/urllib.html ) ,这里仅演示最常用的,如前面的例子那样。
51
60
52
- - read(),readline(),readlines(),fileno(),close():都与文件操作一样,这里不再赘述。可以参考前面有关文件章节
53
- - info():返回头信息
54
- - getcode():返回http状态码
55
- - geturl():返回url
61
+ 当得到了类文件对象之后,即变量` itdiffer ` 引用了得到的类文件对象,依然可以用老办法` dir(itdiffer) ` 查看它的属性和方法,但在不同的Python版本下,显示结果是有所不同的,区别的原因是两个版本对文件对象的不同处理。
56
62
57
63
简单举例:
58
64
@@ -67,7 +73,7 @@ urlopen()主要用于打开url文件,然后就获得指定url的数据,接
67
73
68
74
** 对url编码、解码**
69
75
70
- url对其中的字符有严格要求,不许可某些特殊字符,这就要对url进行编码和解码了。这个在进行web开发的时候特别要注意。urllib模块提供这种功能 。
76
+ url对其中的字符有严格的编码要求,要对url进行编码和解码。在进行web开发的时候特别要注意。 ` urllib ` 或者 ` urllib.request ` 模块提供这种功能 。
71
77
72
78
- quote(string[ , safe] ):对字符串进行编码。参数safe指定了不需要编码的字符
73
79
- urllib.unquote(string) :对字符串进行解码
@@ -77,14 +83,23 @@ url对其中的字符有严格要求,不许可某些特殊字符,这就要
77
83
- pathname2url(path):将本地路径转换成url路径
78
84
- url2pathname(path):将url路径转换成本地路径
79
85
80
- 看例子就更明白了:
86
+ 看例子就更明白了。下面的操作是在Python 2中进行的,
81
87
82
88
>>> du = "http://www.itdiffer.com/name=python book"
83
- >>> urllib.quote(du)
89
+ >>> urllib.quote(du)
84
90
'http%3A//www.itdiffer.com/name%3Dpython%20book'
85
91
>>> urllib.quote_plus(du)
86
92
'http%3A%2F%2Fwww.itdiffer.com%2Fname%3Dpython+book'
87
93
94
+ 如果是Python 3的读者,请注意,该方法不在前述所引用的` urllib.request ` 中,尽管它里面有` quote() ` 方法,但最好的操作是` import urllib.parrse ` ,所以,Python 3下应该这么操作:
95
+
96
+ >>> import urllib.parse
97
+ >>> du = 'http://www.itdiffer.com/name=python book'
98
+ >>> urllib.parse.quote(du)
99
+ 'http%3A//www.itdiffer.com/name%3Dpython%20book'
100
+ >>> urllib.parse.quote_plus(du)
101
+ 'http%3A%2F%2Fwww.itdiffer.com%2Fname%3Dpython+book'
102
+
88
103
注意看空格的变化,一个被编码成` %20 ` ,另外一个是` + `
89
104
90
105
再看解码的,假如在google中搜索` 零基础 python ` ,结果如下图:
@@ -95,29 +110,51 @@ url对其中的字符有严格要求,不许可某些特殊字符,这就要
95
110
96
111
这不是重点,重点是看url,它就是用` + ` 替代空格了。
97
112
113
+ Python 2:
114
+
98
115
>>> dup = urllib.quote_plus(du)
99
116
>>> urllib.unquote_plus(dup)
100
117
'http://www.itdiffer.com/name=python book'
101
118
119
+ Python 3:
120
+
121
+ >>> dup = urllib.parse.quote_plus(du)
122
+ >>> urllib.parse.unquote_plus(dup)
123
+ 'http://www.itdiffer.com/name=python book'
124
+
102
125
从解码效果来看,比较完美地逆过程。
103
126
127
+ Python 2:
128
+
104
129
>>> urllib.urlencode({"name":"qiwsir","web":"itdiffer.com"})
105
130
'web=itdiffer.com&name=qiwsir'
106
131
107
- 这个在编程中,也会用到,特别是开发网站时候。
132
+ Python 3:
133
+
134
+ >>> urllib.parse.urlencode({"name":"qiwsir","web":"itdiffer.com"})
135
+ 'name=qiwsir&web=itdiffer.com'
136
+
137
+ 如果将来你要做一个网站,上面的方法或许会用到。
108
138
109
139
** urlretrieve()**
110
140
111
- 虽然urlopen()能够建立类文件对象,但是,那还不等于将远程文件保存在本地存储器中,urlretrieve()就是满足这个需要的。先看实例:
141
+ 虽然urlopen()能够建立类文件对象,但是,那还不等于将远程文件保存在本地存储器中,` urlretrieve() ` 就是满足这个需要的。先看实例。
142
+
143
+ 以下是在Python 2中的操作:
112
144
113
145
>>> import urllib
114
- >>> urllib.urlretrieve("http://www.itdiffer.com/images/me.jpg","me.jpg")
146
+ >>> urllib.urlretrieve("http://www.itdiffer.com/images/me.jpg", "me.jpg")
115
147
('me.jpg', <httplib.HTTPMessage instance at 0xb6ecb6cc>)
116
- >>>
117
148
118
- me.jpg是一张存在于服务器上的图片,地址是:http://www.itdiffer.com/images/me.jpg,把它保存到本地存储器中,并且仍旧命名为me.jpg。注意,如果只写这个名字,表示存在启动python交互模式的那个目录中,否则,可以指定存储具体目录和文件名。
149
+ 如果在Python 3中,则要使用` urllib.request ` :
150
+
151
+ >>> import urllib.request
152
+ >>> urllib.request.urlretrieve("http://www.itdiffer.com/images/me.jpg", "me.jpg")
153
+ ('me.jpg', <http.client.HTTPMessage object at 0x000000000395A160>)
119
154
120
- 在[ urllib官方文档] ( https://docs.python.org/2/library/urllib.html ) 中有一大段相关说明,读者可以去认真阅读。这里仅简要介绍一下相关参数。
155
+ ` me.jpg ` 是一张存在于服务器上的图片,地址是:http://www.itdiffer.com/images/me.jpg,把它保存到本地存储器中,并且仍旧命名为me.jpg。注意,如果只写这个名字,表示存在启动Python交互模式的那个目录中,否则,可以指定存储具体目录和文件名。
156
+
157
+ 在urllib官方文档([ Python 2文档] ( https://docs.python.org/2/library/urllib.html ) ,[ Python 3文档] ( https://docs.python.org/3/library/urllib.html ) )中有一大段相关说明,读者可以去认真阅读。这里仅简要介绍一下相关参数。
121
158
122
159
` urllib.urlretrieve(url[, filename[, reporthook[, data]]]) `
123
160
@@ -132,18 +169,22 @@ me.jpg是一张存在于服务器上的图片,地址是:http://www.itdiffer.
132
169
# coding=utf-8
133
170
134
171
import urllib
172
+ #Python 3
173
+ #import urllib.request
135
174
136
175
def go(a,b,c):
137
176
per = 100.0 * a * b / c
138
177
if per > 100:
139
178
per = 100
140
179
print "%.2f%%" % per
141
180
142
- url = "http://youxi.66wz.com/uploads/1046/1321/11410192.90d133701b06f0cc2826c3e5ac34c620 .jpg"
181
+ url = "http://ww2.sinaimg.cn/mw690/8e4023f8gw1f34gs20b4ij20qo0zkthw .jpg"
143
182
local = "/home/qw/Pictures/g.jpg"
144
183
urllib.urlretrieve(url, local, go)
184
+ #Python 3
185
+ #urllib.request.urlrretrieve(url, local, go)
145
186
146
- 这段程序就是要下载指定的图片,并且保存为本地指定位置的文件,同时要显示下载的进度。上述文件保存之后,执行 ,显示如下效果:
187
+ 这段程序就是要下载指定的图片,并且保存为本地指定位置的文件,同时要显示下载的进度。上述文件保存之后执行 ,显示如下效果:
147
188
148
189
$ python 22501.py
149
190
0.00%
@@ -161,7 +202,7 @@ me.jpg是一张存在于服务器上的图片,地址是:http://www.itdiffer.
161
202
97.59%
162
203
100.00%
163
204
164
- 到相应目录中查看,能看到与网上地址一样的文件。我这里就不对结果截图了,唯恐少部分读者鼻子流血 。
205
+ 到相应目录中查看,能看到与网上地址一样的文件。我这里就不对结果截图了,读者自行查看(或许在本书出版的时候,这张什么的图片已经看不到了,你应该把这视为正常现象,可以换一张图片地址) 。
165
206
166
207
##urllib2
167
208
@@ -178,39 +219,69 @@ urllib2是另外一个模块,它跟urllib有相似的地方——都是对url
178
219
>>> dir(urllib2)
179
220
['AbstractBasicAuthHandler', 'AbstractDigestAuthHandler', 'AbstractHTTPHandler', 'BaseHandler', 'CacheFTPHandler', 'FTPHandler', 'FileHandler', 'HTTPBasicAuthHandler', 'HTTPCookieProcessor', 'HTTPDefaultErrorHandler', 'HTTPDigestAuthHandler', 'HTTPError', 'HTTPErrorProcessor', 'HTTPHandler', 'HTTPPasswordMgr', 'HTTPPasswordMgrWithDefaultRealm', 'HTTPRedirectHandler', 'HTTPSHandler', 'OpenerDirector', 'ProxyBasicAuthHandler', 'ProxyDigestAuthHandler', 'ProxyHandler', 'Request', 'StringIO', 'URLError', 'UnknownHandler', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__version__', '_cut_port_re', '_opener', '_parse_proxy', '_safe_gethostbyname', 'addinfourl', 'base64', 'bisect', 'build_opener', 'ftpwrapper', 'getproxies', 'hashlib', 'httplib', 'install_opener', 'localhost', 'mimetools', 'os', 'parse_http_list', 'parse_keqv_list', 'posixpath', 'proxy_bypass', 'quote', 'random', 'randombytes', 're', 'request_host', 'socket', 'splitattr', 'splithost', 'splitpasswd', 'splitport', 'splittag', 'splittype', 'splituser', 'splitvalue', 'sys', 'time', 'toBytes', 'unquote', 'unwrap', 'url2pathname', 'urlopen', 'urlparse', 'warnings']
180
221
181
- 比较常用的比如urlopen()跟urllib.open()是完全类似的。
222
+ 比较常用的比如` urlopen() ` 跟` urllib.open() ` 是完全类似的。
223
+
224
+ 但是,要注意,上述言论仅仅是针对Python 2的,在Python 3中,已经没有` urllib2 ` 这个模块了,取代它的是` urllib.request ` 。
182
225
183
226
** Request类**
184
227
185
228
正如前面区别urllib和urllib2所讲,利用urllib2模块可以建立一个Request对象。方法就是:
186
229
230
+ Python 2:
231
+
187
232
>>> req = urllib2.Request("http://www.itdiffer.com")
188
233
189
- 建立了Request对象之后,它的最直接应用就是可以作为urlopen()方法的参数
234
+ Python 3:
235
+
236
+ >>> import urllib.request
237
+ >>> req = urllib.request.Request("http://www.itdiffer.com")
238
+
239
+ 建立了Request对象之后,它的最直接应用就是可以作为` urlopen() ` 方法的参数
240
+
241
+ Python 2:
190
242
191
243
>>> response = urllib2.urlopen(req)
192
244
>>> page = response.read()
193
245
>>> print page
194
246
195
- 因为与前面的` urllib.open("http://www.itdiffer.com") ` 结果一样,就不浪费篇幅了。
247
+ Python 3:
248
+
249
+ >>> response = urllib.request.urlopen(req)
250
+ >>> page = response.read()
251
+ >>> print(page)
252
+
253
+ 显示结果从略。但是,如果Request对象仅仅局限于此,似乎还没有什么太大的优势。因为刚才的访问仅仅是满足以get方式请求页面,并建立类文件对象。如果是通过post向某地址提交数据,也可以建立Request对象。
196
254
197
- 但是,如果Request对象仅仅局限于此,似乎还没有什么太大的优势。因为刚才的访问仅仅是满足以get方式请求页面,并建立类文件对象。如果是通过post向某地址提交数据,也可以建立Request对象。
255
+ Python 2:
198
256
199
257
import urllib
200
258
import urllib2
201
259
202
260
url = 'http://www.itdiffer.com/register.py'
203
261
204
- values = {'name' : 'qiwsir',
205
- 'location' : 'China',
206
- 'language' : 'Python' }
262
+ values = {'name' : 'qiwsir', 'location' : 'China', 'language' : 'Python' }
207
263
208
264
data = urllib.urlencode(values) # 编码
209
265
req = urllib2.Request(url, data) # 发送请求同时传data表单
210
266
response = urllib2.urlopen(req) #接受反馈的信息
211
267
the_page = response.read() #读取反馈的内容
212
268
213
- 注意,读者不能照抄上面的程序,然后运行代码。因为那个url中没有相应的接受客户端post上去的data的程序文件。上面的代码只是以一个例子来显示Request对象的另外一个用途,还有就是在这个例子中是以post方式提交数据。
269
+ Python 3:
270
+
271
+
272
+ import urllib.request
273
+ import urllib.parse
274
+
275
+ url = 'http://www.itdiffer.com/register.py'
276
+
277
+ values = {'name' : 'qiwsir', 'location' : 'China', 'language' : 'Python' }
278
+
279
+ data = urllib.parse.urlencode(values) # 编码
280
+ req = urllib.request.Request(url, data) # 发送请求同时传data表单
281
+ response = urllib.request.urlopen(req) #接受反馈的信息
282
+ the_page = response.read() #读取反馈的内容
283
+
284
+ 如果读者照抄上面的程序,然后运行代码,肯定报错。因为那个url中没有相应的接受客户端post上去的data的程序文件,为了让程序运行,读者可以开发接受数据的程序。上面的代码只是以一个例子来显示Request对象的另外一个用途,并且在这个例子中是以post方式提交数据。
214
285
215
286
在网站中,有的会通过User-Agent来判断访问者是浏览器还是别的程序,如果通过别的程序访问,它有可能拒绝。这时候,我们编写程序去访问,就要设置headers了。设置方法是:
216
287
@@ -219,13 +290,13 @@ urllib2是另外一个模块,它跟urllib有相似的地方——都是对url
219
290
220
291
然后重新建立Request对象:
221
292
222
- req = urllib2.Request(url, data, headers)
293
+ req = urllib2.Request(url, data, headers) #Python 3: req = urllib.request.Request(url, data, headers)
223
294
224
- 再用urlopen() 方法访问:
295
+ 再用·urlopen()· 方法访问:
225
296
226
- response = urllib2.urlopen(req)
297
+ response = urllib2.urlopen(req) #Python 3: response = urllib.request.urlopen(req)
227
298
228
- 除了上面演示之外,urllib2模块的东西还很多 ,比如还可以:
299
+ 除了上面演示之外,` urllib2 ` 或者 ` urllib.request ` 的东西还很多 ,比如还可以:
229
300
230
301
- 设置HTTP Proxy
231
302
- 设置Timeout值
0 commit comments