-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathPython实战中阶(一)——爬取网页的一点分享 | 文杰的博客,good·je.html
522 lines (494 loc) · 44.3 KB
/
Python实战中阶(一)——爬取网页的一点分享 | 文杰的博客,good·je.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Python实战中阶(一)——爬取网页的一点分享 | 文杰的博客,good·je</title>
<link rel='stylesheet' href="//blog.goodje.com/wp-content/themes/color/style.css?20120822" type='text/css' media='screen' />
<link rel="pingback" href="http://blog.goodje.com/xmlrpc.php" /> <script>
function convertEntities(b){var d,a;d=function(c){if(/&[^;]+;/.test(c)){var f=document.createElement("div");f.innerHTML=c;return !f.firstChild?c:f.firstChild.nodeValue}return c};if(typeof b==="string"){return d(b)}else{if(typeof b==="object"){for(a in b){if(typeof b[a]==="string"){b[a]=d(b[a])}}}}return b};
</script>
<link rel="alternate" type="application/rss+xml" title="文杰的博客,good·je » Python实战中阶(一)——爬取网页的一点分享评论Feed" href="http://blog.goodje.com/2012-08/python-middle-action-web-crawler.html/feed" />
<link rel='stylesheet' id='fontawesome-css' href='http://blog.goodje.com/wp-content/plugins/nextgen-gallery/products/photocrati_nextgen/modules/nextgen_gallery_display/static/fontawesome/font-awesome.css?ver=3.8.5' type='text/css' media='all' />
<script type='text/javascript' src='http://blog.goodje.com/wp-includes/js/jquery/jquery.js?ver=1.10.2'></script>
<script type='text/javascript' src='http://blog.goodje.com/wp-includes/js/jquery/jquery-migrate.min.js?ver=1.2.1'></script>
<script type='text/javascript' src='http://blog.goodje.com/wp-includes/js/comment-reply.min.js?ver=3.8.5'></script>
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://blog.goodje.com/xmlrpc.php?rsd" />
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://blog.goodje.com/wp-includes/wlwmanifest.xml" />
<link rel='prev' title='主动分享' href='http://blog.goodje.com/2012-08/zhudongfenxiang.html' />
<link rel='next' title='他的中国观' href='http://blog.goodje.com/2012-08/his-world.html' />
<link rel='shortlink' href='http://blog.goodje.com/?p=1374' />
<!-- <meta name="NextGEN" version="2.0.59" /> -->
<script type="text/javascript">
window._wp_rp_static_base_url = 'http://wprp.zemanta.com/static/';
window._wp_rp_wp_ajax_url = "http://blog.goodje.com/wp-admin/admin-ajax.php";
window._wp_rp_plugin_version = '3.3.3';
window._wp_rp_post_id = '1374';
window._wp_rp_num_rel_posts = '6';
</script>
<style type="text/css">
.wp-polls .pollbar {
margin: 1px;
font-size: 8px;
line-height: 10px;
height: 10px;
background-image: url('http://blog.goodje.com/wp-content/plugins/wp-polls/images/default_gradient/pollbg.gif');
border: 1px solid #c8c8c8;
}
</style>
<link id='MediaRSS' rel='alternate' type='application/rss+xml' title='NextGEN Gallery RSS Feed' href='http://blog.goodje.com/wp-content/plugins/nextgen-gallery/products/photocrati_nextgen/modules/ngglegacy/xml/media-rss.php' />
<!-- All in One SEO Pack 2.1.4 by Michael Torbert of Semper Fi Web Design[103,150] -->
<meta name="description" content="很久之前为公司爬取过一次数据,受益匪浅,记忆犹新,分享一下。 一 工欲善其事必先利其器 首先,这里介绍几个工具 httplib python中的http客户端 urllib 对httplib的简单封装,可以很方便的" />
<meta name="keywords" content="python,urllib2,urllib,re,爬虫" />
<link rel="canonical" href="http://blog.goodje.com/2012-08/python-middle-action-web-crawler.html" />
<!-- /all in one seo pack -->
<script>
var shlPath = "http://blog.goodje.com/wp-content/themes/color/syntaxhighlighter/scripts/";
var shal = [];
var shallist = {
js: ['js', 'jscript', 'javascript', shlPath + 'shBrushJScript.js'],
php: ['php', 'phtml', shlPath + 'shBrushPhp.js'],
as3: ['as3', 'actionscript3', shlPath + 'shBrushAS3.js'],
bash: ['bash', shlPath + 'shBrushBash.js'],
cpp: ['cpp', shlPath + 'shBrushCpp.js'],
csharp: ['csharp', shlPath + 'shBrushCSharp.js'],
css: ['css', shlPath + 'shBrushCss.js'],
java: ['java', shlPath + 'shBrushJava.js'],
perl: ['perl', shlPath + 'shBrushPerl.js'],
plain: ['plain', 'text', shlPath + 'shBrushPlain.js'],
python: ['py', 'python', shlPath + 'shBrushPython.js'],
ruby: ['ruby', 'rb', shlPath + 'shBrushRuby.js'],
sql: ['sql', shlPath + 'shBrushSql.js'],
xml: ['xml', shlPath + 'shBrushXml.js'],
apple: ['apple', shlPath + 'shBrushAppleScript.js']
};
var colorOption = {shlPath: shlPath};
function sh(brush) {
if (typeof shallist[brush] !== 'undefined') shal[shal.length] = shallist[brush];
}
sh('js');
</script>
</head>
<body class="single single-post postid-1374 single-format-standard">
<div id="wrapper">
<div id="header">
<div id="header-nav">
<ul>
<li class="portfolio"><a href="http://blog.goodje.com/who-is-je">文杰是谁</a></li>
<li class="contact"><a href="http://blog.goodje.com/contact">联系我</a></li>
</ul>
</div>
<h1 id="header-title"><a href="http://blog.goodje.com/"><img src="http://blog.goodje.com/wp-content/themes/color/images/site-logo.gif?20120815" alt="网站logo" title="回首页" width="191" height="72" />文杰的博客,good·je</a></h1>
</div><div id="container"><div id="main-content"><div id="crumb"><a href="http://blog.goodje.com/">首页</a> » <a href="http://blog.goodje.com/category/wo-men-dou-shi-cai-niao" title="查看我们都是菜鸟中的全部文章" rel="category tag">我们都是菜鸟</a></div><div class="post" id="post-1374">
<h1 class="post-title" title="Python实战中阶(一)——爬取网页的一点分享">Python实战中阶(一)——爬取网页的一点分享</h1>
<span class="date">2012-8-22 02:44</span><p class="category"> 分类:<a href="http://blog.goodje.com/category/wo-men-dou-shi-cai-niao" title="查看我们都是菜鸟中的全部文章" rel="category tag">我们都是菜鸟</a> 作者:<a href="http://blog.goodje.com/author/admin" title="由文发布" rel="author">文</a> 阅读:3,173 评论: <span class="comment"><a href="http://blog.goodje.com/2012-08/python-middle-action-web-crawler.html#comments" title="《Python实战中阶(一)——爬取网页的一点分享》上的评论"> 评论: 3</a></span></p>
<p class="post-share"><a href="javascript:;" onclick="post_share('qq', 'Python%E5%AE%9E%E6%88%98%E4%B8%AD%E9%98%B6%EF%BC%88%E4%B8%80%EF%BC%89%E2%80%94%E2%80%94%E7%88%AC%E5%8F%96%E7%BD%91%E9%A1%B5%E7%9A%84%E4%B8%80%E7%82%B9%E5%88%86%E4%BA%AB+%E5%BE%88%E4%B9%85%E4%B9%8B%E5%89%8D%E4%B8%BA%E5%85%AC%E5%8F%B8%E7%88%AC%E5%8F%96%E8%BF%87%E4%B8%80%E6%AC%A1%E6%95%B0%E6%8D%AE%EF%BC%8C%E5%8F%97%E7%9B%8A%E5%8C%AA%E6%B5%85%EF%BC%8C%E8%AE%B0%E5%BF%86%E7%8A%B9%E6%96%B0%EF%BC%8C%E5%88%86%E4%BA%AB%E4%B8%80%E4%B8%8B%E3%80%82+%E4%B8%80+%E5%B7%A5%E6%AC%B2%E5%96%84%E5%85%B6%E4%BA%8B%E5%BF%85%E5%85%88%E5%88%A9%E5%85%B6%E5%99%A8+%E9%A6%96%E5%85%88%EF%BC%8C%E8%BF%99%E9%87%8C%E4%BB%8B%E7%BB%8D%E5%87%A0%E4%B8%AA%E5%B7%A5%E5%85%B7+httplib+python%E4%B8%AD%E7%9A%84http%E5%AE%A2%E6%88%B7%E7%AB%AF+urllib+%E5%AF%B9httplib%E7%9A%84%E7%AE%80%E5%8D%95%E5%B0%81%E8%A3%85%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%BE%88%E6%96%B9%E4%BE%BF%E7%9A%84', 'http%3A%2F%2Fblog.goodje.com%2F2012-08%2Fpython-middle-action-web-crawler.html');" title="转播到腾讯微博"><img src="http://v.t.qq.com/share/images/s/b16.png" alt="转播到腾讯微博" ></a> <a hidefocus="true" href="javascript:;" onclick="post_share('sina', 'Python%E5%AE%9E%E6%88%98%E4%B8%AD%E9%98%B6%EF%BC%88%E4%B8%80%EF%BC%89%E2%80%94%E2%80%94%E7%88%AC%E5%8F%96%E7%BD%91%E9%A1%B5%E7%9A%84%E4%B8%80%E7%82%B9%E5%88%86%E4%BA%AB+%E5%BE%88%E4%B9%85%E4%B9%8B%E5%89%8D%E4%B8%BA%E5%85%AC%E5%8F%B8%E7%88%AC%E5%8F%96%E8%BF%87%E4%B8%80%E6%AC%A1%E6%95%B0%E6%8D%AE%EF%BC%8C%E5%8F%97%E7%9B%8A%E5%8C%AA%E6%B5%85%EF%BC%8C%E8%AE%B0%E5%BF%86%E7%8A%B9%E6%96%B0%EF%BC%8C%E5%88%86%E4%BA%AB%E4%B8%80%E4%B8%8B%E3%80%82+%E4%B8%80+%E5%B7%A5%E6%AC%B2%E5%96%84%E5%85%B6%E4%BA%8B%E5%BF%85%E5%85%88%E5%88%A9%E5%85%B6%E5%99%A8+%E9%A6%96%E5%85%88%EF%BC%8C%E8%BF%99%E9%87%8C%E4%BB%8B%E7%BB%8D%E5%87%A0%E4%B8%AA%E5%B7%A5%E5%85%B7+httplib+python%E4%B8%AD%E7%9A%84http%E5%AE%A2%E6%88%B7%E7%AB%AF+urllib+%E5%AF%B9httplib%E7%9A%84%E7%AE%80%E5%8D%95%E5%B0%81%E8%A3%85%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%BE%88%E6%96%B9%E4%BE%BF%E7%9A%84', 'http%3A%2F%2Fblog.goodje.com%2F2012-08%2Fpython-middle-action-web-crawler.html');" title="分享到新浪微博"><img alt="分享到新浪微博" src="http://blog.goodje.com/wp-content/themes/color/images/sina_weibo_share.gif"></a></p> <div class="post-content"><p><script type="text/javascript">// <![CDATA[
sh('bash');sh('python');
// ]]></script></p>
<p style="text-indent: 2em;">很久之前为公司爬取过一次数据,受益匪浅,记忆犹新,分享一下。</p>
<h3>一 工欲善其事必先利其器</h3>
<p style="text-indent: 2em;">首先,这里介绍几个工具</p>
<ol>
<li><strong><span style="text-indent: 2em;">httplib</span></strong><span style="text-indent: 2em;"> python中的http客户端</span></li>
<li><strong><span style="text-indent: 2em;">urllib</span></strong><span style="text-indent: 2em;"> 对httplib的简单封装,可以很方便的请求一个url</span></li>
<li><strong><span style="text-indent: 2em;">urllib2</span></strong><span style="text-indent: 2em;"> urllib的增强而不是升级,全名定制请求header</span></li>
<li><strong style="text-indent: 26px;">re</strong> python对正则表达式的支持</li>
<li><strong style="text-indent: 26px;">cookielib</strong> python的一个cookie处理器</li>
<li><strong style="text-indent: 26px;">Cookie</strong> python的一个cookie对象,可以很容易的对cookie合成和解析</li>
</ol>
<p style="text-indent: 2em;">这几个工具都是python内核中作为库或模块存在的,直接import即可。</p>
<h4>1. httplib</h4>
<p style="text-indent: 2em;"><strong></strong>httplib是python对http的简单实现,请求头的内容以及响应都需要人肉完全组装和解析,我们一般不用,因为对于抓取普通页面httplib还能应付,但是涉及到302、cookie验证的登录、防盗链等就会很<span id="more-1374"></span>吃力。</p>
<p style="text-indent: 2em;">但是,这里我可以简单介绍一下,假设我们要抓取杰杰的博客首页。</p>
<pre class="brush: python">import httplib
host = 'blog.goodje.com'
port = httplib.HTTP_PORT
url = '/' #这里其实是cgi相对路径和参数列表,类似php的REQUEST_URI
hl = httplib.HTTPConnection(host, port)
hl.request('GET', url)
resp = hl.getresponse() #拿到响应的对象,包括响应头、正文和其它的方法
respHtml = resp.read() #响应正文
hl.close()</pre>
<p style="text-indent: 2em;">当拿到正文后分析,就可以拿到想要抓取的内容了。如果是涉及到登录或者防盗链要家referer,需要手动拼装http请求头,然后作为request方法的第四个参数发送请求。</p>
<blockquote>
<p style="text-indent: 2em;">特别要注意的是,最后一句关闭连接,虽然系统会帮助关闭连接和垃圾回收,或者由于超时自动关闭,但是当连接过多,就会占用系统非常多的资源,不管是打开http连接、tcp连接,还是文件资源等,打开资源后关闭是个非常好的习惯。</p>
</blockquote>
<p style="text-indent: 2em;"><a title="httplib — HTTP protocol client" href="http://docs.python.org/library/httplib.html" target="_blank">这里是关于httplib的详细介绍。</a></p>
<h4>2. urllib</h4>
<p style="text-indent: 2em;"><strong></strong>urllib其实是对httplib的一个简单封装,无需创建request对象、请求和关闭连接,当然也屏蔽了许多细节,使我们没办法构建自定义的http头,我们在后面的使用也不会用到,这里简单介绍一下。</p>
<pre class="brush: python">import urllib
url = 'http://blog.goodje.com/'
fh = urllib.urlopen(url)
#请求了url对应的资源,并返回一个file handle。
respHtml = fh.read() #响应正文
fh.close()</pre>
<p style="text-indent: 2em;">fh其实是一个类似本地的文件资源的连接,拥有read(),readline(),fileno()等方法,另外值得关注的是info(), getcode() 和 geturl()这三个方法,这是普通文件资源所没有的,info()用来读取部分响应的内容,getcode(),用来获取响应的http code从而判断该url是否可用,而geturl()用来获取真实的url地址,因为原始地址可能会被重定向。</p>
<p style="text-indent: 2em;">info()返回的是一个mimetools.Message对象,详情可以<a title="class mimetools.Message" href="http://docs.python.org/library/mimetools.html#mimetools.Message" target="_blank">点击这里</a>。</p>
<p style="text-indent: 2em;">另外值得注意的一点便是,urllib可以很容易实现代理,当抓取机的ip被目标server屏蔽时,便变得非常有用。</p>
<p style="text-indent: 2em;">用法之一便是实现bash的全局变量</p>
<pre class="brush: bash">export http_proxy="http://proxy.goodje.com:3218"</pre>
<p style="text-indent: 2em;">这时,使用urlopen的时候,便会自动走该代理。而如果想自定义的代理或者不想走代理时,可以这样:</p>
<pre class="brush: python">proxies = {'http': 'http://proxy1.goodje.com:3128'}
fh = urllib.urlopen(url, proxies = proxies) #自定义代理
fh = urllib.urlopen(url, proxies = {}) #不使用代理
fh = urllib.urlopen(url, proxies = Null)
#系统代理,也就是判断使用有bash http_proxy全局变量</pre>
<p style="text-indent: 2em;">如果不传第二个参数,也会用系统的代理设置。</p>
<p style="text-indent: 2em;">当然urllib还有其它很多方法,比如说urlencode()等,大家可以自己研究。</p>
<p style="text-indent: 2em;"><a title="urllib — Open arbitrary resources by URL" href="http://docs.python.org/library/urllib.html" target="_blank">这里是关于urllib的详细介绍。</a></p>
<h4>3. urllib2</h4>
<p style="text-indent: 2em;">这是需要重点介绍的,也是我们之后<strong>会用到来抓取页面的常用工具之一</strong>。</p>
<p style="text-indent: 2em;">从字面上来看,urllib2应该是urllib的升级版本,但为什么python会让这两个版本在python共存呢?其实是这样的,urllib2是urllib的增强版,而不是升级版,urllib用来满足日常简单应用,而urllib2可以支持更高级的特性,主要是可以像urlopen()传一个urllib2.Request对象,这样开发者可以自行合成请求头,以及对cookie的支持以及重定向的处理,http 认证等等,当然,这些操作会比使用httplib简单很多很多。后面对于要使用的地方会详细介绍。</p>
<p style="text-indent: 2em;">另外,这里还要介绍一下<strong><a title="PYCURL" href="http://pycurl.sourceforge.net/" target="_blank">pycurl</a></strong>,对于使用命令比较多,或者php curl的开发者,应该会非常熟悉,有他实在是太方便了,但是在python中由于强大的urllib2存在,以及pycurl需要依赖很多包,导致pycurl在py中安装非常繁琐,这里不详细介绍,有兴趣的可以了解一下,使用和php curl类似,当让还有基于urllib2开发的的<a title="mechanize" href="http://wwwsearch.sourceforge.net/mechanize/" target="_blank">mechanize</a>,也是很强大的。</p>
<pre class="brush: python">import urllib2
req = urllib2.Request('http://blog.goodje.com/')
fh = urllib2.urlopen(req) #也可以直接传字符串的url
respHtml = fh.read()
fh.close()</pre>
<p style="text-indent: 2em;"><a title="urllib2 — extensible library for opening URLs" href="http://docs.python.org/library/urllib2.html" target="_blank">这里是关于urllib2的详细介绍。</a></p>
<h4>4. re</h4>
<p style="text-indent: 2em;"><strong></strong>python对正则表达式的支持模块。如果http库有选择的余地外,re几乎是没有选择余地的工具。因为有正则表达式的存在,所以让我们可以很灵活的去抠取抓取过来的完整html中所需要的部分。</p>
<p style="text-indent: 2em;">当然,这篇文章不会详细解释正则表达式,因为如果要系统的介绍正则表达式,或许可以写一本书了。这里只简单提一下我们后面会用到的python正则表达式的用法。</p>
<p style="text-indent: 2em;"><strong>re.compile()</strong>。如果正则表达式比较多,请一定要先用这个方法先行编译正则表达式,之后再正则表达式的使用就会很非常快,因为大家都知道,python文件在第一次运行会分别创建一个字节码文件,如果正则表达式作为字符串的时候,在运行时才会被编译,是会影响到python的执行速度的。</p>
<pre class="brush: python">import re
bodyRe =re.compile(r'(.*)', re.I | re.S)
#re.I是匹配模式不区别大小写,而re.S可以改变.的行为让其匹配默认不会匹配的换行符。</pre>
<p style="text-indent: 2em;">compile()返回的是一个re对象,该对象拥有re库的search(), match(), findall()等方法,这三个方法,在后面会被频繁的用到,生成被编译的re对象还有一个好处是调用方法不用再传入字符串的正则表达式。</p>
<p style="text-indent: 2em;">search()主要用来校验正则表达式能否匹配字符串中的一段,通常用来判断该页面是否有我需要的内容。</p>
<pre class="brush: python">match = re.search(r'<div class="post"', respHtml)
#如果有被正则表达式匹配的一段,则返回匹配对象,否则为None
if match is not None:
print match.group() #匹配成功</pre>
<p style="text-indent: 2em;">match()用来判断字符串是否完全被一个正则表达式匹配,后面用的比较少。</p>
<pre class="brush: python">#seach()和match()区别主要是一个是用正则表达式进行查找,一个是用来匹配字符串
re.match(r'post', 'class="post"') #匹配失败
re.search(r'post', 'class="post"') #匹配成功</pre>
<p style="text-indent: 2em;">findall()用来搜索正则表达式在字符串中的所有匹配,并返回一个列表,如果没有任何匹配,则返回一个空列表。</p>
<pre class="brush: python">print re.findall(r'p-\d', "p-1, p-2, p-3, p-4")
#['p-1', 'p-2', 'p-3', 'p-4']
#如果有子组(正则表达式中有括号)的正则表达式会更复杂
print re.findall(r'p-(\d(\d?))', "p-12, p-22, p-33, p-4")
#[('12', '2'), ('22', '2'), ('33', '3'), ('4', '')]</pre>
<p style="text-indent: 2em;">带有子组的正则表达式,findall()返回的列表中的每个元素为一个元组,正则表达式中有几个子组,元组中就会有几个元素,第一个元素为第一个括号中的子组匹配到的元素,以此类推。</p>
<p style="text-indent: 2em;">findall()和search()是有类似之处的,都是搜索正则表达式在字符串中的匹配,但是findall()返回一个列表,search()返回一个匹配对象,而且findall()返回的列表中有所有匹配,而search()只返回第一个匹配的匹配对象。</p>
<p style="text-indent: 2em;"><a title="re — Regular expression operations" href="http://docs.python.org/library/re.html" target="_blank">这里是关于re的详细介绍。</a></p>
<h4>5. cookielib和Cookie</h4>
<p style="text-indent: 2em;">这两个库后面会详细提到,这里不过多介绍。</p>
<h3>二 真刀真枪,厮杀秘籍</h3>
<p style="text-indent: 2em;">上面介绍了下面会用到的大部分工具,这里重点讲一下用urllib2来爬取复杂的网络情况,特别是破解防盗链和登录。</p>
<pre class="brush: python">import urllib2
req = urllib2.Request('http://blog.goodje.com/') #创建一个request对象</pre>
<h4><span style="text-indent: 2em;">1. Refere验证</span></h4>
<pre class="brush: python">req.add_header('Refere', 'http://blog.goodje.com/')</pre>
<h4>2. User-Agent验证</h4>
<pre class="brush: python">req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.79 Safari/537.1')</pre>
<h4>3. Cookie验证</h4>
<p style="text-indent: 2em;">有些页面是需要验证cookie的,比如防盗链的资源或者需要登录的页面。</p>
<pre class="brush: python">import cookielib
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
opener.open(req)
#如果这次请求又返回set-cookie,
#那么当第二次请求带上cj时,就会自动将这次设置的cookie带入到请求中</pre>
<p style="text-indent: 2em;">如果想自己手动设置cookie,可以用<strong>Cookie</strong>库</p>
<pre class="brush: python">import Cookie
c = Cookie.SimpleCookie()
c['name'] = 'admin' #cookie名为name,值为admin
c['name']['domain'] = '.goodje.com'
c['name']['path'] = '/'
#可以用c.outpu()检验cookie的正确性
#另外还有expires(过期时间,不穿为回话),comment,max-age,secure,version,httponly ,因为这些参数主要用于浏览器客户端,不涉及这次的开发,有兴趣的同学可以详细查看RFC 2109。
cj.set_cookie(c) #再次请求,就会带上name这个cookie</pre>
<p style="text-indent: 2em;">不过这一步的意义不大,因为服务器需要验证的cookie,通常我们是无法知道具体值的,所以没办法自己拼装。</p>
<p style="text-indent: 2em;"><a title="RFC 2109 HTTP State Management Mechanism" href="http://tools.ietf.org/html/rfc2109.html" target="_blank">RFC 2109</a>。</p>
<h4>4. 返回码(HTTP Code)</h4>
<p style="text-indent: 2em;">如果抓取的页面不存在,或者dns无法解析等问题,会抛出urllib2.HTTPError或者urllib2.URLError异常。</p>
<p style="text-indent: 2em;">通常来说是dns无法解析会抛出URLError,也是IOError的基类,而404,500等会抛出HTTPError异常,它是URLError的基类。</p>
<pre class="brush: python">try:
urllib2.urlopen('http://blog.goodje.com/errpage')
except urllib2.HTTPError, e:
print e.code #返回的http code
except urllib2.URLError, e:
...</pre>
<h4>5. 调试模式</h4>
<p style="text-indent: 2em;">代码在跑的时候,我们并不知道程序在后台的动作,打开调试模式,可以查看后台的发包和收包状况</p>
<pre class="brush: python">httpHandler = urllib2.HTTPHandler(debuglevel = 1)
httpshandler = urllib2.HTTPSHandler(debuglevel = 1)
opener = urllib2.build_opener(httpHandler, httpshandler)
fh = opener.urlopen('http://blog.goodje.com/')</pre>
<h4>6. 防封ip神器——代理</h4>
<p style="text-indent: 2em;">当抓取机在某台服务器上告诉抓取时,很有可能被网站管理员发现很有可能会被封掉ip,这时代理就能派上用场了。</p>
<pre class="brush: python">proxyHandler = urllib2.proxyHandler({'http': 'http://proxy.goodje.com:3128/'})
#设置带用户名和密码的代理
proxyAuthHandler = urllib2.proxyBasicAuthHandler()
proxyAuthHandler.add_password('realm', 'proxy.goodje.com:3128', 'user', 'password') #需要用户名密码的代理
proxyHandler1 = urllib2.proxyHandler({'http': 'http://user:[email protected]:3128/'}) #另外一种形式设置用户名和密码
opener = urllib2.build_opener(proxyHandler)
fh = opener.urlopen('http://blog.goodje.com/')</pre>
<h4>7. 防封ip终极神器——sleep()</h4>
<p style="text-indent: 2em;">就算设置了代理,代理的ip也有可能被封,还有另外一种终极的办法来防止被封,那便是使用time库的sleep()函数。</p>
<pre class="brush: python">import time
for i in range(1:10):
... #抓取逻辑
time.sleep(5) #单位为秒</pre>
<p style="text-indent: 2em;">休眠时间可根据实际情况动态的调整,最开始10s,慢慢调成9s, 8s…… 不要调到太小以防止被封</p>
<h4>8.多线程</h4>
<p style="text-indent: 2em;">如果有一台很好的机器来抓取网页,单线程的方式就实在是太大材小用了,让多线程来好好利用吧。</p>
<p style="text-indent: 2em;">这里会用到threading库的Thread类。</p>
<pre class="brush: python">def worker(arg1, arg2):
...#抓取逻辑
#创建一个线程
th = threading.Thread(target=worker, args=(arg1, arg2))
th.start() #启动线程
th.join() #等待线程结束,则主进程结束</pre>
<p style="text-indent: 2em;">因为python的线程是跑在虚拟机上的,并非真的多线程,所以对于系统资源的利用率上和本身多进程机制还是有一定问题的,另外对多核cpu的利用也不好,但是相对于单线程还是好多了。</p>
<h3>三、总结</h3>
<p style="text-indent: 2em;">抓取网页,总的来说有三个问题要解决,破解防盗链,防止IP被封和html过于复杂。</p>
<p style="text-indent: 2em;">前面两个问题上文已经给出了解决方案,至于最后一个问题,就要开发者实地评估和能很好的使用正则表达式了,但是虽然能很好的使用正则表达式,一般的页面都能爬出来,但是正则表达式无法解决嵌套的问题,python有个库,xml.dom,但是它对html的结构要求非常严格,如果标签没有结束或者标签属性不对都会抛出异常。</p>
<p style="text-indent: 2em;">有一个比较好的解析html的工具——<a title="sgmllib — Simple SGML parser" href="http://docs.python.org/library/sgmllib.html" target="_blank">SGMLParser</a>,有兴趣的同学可以详细研究,非常好用。</p>
<p style="text-indent: 2em;">最后,本文没有讲到数据落地的问题,也就是爬到了,但是没有保存起来,博主之后会写一篇关于<a title="MySQL for Python" href="http://sourceforge.net/projects/mysql-python/" target="_blank">MySQL for Python</a>的博客,敬请关注!</p>
</div>
<div class="post-footer"><a href="http://blog.goodje.com/2012-08/python-middle-action-web-crawler.html#comments" class="post-reply" title="《Python实战中阶(一)——爬取网页的一点分享》上的评论">发表评论</a><div>标签:<a href="http://blog.goodje.com/tag/python" rel="tag">python</a>,<a href="http://blog.goodje.com/tag/%e7%88%ac%e8%99%ab" rel="tag">爬虫</a></div></div>
<div class="clear"></div></div>
<div class="post-nextprev"><span class="prev">上一篇:<a href="http://blog.goodje.com/2012-08/zhudongfenxiang.html" rel="prev">主动分享</a> </span><span class="next">下一篇:<a href="http://blog.goodje.com/2012-08/his-world.html" rel="next">他的中国观</a> </span></div><div class="related_post_area">
<div class="wp_rp_wrap wp_rp_plain" id="wp_rp_first"><div class="wp_rp_content"><h3 class="related_post_title">相关日志</h3><ul class="related_post wp_rp" style="visibility: visible"><li ><a href="http://blog.goodje.com/2010-06/wordpress3-0%e4%bd%93%e9%aa%8c%e5%92%8c%e6%96%b0%e7%89%b9%e6%80%a7.html" class="wp_rp_title">WordPress3.0体验和新特性</a></li><li ><a href="http://blog.goodje.com/2012-08/his-world.html" class="wp_rp_title">他的中国观</a></li><li ><a href="http://blog.goodje.com/2010-05/swfupload-sample-tutorial.html" class="wp_rp_title">文件上传利器SWFUpload入门简易教程</a></li><li ><a href="http://blog.goodje.com/2009-03/javascript-%e5%b8%b8%e7%94%a8screen%e5%af%b9%e8%b1%a1%e7%9a%84%e5%b1%9e%e6%80%a7.html" class="wp_rp_title">javascript 常用screen对象的属性</a></li><li ><a href="http://blog.goodje.com/2009-11/fanqiang-so-easy.html" class="wp_rp_title">翻墙,就是这么自信</a></li><li ><a href="http://blog.goodje.com/2009-03/php-%e4%b8%8a%e4%bc%a0%e6%96%87%e4%bb%b6%e7%9a%84%e5%a2%9e%e5%bc%ba%e5%87%bd%e6%95%b0.html" class="wp_rp_title">php 上传文件的增强函数</a></li></ul></div></div>
</div><div id="comment">
<h5 id="comments">3条评论</h5>
<div class="navigation">
<div class="alignleft"></div>
<div class="alignright"></div>
</div>
<div id="commentlist">
<ol>
<div class="gravatar"><img alt='' src='http://0.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s=40' class='avatar avatar-40 photo avatar-default' height='40' width='40' /></div>
<div class="comments">
<li class="alt" id="comment-2195">
<cite><a href='http://blog.goodje.com/?r=http://0' rel='external nofollow' class='url'>匿名</a></cite> <br />
<p>0</p>
<small class="commentmetadata"><a href="http://blog.goodje.com/2012-08/python-middle-action-web-crawler.html/comment-page-1#comment-2195" title="2012-08-24T14:18:06+00:00">2012年8月24日14:18</a> </small>
<div class="reply"><a class='comment-reply-link' href='/2012-08/python-middle-action-web-crawler.html?replytocom=2195#respond' onclick='return addComment.moveForm("comment-2195", "2195", "respond", "1374")'>回复<span>↓</span></a></div><!-- .reply -->
<div class="clear"></div>
</li>
</div>
<div class="separator"></div>
</li><!-- #comment-## -->
<div class="gravatar"><img alt='' src='http://0.gravatar.com/avatar/eb819c24e9f6d53fa4ad03d2cc403ce2?s=40&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D40&r=G' class='avatar avatar-40 photo' height='40' width='40' /></div>
<div class="comments">
<li class="alt" id="comment-3700">
<cite><a href='http://blog.goodje.com/?r=http://u.youku.com/initialgsa' rel='external nofollow' class='url'>Jarvis</a></cite> <br />
<p>哥们儿,你好久不更新博客了。这个系列怎么不写下去了呢?</p>
<small class="commentmetadata"><a href="http://blog.goodje.com/2012-08/python-middle-action-web-crawler.html/comment-page-1#comment-3700" title="2013-02-07T17:04:26+00:00">2013年2月7日17:04</a> </small>
<div class="reply"><a class='comment-reply-link' href='/2012-08/python-middle-action-web-crawler.html?replytocom=3700#respond' onclick='return addComment.moveForm("comment-3700", "3700", "respond", "1374")'>回复<span>↓</span></a></div><!-- .reply -->
<div class="clear"></div>
</li>
</div>
<div class="separator"></div>
<ol class="children">
<div class="gravatar"><img alt='' src='http://1.gravatar.com/avatar/58cc2d47e9357f005afba44758b119a0?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G' class='avatar avatar-32 photo' height='32' width='32' /></div>
<div class="comments">
<li class="alt" id="comment-4878">
<cite><a href='http://blog.goodje.com/?r=http://www.goodje.com/' rel='external nofollow' class='url'>JeJe</a></cite> <br />
<p>最近忙得不得了,唉,会继续的!</p>
<small class="commentmetadata"><a href="http://blog.goodje.com/2012-08/python-middle-action-web-crawler.html/comment-page-1#comment-4878" title="2013-04-07T13:58:33+00:00">2013年4月7日13:58</a> </small>
<div class="reply"><a class='comment-reply-link' href='/2012-08/python-middle-action-web-crawler.html?replytocom=4878#respond' onclick='return addComment.moveForm("comment-4878", "4878", "respond", "1374")'>回复<span>↓</span></a></div><!-- .reply -->
<div class="clear"></div>
</li>
</div>
<div class="separator"></div>
</li><!-- #comment-## -->
</ol><!-- .children -->
</li><!-- #comment-## -->
</ol>
</div>
<div class="navigation">
<div class="alignleft"></div>
<div class="alignright"></div>
</div>
</div>
<h5 id="respond">发表评论</h5>
<p><a rel="nofollow" id="cancel-comment-reply-link" href="/2012-08/python-middle-action-web-crawler.html#respond" style="display:none;">点击这里取消回复。</a></p>
<form action="http://blog.goodje.com/wp-comments-post.php" method="post" id="commentform">
<p>
<input type="text" name="author" id="author" value="" size="40" tabindex="1" class="comment-form" />
<label for="author"><span class="cmt-detail">昵称 </span></label>
</p>
<p>
<input type="text" name="email" id="email" value="" size="40" tabindex="2" class="comment-form" />
<label for="email"><span class="cmt-detail">E-mail </span></label>
</p>
<p>
<input type="text" name="url" id="url" value="" size="40" tabindex="3" class="comment-form" />
<label for="url"><span class="cmt-detail">网址</span></label>
</p>
<p><small>您可以使用这些<strong>HTML</strong>标签以至于不被和谐: <code><a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> </code></small></p>
<p>
<textarea name="comment" id="comment" cols="100%" rows="10" tabindex="4" class="comment-form"></textarea>
</p>
<p>
<input name="submit" type="submit" id="submit" tabindex="5" value="提交评论" />
<input type='hidden' name='comment_post_ID' value='1374' id='comment_post_ID' />
<input type='hidden' name='comment_parent' id='comment_parent' value='0' />
</p>
<p style="display: none;"><input type="hidden" id="akismet_comment_nonce" name="akismet_comment_nonce" value="f4e2c16ab2" /></p></form>
</div><div id="sidebar">
<div class="sb-top">
</div>
<div class="sb-content">
<div class="box">
<h6>搜索</h6>
<div class="sidebar-search"><form method="get" id="searchform" action="http://blog.goodje.com/"><input type="text" name="s" class="keyword" value="关键字" onblur="if(this.value=='') this.value='关键字'" onfocus="if(this.value=='关键字') this.value=''" size="28"/></form></div>
</div>
<div class="clear"></div>
<div id="categories-378652251" class="box widget_categories"><h6 class="widget-title">文章分类</h6> <ul>
<li class="cat-item cat-item-218"><a href="http://blog.goodje.com/category/wo-men-dou-shi-cai-niao/cat-api-or-open-platform" title="查看api/开放平台下的所有文章">api/开放平台</a> (1)
</li>
<li class="cat-item cat-item-16"><a href="http://blog.goodje.com/category/goooooal%ef%bc%81%ef%bc%81" title="查看GOOOOOAL!!下的所有文章">GOOOOOAL!!</a> (16)
</li>
<li class="cat-item cat-item-14"><a href="http://blog.goodje.com/category/jeje-bu-zhui-xing" title="查看JeJe不追星下的所有文章">JeJe不追星</a> (7)
</li>
<li class="cat-item cat-item-140"><a href="http://blog.goodje.com/category/jeje-zuo-pin" title="查看JeJe作品下的所有文章">JeJe作品</a> (5)
</li>
<li class="cat-item cat-item-15"><a href="http://blog.goodje.com/category/qi-zhai-chao" title="查看七摘八抄下的所有文章">七摘八抄</a> (10)
</li>
<li class="cat-item cat-item-213"><a href="http://blog.goodje.com/category/cat-blog" title="查看博客下的所有文章">博客</a> (2)
</li>
<li class="cat-item cat-item-214"><a href="http://blog.goodje.com/category/cat-good-song-let-everyone-love-to-listen" title="查看好歌都爱听下的所有文章">好歌都爱听</a> (1)
</li>
<li class="cat-item cat-item-217"><a href="http://blog.goodje.com/category/wide-template" title="文章展示时,主体区域宽的板式设计,宽度为整个版面的宽度。">宽版</a> (1)
</li>
<li class="cat-item cat-item-11"><a href="http://blog.goodje.com/category/wo-men-dou-shi-cai-niao" title="查看我们都是菜鸟下的所有文章">我们都是菜鸟</a> (39)
</li>
<li class="cat-item cat-item-10"><a href="http://blog.goodje.com/category/sheng-huo-liu-shui-xian" title="查看生活流水线下的所有文章">生活流水线</a> (33)
</li>
<li class="cat-item cat-item-12"><a href="http://blog.goodje.com/category/zou-jeje-de-lu" title="查看走JeJe的路下的所有文章">走JeJe的路</a> (20)
</li>
</ul>
</div><div class="clear"></div><div id="views-3" class="box widget_views"><h6 class="widget-title">人气文章</h6><ul>
<li><a href="http://blog.goodje.com/2009-11/fanqiang-so-easy.html" title="翻墙,就是这么自信">翻墙,就是这么自信</a>(8,530)</li><li><a href="http://blog.goodje.com/gallery" title="相册">相册</a>(8,262)</li><li><a href="http://blog.goodje.com/2010-06/%e5%88%86%e4%ba%ab%e4%b8%80%e4%b8%aaflash-builder-4%e6%ad%a3%e5%bc%8f%e7%89%88%e7%9a%84%e5%ba%8f%e5%88%97%e5%8f%b7.html" title="分享一个Flash Builder 4正式版的序列号">分享一个Flash Builder 4正式版的序列号</a>(7,923)</li><li><a href="http://blog.goodje.com/2010-05/swfupload-sample-tutorial.html" title="文件上传利器SWFUpload入门简易教程">文件上传利器SWFUpload入门简易教程</a>(7,139)</li><li><a href="http://blog.goodje.com/2011-11/tengxunkaifangpingtai-client-id-is-illegal100008.html" title="腾讯开放平台——client id is illegal(100008)!错误解决">腾讯开放平台——client id is illegal(100008)!错误解决</a>(3,781)</li><li><a href="http://blog.goodje.com/2012-08/python-middle-action-web-crawler.html" title="Python实战中阶(一)——爬取网页的一点分享">Python实战中阶(一)——爬取网页的一点分享</a>(3,173)</li><li><a href="http://blog.goodje.com/2010-05/%e9%9a%90%e8%97%8f%e6%96%87%e4%bb%b6%e6%97%a0%e6%b3%95%e5%8f%96%e6%b6%88%e9%9a%90%e8%97%8f%e5%b1%9e%e6%80%a7%e7%9a%84%e8%a7%a3%e5%86%b3.html" title="隐藏文件无法取消隐藏属性的解决">隐藏文件无法取消隐藏属性的解决</a>(1,845)</li><li><a href="http://blog.goodje.com/2010-08/%e7%bc%96%e8%af%91%e5%ae%89%e8%a3%85gd%e5%ba%93%e5%87%ba%e9%94%99%e7%9a%84%e8%a7%a3%e5%86%b3.html" title="编译安装GD库出错的解决">编译安装GD库出错的解决</a>(1,315)</li><li><a href="http://blog.goodje.com/2009-03/%e5%9c%a8ubuntu810%e4%b8%8a%e5%ae%89%e8%a3%85vmware-tools.html" title="在Ubuntu8.10上安装VMware Tools">在Ubuntu8.10上安装VMware Tools</a>(1,294)</li><li><a href="http://blog.goodje.com/who-is-je" title="文杰是谁">文杰是谁</a>(1,275)</li></ul>
</div><div class="clear"></div> <div id="recent-posts-2" class="box widget_recent_entries"> <h6 class="widget-title">近期文章</h6> <ul>
<li>
<a href="http://blog.goodje.com/2013-05/feelbitter.html">心酸</a>
</li>
<li>
<a href="http://blog.goodje.com/2012-08/talk-something-with-a-driver.html">和一位的士司机的谈话</a>
</li>
<li>
<a href="http://blog.goodje.com/2012-08/his-world.html">他的中国观</a>
</li>
<li>
<a href="http://blog.goodje.com/2012-08/python-middle-action-web-crawler.html">Python实战中阶(一)——爬取网页的一点分享</a>
</li>
<li>
<a href="http://blog.goodje.com/2012-08/zhudongfenxiang.html">主动分享</a>
</li>
</ul>
</div><div class="clear"></div><div id="archives-2" class="box widget_archive"><h6 class="widget-title">每月文章</h6> <ul>
<li><a href='http://blog.goodje.com/2013/05'>2013年五月</a> (1)</li>
<li><a href='http://blog.goodje.com/2012/08'>2012年八月</a> (4)</li>
<li><a href='http://blog.goodje.com/2012/05'>2012年五月</a> (2)</li>
<li><a href='http://blog.goodje.com/2012/02'>2012年二月</a> (1)</li>
<li><a href='http://blog.goodje.com/2011/11'>2011年十一月</a> (2)</li>
<li><a href='http://blog.goodje.com/2011/10'>2011年十月</a> (2)</li>
<li><a href='http://blog.goodje.com/2011/09'>2011年九月</a> (2)</li>
<li><a href='http://blog.goodje.com/2011/06'>2011年六月</a> (3)</li>
<li><a href='http://blog.goodje.com/2011/04'>2011年四月</a> (2)</li>
<li><a href='http://blog.goodje.com/2011/01'>2011年一月</a> (2)</li>
<li><a href='http://blog.goodje.com/2010/12'>2010年十二月</a> (1)</li>
<li><a href='http://blog.goodje.com/2010/11'>2010年十一月</a> (1)</li>
<li><a href='http://blog.goodje.com/2010/09'>2010年九月</a> (1)</li>
<li><a href='http://blog.goodje.com/2010/08'>2010年八月</a> (4)</li>
<li><a href='http://blog.goodje.com/2010/07'>2010年七月</a> (4)</li>
<li><a href='http://blog.goodje.com/2010/06'>2010年六月</a> (12)</li>
<li><a href='http://blog.goodje.com/2010/05'>2010年五月</a> (11)</li>
<li><a href='http://blog.goodje.com/2010/04'>2010年四月</a> (9)</li>
<li><a href='http://blog.goodje.com/2010/03'>2010年三月</a> (10)</li>
<li><a href='http://blog.goodje.com/2010/02'>2010年二月</a> (2)</li>
<li><a href='http://blog.goodje.com/2010/01'>2010年一月</a> (4)</li>
<li><a href='http://blog.goodje.com/2009/12'>2009年十二月</a> (4)</li>
<li><a href='http://blog.goodje.com/2009/11'>2009年十一月</a> (7)</li>
<li><a href='http://blog.goodje.com/2009/09'>2009年九月</a> (3)</li>
<li><a href='http://blog.goodje.com/2009/06'>2009年六月</a> (7)</li>
<li><a href='http://blog.goodje.com/2009/05'>2009年五月</a> (2)</li>
<li><a href='http://blog.goodje.com/2009/04'>2009年四月</a> (6)</li>
<li><a href='http://blog.goodje.com/2009/03'>2009年三月</a> (7)</li>
<li><a href='http://blog.goodje.com/2009/02'>2009年二月</a> (4)</li>
<li><a href='http://blog.goodje.com/2009/01'>2009年一月</a> (3)</li>
<li><a href='http://blog.goodje.com/2008/12'>2008年十二月</a> (7)</li>
</ul>
</div><div class="clear"></div></div>
<div class="sb-bottom"></div>
</div></div></div> <div id="end">
</div>
<div id="footer">
<div id="footer-section">
<div class="footer-cell">
<h6>近期评论</h6>
<ul class="recentcomments"><li class="rc-navi rc-clearfix"><span class="rc-loading">正在加载...</span></li><li id="rc-comment-temp" class="rc-item rc-comment rc-clearfix"><div class="rc-info"></div><div class="rc-timestamp"></div><div class="rc-excerpt"></div></li><li id="rc-ping-temp" class="rc-item rc-ping rc-clearfix"><span class="rc-label"></span></li></ul>
</div>
<div class="footer-cell"><h6>链接表</h6>
<ul class='xoxo blogroll'>
<li><a href="http://www.qp3db.com" rel="friend" title="深化神话大虾的团队官方网站" target="_blank">80After 八零后</a></li>
<li><a href="http://goodje.diandian.com/" title="deli的点点滴滴" target="_blank">deli的点点</a></li>
<li><a href="http://blog.hedyguo.com/" rel="friend muse date sweetheart" title="钙钙的博客" target="_blank">在路上</a></li>
<li><a href="http://www.goodje.com/" rel="me" title="JeJe的站点,JeJe的Blog,JeJe的作品…" target="_blank">杰杰</a></li>
<li><a href="http://www.jejemf.com/" title="杰杰网络磨坊" target="_blank">杰杰网络磨坊</a></li>
</ul>
</div>
<div id="credit">Powered by Wordpress. Design by Jayhan.<br />© 2015 <a href="http://www.goodje.com/">杰杰博客 blog.GoodJe.com</a> All rights reserved. 鄂ICP备09015360号
</div>
</div>
</div>
<!-- ngg_resource_manager_marker --><script type='text/javascript' src='//blog.goodje.com/wp-content/themes/color/scripts.js?ver=20120815'></script>
<script type='text/javascript'>
/* <![CDATA[ */
var pollsL10n = {"ajax_url":"http:\/\/blog.goodje.com\/wp-admin\/admin-ajax.php","text_wait":"Your last request is still being processed. Please wait a while ...","text_valid":"Please choose a valid poll answer.","text_multiple":"Maximum number of choices allowed: ","show_loading":"1","show_fading":"1"};
/* ]]> */
</script>
<script type='text/javascript' src='http://blog.goodje.com/wp-content/plugins/wp-polls/polls-js.js?ver=2.63'></script>
<script type='text/javascript'>
/* <![CDATA[ */
var viewsCacheL10n = {"admin_ajax_url":"http:\/\/blog.goodje.com\/wp-admin\/admin-ajax.php","post_id":"1374"};
/* ]]> */
</script>
<script type='text/javascript' src='http://blog.goodje.com/wp-content/plugins/wp-postviews/postviews-cache.js?ver=1.64'></script>
<script>
/* <![CDATA[ */
var rcGlobal = {
serverUrl :'http://blog.goodje.com',
infoTemp :'%REVIEWER% 在 %POST%',
loadingText :'正在加载',
noCommentsText :'没有任何评论',
newestText :'« 最新的',
newerText :'« 上一页',
olderText :'下一页 »',
showContent :'',
external :'1',
avatarSize :'32',
avatarPosition :'left',
anonymous :'匿名'
};
/* ]]> */
</script>
<!-- Powered by WPtouch: 3.2.1 --><span id="back-top"><a href="javascript:;" onclick="back_top();"><img src="http://blog.goodje.com/wp-content/themes/color/images/transparent.gif" /></a></span>
<script type="text/javascript">//<![CDATA[
// Google Analytics for WordPress by Yoast v4.3.5 | http://yoast.com/wordpress/google-analytics/
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-21391755-1']);
_gaq.push(['_trackPageview']);
(function () {
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();
//]]></script>
<script>
for (var i in shal) {
SyntaxHighlighter.autoloader(shal[i]);
}
SyntaxHighlighter.all();
</script></body></html>
<!-- Dynamic page generated in 0.475 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2015-03-24 09:33:07 -->
<!-- super cache -->