~justin-fathomdb/nova/justinsb-openstack-api-volumes

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/doc/historic/2003/europython/webclients.html

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<html><head><title>Writing Web Clients</title></head><body>
 
2
 
 
3
<h1>Writing Web Clients</h1>
 
4
 
 
5
<h2>Web Clients -- The Tutorial</h2><ul>
 
6
<li>Welcome</li>
 
7
 
 
8
<li>Gimmick -- Buffy quotes</li>
 
9
 
 
10
</ul>
 
11
<hr />
 
12
<em>Anya (Family, season 5) -- Thank you for coming. We value your patronage.</em>
 
13
<h2>What Are Web Clients?</h2><ul>
 
14
<li>Clarification: non-interactive web clients</li>
 
15
 
 
16
<li>Special purpose</li>
 
17
 
 
18
<li>Often, quick and dirty hacks</li>
 
19
 
 
20
<li>Make a web page into API</li>
 
21
 
 
22
</ul>
 
23
<hr />
 
24
<em>Giles (Family, season 5) -- Could we please be a little less effusive, Anya?</em>
 
25
<h2>What Are Web Clients Useful For?</h2><ul>
 
26
<li>Mass download</li>
 
27
 
 
28
<li>Periodic checking</li>
 
29
 
 
30
<li>Automating tasks<ul><li>Make a web page more friendly</li>
 
31
</ul></li>
 
32
 
 
33
</ul>
 
34
<hr />
 
35
<em>Harmony (Family, season 5) -- Aww. You're my little lamb.</em>
 
36
<h2>Review of Modules</h2><ul>
 
37
<li>htmllib</li>
 
38
 
 
39
<li>sgmllib</li>
 
40
 
 
41
<li>httplib</li>
 
42
 
 
43
<li>urllib</li>
 
44
 
 
45
<li>urllib2</li>
 
46
 
 
47
<li>urlparse</li>
 
48
 
 
49
</ul>
 
50
<hr />
 
51
<em>Buffy (Family, season 5) -- Your definition of narrow is impressively wide.</em>
 
52
<h2>Modules -- htmllib</h2><ul>
 
53
<li>Most useful for easy filtering of images</li>
 
54
 
 
55
<li>...or links</li>
 
56
 
 
57
<li>Other things often easier with sgmllib</li>
 
58
 
 
59
<li>Or with re</li>
 
60
 
 
61
<li>Or with string manipulation</li>
 
62
 
 
63
</ul>
 
64
<hr />
 
65
<em>Xander (Family, season 5) -- The answer is somewhere here.</em>
 
66
<h2>Modules -- htmllib -- idiomatic usage</h2>
 
67
<pre>
 
68
# For lists
 
69
import htmllib, formatter
 
70
 
 
71
h = htmllib.HTMLParser(formatter.NullFormatter())
 
72
h.feed(htmlString)
 
73
print h.anchorlist
 
74
</pre>
 
75
 
 
76
<hr />
 
77
<em>Xander (Family, season 5) -- I'm helping, I'm reading, I'm quiet.</em>
 
78
<h2>Modules -- htmllib -- idiotmatic usage (cont'd)</h2>
 
79
<pre>
 
80
import htmllib, formatter
 
81
 
 
82
class IMGFinder(htmllib.HTMLParser):
 
83
 
 
84
    def __init__(self, *args, **kw):
 
85
        htmllib.HTMLParser.__init__(self, *args, **kw)
 
86
        self.ims = []
 
87
 
 
88
    def handle_image(self, src, *args): self.ims.append(src)
 
89
 
 
90
h = IMGFinder(formatter.NullFormatter())
 
91
h.feed(htmlString)
 
92
print h.ims
 
93
</pre>
 
94
 
 
95
<hr />
 
96
<em>Donny (Family, season 5) -- Look what I found!</em>
 
97
<h2>Modules -- htmllib -- base</h2><ul>
 
98
<li>Some sites use 'base' for different relative linking</li>
 
99
 
 
100
<li>For example, Zope does</li>
 
101
 
 
102
<li>In above examples, 'h.base' has the base</li>
 
103
 
 
104
</ul>
 
105
<hr />
 
106
<em>Dawn (Family, season 5) -- This is the source of my gladness.</em>
 
107
<h2>Modules -- htmllib -- base (example)</h2><ul>
 
108
<li>If the page on http://example.com/foo/bar.html has a link to '../baz.html'<ul><li>It means http://example.com/baz.html</li>
 
109
</ul></li>
 
110
 
 
111
<li>If the original page has base='/foo/quux'<ul><li>It means http://example.com/foo/baz.html</li>
 
112
</ul></li>
 
113
 
 
114
</ul>
 
115
<hr />
 
116
<em>Riley (Family, season 5) -- Every time I think I'm getting close to you...</em>
 
117
<h2>Modules -- urllib/urllib2</h2><ul>
 
118
<li>High-level interface</li>
 
119
 
 
120
<li>Treat URLs as file-like objects</li>
 
121
 
 
122
<li>...but still allows low-level operations</li>
 
123
 
 
124
<li>Interface largely compatible</li>
 
125
 
 
126
</ul>
 
127
<hr />
 
128
<em>Glory (Family, season 5) -- I am great and I am beautiful.</em>
 
129
<h2>Modules -- urllib/urllib2 (cont'd)</h2><ul>
 
130
<li>Can work through object-interface</li>
 
131
 
 
132
<li>More flexible</li>
 
133
 
 
134
<li>Interface no longer compatible</li>
 
135
 
 
136
<li>urllib2 better usually</li>
 
137
 
 
138
</ul>
 
139
<hr />
 
140
<em>Joyce (Ted, season 2) -- He redid my entire system.</em>
 
141
<h2>Modules -- urllib/urllib2 (examples)</h2><ul>
 
142
<li>urllib.urlopen("http://www.yahoo.com/").read() -&gt; contents</li>
 
143
 
 
144
<li>urllib.urlopen("http://www.yahoo.com/").info() -&gt; headers</li>
 
145
 
 
146
<li>Same works with urllib2</li>
 
147
 
 
148
<li>Automatically uses environment variables for proxies</li>
 
149
 
 
150
<li>urllib2 supports proxies with authentication</li>
 
151
 
 
152
</ul>
 
153
<hr />
 
154
<em>Xander (Ted, season 2) -- Yum-my!</em>
 
155
<h2>Digression -- HTTP Overview</h2><ul>
 
156
<li>Request/Response</li>
 
157
 
 
158
<li>Request is command followed by headers followed by body</li>
 
159
 
 
160
<li>Response is error code followed by headers followed by body</li>
 
161
 
 
162
<li>No welcome message</li>
 
163
 
 
164
</ul>
 
165
<hr />
 
166
<em>Tara (Family, season 5) -- ...in terms of the karmic cycle.</em>
 
167
<h2>Example HTTP Sessions</h2><ul>
 
168
<li>Client</li>
 
169
</ul>
 
170
 
 
171
<pre>
 
172
GET /foo/bar.html HTTP/1.0
 
173
Host: www.example.org
 
174
&lt;blank line&gt;
 
175
</pre>
 
176
 
 
177
<ul><li>Server</li></ul>
 
178
 
 
179
<pre>
 
180
HTTP/1.0 200 OK
 
181
Content-Type: text/html
 
182
 
 
183
&lt;html&gt;&lt;body&gt;lalalala&lt;/body&gt;&lt;/html&gt;
 
184
</pre>
 
185
 
 
186
<hr />
 
187
<em>Giles (Family, season 5) -- And you are talking about what on earth?</em>
 
188
<h2>Modules -- httplib</h2><ul>
 
189
<li>Low-level interface to innards of HTTP</li>
 
190
 
 
191
<li>Absolute control</li>
 
192
 
 
193
<li>No abstractions</li>
 
194
 
 
195
</ul>
 
196
<hr />
 
197
<em>Mr. MacLay (Family, season 5) -- We know how to control her...problem.</em>
 
198
<h2>Modules -- httplib -- example</h2><ul>
 
199
<li>Note: usually, the Host header is important<ul><li>Virtual hosting</li>
 
200
</ul></li></ul>
 
201
 
 
202
<pre>
 
203
&gt;&gt;&gt; import httplib
 
204
&gt;&gt;&gt; h=httplib.HTTP("moshez.org")
 
205
&gt;&gt;&gt; h.putrequest('GET', '/')
 
206
&gt;&gt;&gt; h.putheader('Host', 'moshez.org')
 
207
&gt;&gt;&gt; h.endheaders()
 
208
&gt;&gt;&gt; h.getreply()
 
209
(200, 'OK', &lt;mimetools.Message instance at 0x81220dc&gt;)
 
210
&gt;&gt;&gt; h.getfile().read(10)
 
211
"&lt;HTML&gt;\n&lt;HE"
 
212
</pre>
 
213
<hr />
 
214
<em>Anya (Family, season 5) -- ...and it was fun!</em>
 
215
<h2>Modules -- urlparse</h2><ul>
 
216
<li>urlparse.urljoin -- like os.path.join for URLs</li>
 
217
 
 
218
<li>For path manipulation<ul><li>urlparse.urlsplit</li>
 
219
 
 
220
<li>urlparse.urlunsplit</li>
 
221
</ul></li>
 
222
 
 
223
</ul>
 
224
<hr />
 
225
<em>Buffy (Family, season 5) -- You know what, you guys, just leave it here.</em>
 
226
<h2>Downloading Dilbert</h2>
 
227
<pre>
 
228
import urllib2, re
 
229
 
 
230
URL = 'http://www.dilbert.com/'
 
231
f = urllib2.urlopen(URL)
 
232
s = f.read()
 
233
href = re.compile('&lt;a href="(/comics/.*?/dilbert.*?gif)"&gt;')
 
234
m = href.search(value)
 
235
f = urllib2.urlretrieve(urlparse.urljoin(URL, m.group(1)),
 
236
                        "dilbert.gif")
 
237
</pre>
 
238
<hr />
 
239
<em>Tara (Family, season 5) -- That was funny if you [...] are a complete dork.</em>
 
240
<h2>Downloading Dark Angel Transcripts</h2><ul>
 
241
<li>Common situation of mass download</li></ul>
 
242
 
 
243
<pre>
 
244
import urllib2, htmllib, formatter, posixpath
 
245
URL="http://www.darkangelfan.com/episode/"
 
246
LINK_RE = re.compile('/trans_[0-9]+\.shtml$')
 
247
s = urllib2.urlopen(URL).read()
 
248
h = htmllib.HTMLParser(formatter.NullFormatter())
 
249
h.feed(s)
 
250
links = [urlparse.urljoin(URL, link)
 
251
              for link in h.anchorlist if LINK_RE.search(link)]
 
252
### -- really download --
 
253
for link in links:
 
254
    urllib2.urlretrieve(link, posixpath.basename(link))
 
255
</pre>
 
256
 
 
257
<hr />
 
258
<em>Intern (Family, season 5) -- Yeah. That makes like five this month.</em>
 
259
<h2>Downloading Dark Angel Transcripts (select)</h2>
 
260
 
 
261
<pre>
 
262
class Downloader:
 
263
 
 
264
    def __init__(self, fin, fout):
 
265
        self.fin, self.fout, self.fileno = fin, fout, fin.fileno
 
266
 
 
267
    def read(self):
 
268
        buf = self.fin.read(4096)
 
269
        if not buf:
 
270
            for f in [self.fout, self.fin]: f.close()
 
271
            return 1
 
272
        self.fout.write(buf)
 
273
</pre>
 
274
<hr />
 
275
<em>Joyce (Ted, season 2) -- I've been looking for the right moment.</em>
 
276
<h2>Downloading Dark Angel Transcripts (select, cont'd)</h2><ul>
 
277
<li>Same code up to 'really download'</li></ul>
 
278
 
 
279
<pre>
 
280
downloaders = [Downloader(urllib2.urlopen(link),
 
281
                 open(posixpath.basename(link), 'wb'))
 
282
                                      for link in links]
 
283
while downloaders:
 
284
    toRead = select.select(None, [downloaders], [], [])
 
285
    for downloader in toRead:
 
286
         if downloader.read():
 
287
             downloaders.remove(downloader)
 
288
</pre>
 
289
<hr />
 
290
<em>Buffy (Family, season 5) -- Tara's damn birthday is just one too many things for me to worry about.</em>
 
291
<h2>Downloading Dark Angel Transcripts (threads)</h2><ul>
 
292
<li>Bare bones example</li></ul>
 
293
 
 
294
<pre>
 
295
import threading
 
296
 
 
297
for link in links:
 
298
    Thread(target=urllib2.urlretrieve,
 
299
           args=(link,posixpath.basename(link)))
 
300
</pre>
 
301
<hr />
 
302
<em>Buffy (Ted, season 2) -- Sounds like fun.</em>
 
303
<h2>Digression - twisted.web.client</h2><ul>
 
304
<li>Part of the Twisted networking framework</li>
 
305
 
 
306
<li>High level interface to HTTP client</li>
 
307
 
 
308
<li>Completely asynchronous</li>
 
309
 
 
310
<li>Reports results via callbacks</li>
 
311
 
 
312
<li>client.getpage("http://www.yahoo.com").addCallbacks(gotResult, gotError)</li>
 
313
 
 
314
</ul>
 
315
<hr />
 
316
<em>Buffy (Ted, season 2) -- You're supposed to use your powers for good!</em>
 
317
<h2>Downloading Dark Angel Transcripts (web.client)</h2>
 
318
<pre>
 
319
from twisted.web import client
 
320
from twisted.internet import import reactor, defer
 
321
 
 
322
defer.DeferredList(
 
323
[client.downloadPage(link, posixpath.basename(link))
 
324
            for link in links]).addBoth(lambda _: reactor.stop())
 
325
reactor.run()
 
326
</pre>
 
327
<hr />
 
328
<em>Ted (Ted, season 2) -- You don't have to worry about anything.</em>
 
329
<h2>HTTP Authentication</h2><ul>
 
330
<li>Client attempts to connect</li>
 
331
 
 
332
<li>Server sends back a 401 (please authenticate)</li>
 
333
 
 
334
<li>Client sends same request back -- with auth tokens</li>
 
335
 
 
336
<li>Only HTTP Basic authentication widely supported</li>
 
337
 
 
338
<li>Client can send auth tokens on more requests automatically</li>
 
339
 
 
340
</ul>
 
341
<hr />
 
342
<em>Buffy (Ted, season 2) -- Ummm... Who are these people?</em>
 
343
<h2>HTTP Authentication - manually</h2><ul>
 
344
<li>In HTTP, authentication is a header</li>
 
345
 
 
346
<li>Base authentication is sending username and password</li>
 
347
</ul>
 
348
<pre>
 
349
user = 'moshez'
 
350
password = 's3kr1t'
 
351
import httplib
 
352
h=httplib.HTTP("localhost")
 
353
h.putrequest('GET', '/protected/stuff.html')
 
354
h.putheader('Authorization',
 
355
            base64.encodestring(user+":"+password).strip())
 
356
h.endheaders()
 
357
h.getreply()
 
358
print h.getfile().read()
 
359
</pre>
 
360
<hr />
 
361
<em>Tara (Family, season 5) -- And, uh, these are my-my friends.</em>
 
362
<h2>HTTP Authentication - urllib2</h2><ul>
 
363
<li>Can read username/password from URL</li>
 
364
 
 
365
<li>urllib2.urlopen("http://moshez:s3krit@example.com"
 
366
                    "/protected/stuff.html")</li>
 
367
 
 
368
</ul>
 
369
<hr />
 
370
<em>Xander (Ted, season 2) -- I am really jinxing the hell out of us.</em>
 
371
<h2>Further Reading</h2><ul>
 
372
<li>htmllib docs <a href="http://www.python.org/doc/current/lib/module-htmllib.html">http://www.python.org/doc/current/lib/module-htmllib.html</a></li>
 
373
 
 
374
<li>sgmllib docs<a href="http://www.python.org/doc/current/lib/module-sgmllib.html">http://www.python.org/doc/current/lib/module-sgmllib.html</a></li>
 
375
 
 
376
<li>urllib docs<a href="http://www.python.org/doc/current/lib/module-urllib.html">http://www.python.org/doc/current/lib/module-urllib.html</a></li>
 
377
 
 
378
<li>urllib2 docs<a href="http://www.python.org/doc/current/lib/module-urllib2.html">http://www.python.org/doc/current/lib/module-urllib2.html</a></li>
 
379
 
 
380
<li>httplib docs<a href="http://www.python.org/doc/current/lib/module-httplib.html">http://www.python.org/doc/current/lib/module-httplib.html</a></li>
 
381
 
 
382
<li>re docs<a href="http://www.python.org/doc/current/lib/module-re.html">http://www.python.org/doc/current/lib/module-re.html</a></li>
 
383
 
 
384
<li>HTTP RFC<a href="http://www.w3.org/Protocols/rfc2616/rfc2616.html">http://www.w3.org/Protocols/rfc2616/rfc2616.html</a></li>
 
385
 
 
386
<li>W3C HTML Page<a href="http://www.w3.org/MarkUp/">http://www.w3.org/MarkUp/</a></li>
 
387
 
 
388
<li>Twisted<a href="http://twistedmatrix.com">http://twistedmatrix.com</a></li>
 
389
 
 
390
</ul>
 
391
<hr />
 
392
<em>Willow (Ted, season 2) -- 'Book-cracker Buffy', it's kind of her nickname.</em>
 
393
<h2>Questions?</h2>
 
394
<em>Buffy (Family, season 5) -- I let you come, now sit down and look studious.</em>
 
395
<h2>Bonus Slides</h2>
 
396
<em>Tara (Family, season 5) -- You always make me feel special.</em>
 
397
 
 
398
<h2>Cookies</h2><ul>
 
399
<li>Carry state from one page to another</li>
 
400
 
 
401
<li>Server sends header: Set-Cookie</li>
 
402
 
 
403
<li>Client sends on later requests header: Cookie</li>
 
404
 
 
405
</ul>
 
406
<hr />
 
407
<em>Ted (Ted, season 2) -- Who's up for dessert? I made chocolate-chip cookies!</em>
 
408
<h2>urllib2 cookies</h2><ul>
 
409
<li>Unfortunately, no automatic cookie jar support</li>
 
410
 
 
411
<li>Can manually use .info() to read cookies...</li>
 
412
 
 
413
<li>...and the Request() API to send them to the server</li>
 
414
 
 
415
</ul>
 
416
<hr />
 
417
<em>Joyce (Ted, season 2) -- Mm! Buffy, you've got to try one of these!</em>
 
418
<h2>Logging Into Advogato</h2>
 
419
<pre>
 
420
 
 
421
import urllib2
 
422
 
 
423
u = urllib2.urlopen("http://advogato.org/acct/loginsub.html",
 
424
                    urllib2.urlencode({'u': 'moshez',
 
425
                                       'pass': 'not my real pass'})
 
426
cookie = u.info()['set-cookie']
 
427
cookie = cookie[:cookie.find(';')]
 
428
r = Request('http://advogato.org/diary/post.html',
 
429
            urllib2.urlencode(
 
430
            {'entry': open('entry').read(), 'post': 'Post'}),
 
431
            {'Cookie': cookie})
 
432
urllib2.urlopen(r).read()
 
433
</pre>
 
434
 
 
435
<hr />
 
436
<em>Anya (Family, season 5) -- I have a place in the world now.</em>
 
437
<h2>On Being Nice - Robots</h2><ul>
 
438
<li>Some sites don't want automatic crawlers</li>
 
439
 
 
440
<li>It is up to you whether to play nice</li>
 
441
 
 
442
<li>But you should know the rules before you break them</li>
 
443
 
 
444
<li>Robots file -- at /robots.txt</li>
 
445
 
 
446
</ul>
 
447
<hr />
 
448
<em>Willow (Ted, season 2) -- There were design features in that robot that pre-date...</em>
 
449
<h2>Using robotparser</h2>
 
450
<pre>
 
451
import robotparser
 
452
rp = robotparser.RobotFileParser()
 
453
rp.set_url('http://www.example.com/robots.txt')
 
454
rp.read()
 
455
if not rp.can_fetch('', 'http://www.example.com/'):
 
456
    sys.exit(1)
 
457
</pre>
 
458
 
 
459
<hr />
 
460
<em>Buffy (Ted, season 2) -- Tell me you didn't keep any parts.</em>
 
461
<h2>webchecker</h2><ul>
 
462
<li>In the source distribution, in Tools/</li>
 
463
 
 
464
<li>Understands robots.txt</li>
 
465
 
 
466
<li>Can override which links gets chased</li>
 
467
 
 
468
</ul>
 
469
<hr />
 
470
<em>Willow (Ted, season 2) -- What do you mean, check him out?</em>
 
471
<h2>websucker</h2><ul>
 
472
<li>In the source distribution, in Tools/</li>
 
473
 
 
474
<li>Uses webchecker as a module</li>
 
475
 
 
476
<li>Saves the pages it downloads</li>
 
477
 
 
478
</ul>
 
479
<hr />
 
480
<em>Buffy (Ted, season 2) -- Find out his secrets, hack into his life.</em>
 
481
 
 
482
</body></html>