-
Notifications
You must be signed in to change notification settings - Fork 3
/
search.xml
493 lines (297 loc) · 860 KB
/
search.xml
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
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>使用rancher2.3.6构建kubernets集群</title>
<link href="/2020/04/06/%E4%BD%BF%E7%94%A8rancher2-3-6%E6%9E%84%E5%BB%BAkubernets%E9%9B%86%E7%BE%A4/"/>
<url>/2020/04/06/%E4%BD%BF%E7%94%A8rancher2-3-6%E6%9E%84%E5%BB%BAkubernets%E9%9B%86%E7%BE%A4/</url>
<content type="html"><![CDATA[<h3 id="使用rancher2-3-6构建-kubernets集群"><a href="#使用rancher2-3-6构建-kubernets集群" class="headerlink" title="使用rancher2.3.6构建 kubernets集群"></a>使用<code>rancher2.3.6</code>构建 <code>kubernets</code>集群</h3><blockquote><p>作者:lizhonglin<br>github: <a href="https://github.com/kujirashark/" target="_blank" rel="noopener">https://github.com/kujirashark/</a><br>blog: <a href="https://kujirashark.github.io" target="_blank" rel="noopener">https://kujirashark.github.io</a></p><p>csdn-blog:<a href="https://blog.csdn.net/qq_33196814" target="_blank" rel="noopener">https://blog.csdn.net/qq_33196814</a></p></blockquote><h4 id="一、准备工作"><a href="#一、准备工作" class="headerlink" title="一、准备工作"></a>一、准备工作</h4><h5 id="1-准备3台「centosos7」系统的机器"><a href="#1-准备3台「centosos7」系统的机器" class="headerlink" title="1.准备3台「centosos7」系统的机器."></a>1.准备3台<code>「centosos7」</code>系统的机器.</h5><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">10.0.0.110 rancher-1 #1 为了下面文章好用,进行的编号.</span><br><span class="line">10.0.0.111 master-1 #2</span><br><span class="line">10.0.0.112 node-1 #3</span><br></pre></td></tr></table></figure><h5 id="2-docker安装源"><a href="#2-docker安装源" class="headerlink" title="2.docker安装源"></a>2.<code>docker</code>安装源</h5><p>1).设置每台机器的<code>docker</code>源.</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo</span><br></pre></td></tr></table></figure><p>2).在每台机器上面安装<code>docker</code>.</p><p>安装 <code>Docker Engine-Community</code>,下面的命令默认安装最新版本的<code>docker</code>.</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum install -y docker-ce docker-ce-cli containerd.io</span><br></pre></td></tr></table></figure><p>安装好docker之后可以使用查看docker版本。</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker version</span><br></pre></td></tr></table></figure><p>实例:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">[root@k8s-master-1 ~]# docker version</span><br><span class="line">Client: Docker Engine - Community</span><br><span class="line"> Version: 19.03.8</span><br><span class="line"> API version: 1.40</span><br><span class="line"> Go version: go1.12.17</span><br><span class="line"> Git commit: afacb8b</span><br><span class="line"> Built: Wed Mar 11 01:27:04 2020</span><br><span class="line"> OS/Arch: linux/amd64</span><br><span class="line"> Experimental: false</span><br><span class="line">Server: Docker Engine - Community</span><br><span class="line"> Engine:</span><br><span class="line"> Version: 19.03.8</span><br><span class="line"> API version: 1.40 (minimum version 1.12)</span><br><span class="line"> Go version: go1.12.17</span><br><span class="line"> Git commit: afacb8b</span><br><span class="line"> Built: Wed Mar 11 01:25:42 2020</span><br><span class="line"> OS/Arch: linux/amd64</span><br><span class="line"> Experimental: false</span><br><span class="line"> containerd:</span><br><span class="line"> Version: 1.2.13</span><br><span class="line"> GitCommit: 7ad184331fa3e55e52b890ea95e65ba581ae3429</span><br><span class="line"> runc:</span><br><span class="line"> Version: 1.0.0-rc10</span><br><span class="line"> GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd</span><br><span class="line"> docker-init:</span><br><span class="line"> Version: 0.18.0</span><br><span class="line"> GitCommit: fec3683</span><br><span class="line">[root@k8s-master-1 ~]#</span><br></pre></td></tr></table></figure><h5 id="3-修改每台机器的主机名称和hosts"><a href="#3-修改每台机器的主机名称和hosts" class="headerlink" title="3.修改每台机器的主机名称和hosts"></a>3.修改每台机器的主机名称和<code>hosts</code></h5><p>1).修改主机名称.</p><p>使用<code>vim</code>打开<code>/etc/hostname</code>文件.编辑成自己需要的主机名称修改保存即可.</p><p>2).修改每台机器的<code>hosts</code>文件 .</p><p>使用<code>vim</code>打开<code>/etc/hosts</code>文件.编辑文件写下如下内容:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">10.0.0.110 k8s-master-1</span><br><span class="line">10.0.0.111 k8s-node-1</span><br><span class="line">10.0.0.112 k8s-node-2</span><br></pre></td></tr></table></figure><h5 id="4-设置防火墙"><a href="#4-设置防火墙" class="headerlink" title="4.设置防火墙"></a>4.设置防火墙</h5><p>1). 如果是实验环境可以关闭防火墙.</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 关闭防火墙开机启动</span></span><br><span class="line">systemctl disable firewalld</span><br><span class="line"><span class="meta">#</span><span class="bash"> 停止防火墙</span></span><br><span class="line">systemctl stop firewalld</span><br></pre></td></tr></table></figure><p>2).如果是生产环境建议开启防火墙,对项目需要使用的所有端口开放即可。</p><p>开放端口的命令:</p> <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">firewall-cmd --zone=public --add-port=80/tcp --permanent</span><br></pre></td></tr></table></figure><blockquote><p><code>--zone</code> :作用域<br><code>--add-port=80/tcp</code> :添加端口,格式为:端口/通讯协议<br><code>--permanent</code> :永久生效,没有此参数重启后失效</p></blockquote><p>重启防火墙:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">firewall-cmd --reload</span><br></pre></td></tr></table></figure><p>5.修改每台机器的<code>docker</code> 仓库地址配置.</p><p>使用<code>vim</code>打开<code>/etc/docker/daemon.json</code> 文件.如果没有这个文件就新建一个.</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"> "registry-mirrors":[</span><br><span class="line"> "https://registry.docker-cn.com",</span><br><span class="line"> "https://kfwkfulq.mirror.aliyuncs.com",</span><br><span class="line"> "https://2lqq34jg.mirror.aliyuncs.com",</span><br><span class="line"> "https://pee6w651.mirror.aliyuncs.com",</span><br><span class="line"> "http://hub-mirror.c.163.com"</span><br><span class="line"> ],</span><br><span class="line"> "insecure-registries":["10.0.0.110:5000"],</span><br><span class="line"> "exec-opts":["native.cgroupdriver=systemd"]</span><br><span class="line">}</span><br></pre></td></tr></table></figure><blockquote><p>在<code>registry-mirrors</code> 中可以添加镜像源地址.</p><p><code>insecure-registries</code>:是自己的私有仓库地址.这个是自己提前确定好的地址. </p></blockquote><p>6.安装好后启动<code>docker</code>.</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 设置为开机启动</span></span><br><span class="line">systemctl enable docker</span><br><span class="line"><span class="meta">#</span><span class="bash"> 启动docker</span></span><br><span class="line">systemctl satrt docker</span><br><span class="line"><span class="meta">#</span><span class="bash"> 重启docker</span></span><br><span class="line">systemctl restart docker</span><br></pre></td></tr></table></figure><p>7.拉取镜像</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker pull registry:latest</span><br></pre></td></tr></table></figure><p>8.创建本地镜像仓库</p><p>1).首先在1号机器上面创建一个存放镜像的文件夹,来用做本地镜像仓库。</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mkdir /usr/local/docker_registry</span><br></pre></td></tr></table></figure><p>2).启动本地镜像仓库</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -d -p 5000:5000 --name=local_registry --restart=always -- privileged=true -v /usr/local/docker_registry:/var/lib/registry registry</span><br></pre></td></tr></table></figure><blockquote><p><code>-p 5000:5000</code>:端口 </p><p><code>--name=local_registry</code>:运行的容器名称 </p><p><code>--restart=always</code>:自动重启 :<code>centos7</code>中的安全模块 <code>selinux</code>把权限禁止了,加上这行是给容器增加执行权限.</p><p><code>-v /usr/local/docker_registry:/var/lib/registry</code>: 把的<code>/usr/local/docker_registry</code> :目录挂载到<code>registry</code>容器的<code>/var/lib/registry</code>目录下, 假如有删除容器操作,我们的镜像也不会被删除 </p><p><code>registry</code>: 镜像名称</p></blockquote><p><code>docker</code>常用基本操作:</p> <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 查看本地镜像:</span></span><br><span class="line">docker images</span><br><span class="line"><span class="meta">#</span><span class="bash"> 从远程镜像仓库下拉镜像源</span></span><br><span class="line">docker pull 镜像源名称</span><br><span class="line"><span class="meta">#</span><span class="bash">镜像搜索</span></span><br><span class="line">docker search nginx(镜像源名称)</span><br><span class="line"><span class="meta">#</span><span class="bash"> 运行镜像</span></span><br><span class="line">docker run -it(以交互的方式运行) python:3.6.4(镜像名称和版本号) python(在镜像内执行的命令)</span><br><span class="line"><span class="meta">#</span><span class="bash"> 停止容器</span></span><br><span class="line">docker stop 容器名称</span><br><span class="line"><span class="meta">#</span><span class="bash"> 重启容器</span></span><br><span class="line">docker restart 容器名称</span><br><span class="line"><span class="meta">#</span><span class="bash"> 启动容器</span></span><br><span class="line">docker start 容器名称</span><br><span class="line"><span class="meta">#</span><span class="bash"> 查看运行的容器</span></span><br><span class="line">docker ps -a</span><br><span class="line"><span class="meta">#</span><span class="bash"> 删除容器</span></span><br><span class="line">docker rm 容器名称</span><br><span class="line"><span class="meta">#</span><span class="bash"> 在容器中执行命令</span></span><br><span class="line">docker exec 命令</span><br><span class="line"><span class="meta">#</span><span class="bash"> 删除镜像</span></span><br><span class="line">docker rmi 镜像名称</span><br><span class="line"><span class="meta">#</span><span class="bash"> 提交镜像</span></span><br><span class="line">docker commit -m="xxx" -a="xxx" e218edb10161 centos7/centos7.3.8:v1</span><br><span class="line">-m: 提交的描述信息</span><br><span class="line">-a: 指定镜像作者</span><br><span class="line">e218edb10161:容器 ID</span><br><span class="line">centos7/centos7.3.8:v1: 指定要创建的目标镜像名和tag</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 杀死所有正在运行的容器</span></span><br><span class="line">docker kill $(docker ps -a -q)</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 删除所有已经停止的容器</span></span><br><span class="line">docker rm $(docker ps -a -q)</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 删除所有未打 dangling 标签的镜</span></span><br><span class="line">docker rmi $(docker images -q -f dangling=true)</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 删除所有镜像</span></span><br><span class="line">docker rmi $(docker images -q)</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 强制删除 无法删除的镜像</span></span><br><span class="line">docker rmi -f <IMAGE_ID></span><br><span class="line">docker rmi -f $(docker images -q)</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 杀死所有正在运行的容器.</span></span><br><span class="line">alias dockerkill='docker kill $(docker ps -a -q)'</span><br><span class="line"> </span><br><span class="line"><span class="meta">#</span><span class="bash"> 删除所有已经停止的容器.</span></span><br><span class="line">alias dockercleanc='docker rm $(docker ps -a -q)'</span><br><span class="line"> </span><br><span class="line"><span class="meta">#</span><span class="bash"> 删除所有未打标签的镜像.</span></span><br><span class="line">alias dockercleani='docker rmi $(docker images -q -f dangling=true)'</span><br><span class="line"> </span><br><span class="line"><span class="meta">#</span><span class="bash"> 删除所有已经停止的容器和未打标签的镜像.</span></span><br><span class="line">alias dockerclean='dockercleanc || true && dockercleani'</span><br></pre></td></tr></table></figure><h4 id="二、安装rancher"><a href="#二、安装rancher" class="headerlink" title="二、安装rancher"></a>二、安装<code>rancher</code></h4><p>1).拉取<code>rancher</code>镜像 我这里的版本的<code>2.3.6</code></p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker pull rancher/rancher:stable</span><br></pre></td></tr></table></figure><p>2).启动<code>rancher</code>.</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -d --restart=unless-stopped -p 80:80 -p 443:443 -v /docker_volume/rancher_home/rancher:/var/lib/rancher -v /docker_volume/rancher_home/auditlog:/var/log/auditlog --name rancher rancher/rancher:stable</span><br></pre></td></tr></table></figure><p>3).查看rancher是否启动.</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker ps -a</span><br></pre></td></tr></table></figure><p>示例:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[root@k8s-master-1 ~]# docker ps -a</span><br><span class="line">CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES</span><br><span class="line">a0e13ed8a7d3 rancher/rancher:stable "entrypoint.sh" 47 hours ago Up About an hour 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp rancher</span><br><span class="line">9181c2c1cdb0 registry "/entrypoint.sh /etc…" 2 days ago Up About an hour 0.0.0.0:5000->5000/tcp local_registry</span><br><span class="line">[root@k8s-master-1 ~]#</span><br></pre></td></tr></table></figure><p>状态是<code>Up</code>.说明就启动成功了.</p><p>就可以通过浏览器访问了 </p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://10.0.0.110</span><br></pre></td></tr></table></figure><p>会提示你设置密码。我这里都使用的是<code>admin</code>.</p><p>[这步可以不做,也可以提前做好,如果不拉取的话rancher安装的时候也会自动拉取相关镜像的,如果拉取了安装会快一些.]然后分别在2,3号机器上面拉取<code>rancher</code>相关镜像.如下图</p><p><img src="/2020/04/06/使用rancher2-3-6构建kubernets集群/1.png" alt="1"></p><p>4).使用rancher添加集群</p><p><img src="/2020/04/06/使用rancher2-3-6构建kubernets集群/2.png" alt="2"></p><p>根据自己的实际情况选择和填写相关信息.</p><p><img src="/2020/04/06/使用rancher2-3-6构建kubernets集群/3.png" alt="3"></p><p>点击下一步按照节点来购选:</p><p>master节点</p><p><img src="/2020/04/06/使用rancher2-3-6构建kubernets集群/4.png" alt="4"></p><p>node节点:</p><p><img src="/2020/04/06/使用rancher2-3-6构建kubernets集群/5.png" alt="5"></p><p>分别对应不同的节点拷贝不通的命令取对于的节点执行。执行后如果没有拉取上面的镜像就需要等待一段时间让集群启动起来。如果已经拉取了上面的镜像,应该很快就能够启动起来。集群启动成功后如下图:</p><p><img src="/2020/04/06/使用rancher2-3-6构建kubernets集群/6.png" alt="6"></p><p>查看</p><p><img src="/2020/04/06/使用rancher2-3-6构建kubernets集群/7.png" alt="7"></p><p>如果是下图这样的话:</p><p><img src="/2020/04/06/使用rancher2-3-6构建kubernets集群/8.png" alt="8"></p><p>这个样rancher添加集群就已经启动成功.</p><h4 id="三、安装过程问题解决"><a href="#三、安装过程问题解决" class="headerlink" title="三、安装过程问题解决"></a>三、安装过程问题解决</h4><p>1).安装过程中遇到了问题一,三个服务器时间不同步的问题。</p> <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[etcd] Failed to bring up Etcd Plane: [etcd] Etcd Cluster is not healthy</span><br></pre></td></tr></table></figure><p>需要在每台服务器上面安装一个服务器时间同步工具</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum install ntp ntpdate -y</span><br></pre></td></tr></table></figure><p>选择一台服务器作为时间同步服务器,我这里选择的是<code>10.0.0.110</code></p><p>使用<code>vim</code>打开<code>/etc/ntp.conf</code>文件</p><p>添加:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">restrict 10.0.0.0 mask 255.255.255.0 nomodify notrap</span><br><span class="line">server ntp3.aliyun.com iburst</span><br></pre></td></tr></table></figure><p>如下图:</p><p><img src="/2020/04/06/使用rancher2-3-6构建kubernets集群/9.png" alt="9"></p><p>其他服务器上面添加:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">server 10.0.0.110 prefer</span><br></pre></td></tr></table></figure><p><img src="/2020/04/06/使用rancher2-3-6构建kubernets集群/10.png" alt="10"></p><p>修改完成后,分别在每台服务器上面执行:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">systemctl restart ntpd</span><br><span class="line">systemctl disable chronyd.service</span><br><span class="line">chkconfig --level 345 ntpd on</span><br></pre></td></tr></table></figure><p>再在非 <code>10.0.0.110</code>的其他服务上面执行</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ntpq -p</span><br></pre></td></tr></table></figure><p>会看见如下所示的内容,说明成功了. </p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[root@k8s-node-1 ~]# ntpq -p</span><br><span class="line"> remote refid st t when poll reach delay offset jitter</span><br><span class="line">==============================================================================</span><br><span class="line">*k8s-master-1 203.107.6.88 3 u 3 512 377 0.555 -1.802 2.876</span><br><span class="line">[root@k8s-node-1 ~]#</span><br></pre></td></tr></table></figure><p>到此为止。在重新按照<code>[安装rancher]</code>的步骤重新安装就可以安装成功了。</p>]]></content>
</entry>
<entry>
<title>基于flask的restfulAPI项目实现</title>
<link href="/2019/10/27/%E5%9F%BA%E4%BA%8Eflask%E7%9A%84restfulAPI%E9%A1%B9%E7%9B%AE%E5%AE%9E%E7%8E%B0/"/>
<url>/2019/10/27/%E5%9F%BA%E4%BA%8Eflask%E7%9A%84restfulAPI%E9%A1%B9%E7%9B%AE%E5%AE%9E%E7%8E%B0/</url>
<content type="html"><![CDATA[<h4 id="基于flask的restfulAPI项目实现"><a href="#基于flask的restfulAPI项目实现" class="headerlink" title="基于flask的restfulAPI项目实现"></a>基于flask的restfulAPI项目实现</h4><p>了解到一段时间的restfulAPI实现,通用面向对象的用户、角色、权限管理的项目案例来阐述是如何实现restfulAPI接口的实现,今天有空来整理一下。</p><pre><code>项目中权限是参照标准的RBAC. 来实现,有良好的扩展性。数据库访问、业务层、接口层分离。保障了代码的可扩展性。基于面向对象的思想实现本项目。具体实现见下面介绍。</code></pre><h4 id="1、什么是restful?"><a href="#1、什么是restful?" class="headerlink" title="1、什么是restful?"></a>1、什么是restful?</h4><p>RESTFUL是一种网络应用程序的设计风格和开发方式,基于<a href="https://baike.baidu.com/item/HTTP/243074" target="_blank" rel="noopener">HTTP</a>,可以使用<a href="https://baike.baidu.com/item/XML/86251" target="_blank" rel="noopener">XML</a>格式定义或<a href="https://baike.baidu.com/item/JSON/2462549" target="_blank" rel="noopener">JSON</a>格式定义。RESTFUL适用于移动互联网厂商作为业务使能接口的场景,实现第三方<a href="https://baike.baidu.com/item/OTT/9960940" target="_blank" rel="noopener">OTT</a>调用移动网络资源的功能,动作类型为新增、变更、删除所调用资源。具体详细内容自行百度,并不是本文的重点。</p><p>RESTFUL特点包括:</p><p>1、每一个URI代表1种资源;</p><p>2、客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源;</p><p>3、通过操作资源的表现形式来操作资源;</p><p>4、资源的表现形式是XML或者HTML;</p><p>5、客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请求都必须包含理解请求所必需的信息。</p><blockquote><p> 本项目中主要使用的请求类型的定义:</p><p>GET: 获取资源信息</p><p>POST: 添加资源信息</p><p>PUT: 修改资源信息</p><p>DELETE: 删除资源信息</p></blockquote><h4 id="2、项目目录结构"><a href="#2、项目目录结构" class="headerlink" title="2、项目目录结构"></a>2、项目目录结构</h4><p><img src="/2019/10/27/基于flask的restfulAPI项目实现/3.png" alt="3"></p><h4 id="3、项目架构图"><a href="#3、项目架构图" class="headerlink" title="3、项目架构图"></a>3、项目架构图</h4><p><img src="/2019/10/27/基于flask的restfulAPI项目实现/1.png" alt="1"></p><h4 id="4、项目数据库设计图"><a href="#4、项目数据库设计图" class="headerlink" title="4、项目数据库设计图"></a>4、项目数据库设计图</h4><p><img src="/2019/10/27/基于flask的restfulAPI项目实现/2.png" alt="2"></p><h4 id="5、项目具体介绍"><a href="#5、项目具体介绍" class="headerlink" title="5、项目具体介绍"></a>5、项目具体介绍</h4><h5 id="5-1-项目URi-定义"><a href="#5-1-项目URi-定义" class="headerlink" title="5.1 项目URi 定义"></a>5.1 项目URi 定义</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"># 部门管理</span><br><span class="line">'/li-boss/<version>/department',</span><br><span class="line">'/li-boss/<version>/department/<int:dpt_id>'</span><br><span class="line"></span><br><span class="line"># 部门人员</span><br><span class="line">'/li-boss/<version>/department/staff/<int:dpt_id>'</span><br><span class="line"></span><br><span class="line"># 用户</span><br><span class="line">'/li-boss/<version>/user',</span><br><span class="line">'/li-boss/<version>/user/<int:user_id>',</span><br><span class="line"></span><br><span class="line"># 密码</span><br><span class="line">'/li-boss/<version>/user/<int:user_id>/password'</span><br><span class="line"></span><br><span class="line"># 基本信息修改</span><br><span class="line">'/li-boss/<version>/user/<int:user_id>/base/info'</span><br><span class="line"></span><br><span class="line"># 角色</span><br><span class="line">'/li-boss/<version>/role',</span><br><span class="line">'/li-boss/<version>/role/<int:role_id>'</span><br><span class="line"></span><br><span class="line"># 角色权限</span><br><span class="line">'/li-boss/<version>/role/<role_id>/permission'</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># 权限</span><br><span class="line">'/li-boss/<version>/permission'</span><br><span class="line"></span><br><span class="line"># 用户组</span><br><span class="line">'/li-boss/<version>/user/group',</span><br><span class="line">'/li-boss/<version>/user/group/<int:group_id>'</span><br><span class="line"></span><br><span class="line"># 用户组成员</span><br><span class="line">'/li-boss/<version>/user/group/<int:group_id>/staff'</span><br><span class="line"></span><br><span class="line"># 获取用户组的角色信息</span><br><span class="line">'/li-boss/<version>/user/group/<int:group_id>/role'</span><br><span class="line"></span><br><span class="line"># 登陆</span><br><span class="line">'/li-boss/<version>/login'</span><br></pre></td></tr></table></figure><h5 id="5-2-项目请求和响应"><a href="#5-2-项目请求和响应" class="headerlink" title="5.2 项目请求和响应"></a>5.2 项目请求和响应</h5><p> 本项目支持两种数据请求和响应格式。分别是的<code>JSON</code>和<code>XML</code>.如果需要使用<code>XML</code>请求的话需要在URL后面加上 <code>?format=xml</code>.就可以正常的获取到<code>XML</code>格式的数据。</p><h5 id="5-3-请求示例"><a href="#5-3-请求示例" class="headerlink" title="5.3 请求示例"></a>5.3 请求示例</h5><p><code>JSON</code></p><p>这是一个<code>json</code>请求不需要代<code>token</code>的时候的示例:</p><p><img src="/2019/10/27/基于flask的restfulAPI项目实现/4.png" alt="4"></p><p>加了验证的需要选择<code>Bearer Token</code> 验证模式。这是一个<code>JSON</code>需要带<code>token</code>验证的请求示例:</p><p><img src="/2019/10/27/基于flask的restfulAPI项目实现/6.png" alt="6"></p><p><code>XML</code></p><p>这是一个<code>XML</code>请求不需要代<code>token</code>的时候的示例:</p><p><img src="/2019/10/27/基于flask的restfulAPI项目实现/5.png" alt="5"></p><p>加了验证的需要选择<code>Bearer Token</code> 验证模式。这是一个<code>XML</code>需要带<code>token</code>验证的请求示例:</p><p><img src="/2019/10/27/基于flask的restfulAPI项目实现/7.png" alt="7"></p><h4 id="6-具体代码实现"><a href="#6-具体代码实现" class="headerlink" title="6. 具体代码实现"></a>6. 具体代码实现</h4><p>由于本项目代码内容比较多我就不贴代码到这个位置了。详细代码地址放github上面了。<a href="https://github.com/kujirashark/user_restful_api" target="_blank" rel="noopener">项目地址</a></p><p>自己总计的一些开发经验,与大家分享,如果觉得有用不忘收藏。</p><h4 id=""><a href="#" class="headerlink" title=" "></a> </h4>]]></content>
</entry>
<entry>
<title>Flask-APScheduler使用教程</title>
<link href="/2019/05/09/Flask-APScheduler%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B/"/>
<url>/2019/05/09/Flask-APScheduler%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B/</url>
<content type="html"><![CDATA[<h4 id="Flask-APScheduler使用教程"><a href="#Flask-APScheduler使用教程" class="headerlink" title="Flask-APScheduler使用教程"></a>Flask-APScheduler使用教程</h4><blockquote><p>作者:lizhonglin<br>github: <a href="https://github.com/kujirashark/" target="_blank" rel="noopener">https://github.com/kujirashark/</a><br>blog: <a href="https://kujirashark.github.io/" target="_blank" rel="noopener">https://kujirashark.github.io/</a></p></blockquote><p>APScheduler是一个Python库,可让您安排稍后执行的Python代码,是一套任务调度框架,可以用来做定时任务控制器,可以添加删除任务。如果将作业存储在数据库中,它们也将在调度程序重新启动后继续运行并保持其状态。重新启动调度程序后,它将运行它应该在脱机时运行的所有作业。</p><p>除此之外,APScheduler还可以用作特定于平台的调度程序(如cron守护程序或Windows任务调度程序)的跨平台,特定于应用程序的替代程序。但请注意,APScheduler本身<strong>不是</strong>守护程序或服务,也不附带任何命令行工具。它主要用于在现有应用程序中运行。也就是说,APScheduler确实为您提供了一些构建块来构建调度程序服务或运行专用的调度程序进程。</p><p>APScheduler有三个可以使用的内置调度系统:</p><ul><li>Cron式调度(可选的开始/结束时间)</li><li>基于区间的执行(偶数间隔运行作业,可选的开始/结束时间)</li><li>一次性延迟执行(在设定的日期/时间运行一次作业)</li></ul><p><code>APScheduler</code>是一个python的第三方库,用来提供python的后台程序。包含四个组件,分别是:</p><ul><li>triggers: 任务触发器组件,提供任务触发方式</li><li>job stores: 任务商店组件,提供任务保存方式</li><li>executors: 任务调度组件,提供任务调度方式</li><li>schedulers: 任务调度组件,提供任务工作方式</li></ul><p>具体内容如下:</p><p><strong>triggers:</strong> 支持三种任务触发方式</p><ul><li><p>date:固定日期触发器,任务只运行一次,运行完毕自动清除;若错过指定运行时间,任务不会被创建</p><p>| 参数 | 说明 |<br>| :——————————– | :——————- |<br>| run_date (datetime 或 str) | 作业的运行日期或时间 |<br>| timezone (datetime.tzinfo 或 str) | 指定时区 |</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">例如# 在 2019-4-24 00:00:01 时刻运行一次 start_system 方法</span><br><span class="line">scheduler .add_job(start_system, 'date', run_date='2019-4-24 00:00:01', args=['text'])</span><br></pre></td></tr></table></figure></li></ul><ul><li><p>interval:时间间隔触发器,每个一定时间间隔执行一次。</p><p>| 参数 | 说明 |<br>| —————————- | ———- |<br>| weeks (int) | 间隔几周 |<br>| days (int) | 间隔几天 |<br>| hours (int) | 间隔几小时 |<br>| minutes (int) | 间隔几分钟 |<br>| seconds (int) | 间隔多少秒 |<br>| start_date (datetime 或 str) | 开始日期 |<br>| end_date (datetime 或 str) | 结束日期 |</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># 在 2019-4-24 00:00:00 - 2019-4-24 08:00:00 之间, 每隔两小时执行一次 alarm_job 方法</span><br><span class="line">scheduler .add_job(alarm_job, 'interval', hours=2, start_date='2019-4-24 00:00:00' , end_date='2019-4-24 08:00:00')</span><br></pre></td></tr></table></figure></li></ul><ul><li>cron:cron风格的任务触发</li></ul><table><thead><tr><th>参数</th><th>说明</th></tr></thead><tbody><tr><td>year (int 或 str)</td><td>表示四位数的年份 (2019)</td></tr><tr><td>month(int\</td><td>str)</td><td>月 (范围1-12)</td></tr><tr><td>day(int\</td><td>str)</td><td>日 (范围1-31)</td></tr><tr><td>week(int\</td><td>str)</td><td>周 (范围1-53)</td></tr><tr><td>day_of_week (int\</td><td>str)</td><td>表示一周中的第几天,既可以用0-6表示也可以用其英语缩写表示</td></tr><tr><td>hour (int\</td><td>str)</td><td>表示取值范围为0-23时</td></tr><tr><td>minute (int\</td><td>str)</td><td>表示取值范围为0-59分</td></tr><tr><td>second (int\</td><td>str)</td><td>表示取值范围为0-59秒</td></tr><tr><td>start_date (datetime\</td><td>str)</td><td>表示开始时间</td></tr><tr><td>end_date (datetime\</td><td>str)</td><td>表示结束时间</td></tr><tr><td>timezone (datetime.tzinfo\</td><td>str)</td><td>表示时区取值</td></tr></tbody></table><blockquote><p>(<code>int</code>|<code>str</code>) 表示参数既可以是<code>int</code>类型,也可以是<code>str</code>类型<br>(datetime | <code>str</code>) 表示参数既可以是datetime类型,也可以是<code>str</code>类型</p></blockquote><p> 例如:表示每5秒执行该程序一次,相当于interval 间隔调度中seconds = 5</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sched.add_job(my_job, 'cron',second = '*/5')</span><br></pre></td></tr></table></figure><p><strong>job stores:</strong> 支持四种任务存储方式</p><ul><li>memory:默认配置任务存在内存中</li><li>mongdb:支持文档数据库存储</li><li>sqlalchemy:支持关系数据库存储</li><li>redis:支持键值对数据库存储</li></ul><p><strong>schedulers:</strong> 调度器主要分三种,一种独立运行的,一种是后台运行的,最后一种是配合其它程序使用</p><ul><li>BlockingScheduler: 当这个调度器是你应用中 <code>唯一要运行</code> 的东西时使用</li><li>BackgroundScheduler: 当 <code>不运行其它框架</code> 的时候使用,并使你的任务在 <code>后台运行</code></li><li>AsyncIOScheduler: 当你的程序是 <code>异步IO模型</code> 的时候使用</li><li>GeventScheduler: 和 <code>gevent</code> 框架配套使用</li><li>TornadoScheduler: 和 <code>tornado</code> 框架配套使用</li><li>TwistedScheduler: 和 <code>Twisted</code> 框架配套使用</li><li>QtScheduler: 开发 <code>qt</code> 应用的时候使用</li></ul><h5 id="1-安装"><a href="#1-安装" class="headerlink" title="1.安装"></a>1.安装</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install Flask-APScheduler</span><br></pre></td></tr></table></figure><h5 id="2-在flask中使用调度器"><a href="#2-在flask中使用调度器" class="headerlink" title="2.在flask中使用调度器"></a>2.在flask中使用调度器</h5><p>首先在flask的create_app函数中创建最初的调度器</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> apscheduler.triggers.interval <span class="keyword">import</span> IntervalTrigger</span><br><span class="line"></span><br><span class="line"><span class="comment">###此方法负责初始化app</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">create_app</span><span class="params">(config_name)</span>:</span></span><br><span class="line"> app=Flask(__name__)</span><br><span class="line"> CORS(app)</span><br><span class="line"> app.config.from_object(config[config_name])</span><br><span class="line"> config[config_name].init_app(app)</span><br><span class="line"> <span class="comment">###初始化数据库</span></span><br><span class="line"> db.init_app(app)</span><br><span class="line"><span class="comment">#####################################################上面代码忽略</span></span><br><span class="line"> <span class="comment"># 这里是重点 </span></span><br><span class="line"> <span class="comment"># 初始化备份数据库定时器</span></span><br><span class="line"> scheduler.init_app(app)</span><br><span class="line"> <span class="comment"># # 解决FLASK DEBUG模式定时任务执行两次</span></span><br><span class="line"> <span class="keyword">if</span> os.environ.get(<span class="string">'WERKZEUG_RUN_MAIN'</span>) == <span class="string">'true'</span>:</span><br><span class="line"> scheduler.api_enabled = <span class="keyword">True</span></span><br><span class="line"> scheduler.init_app(app)</span><br><span class="line"><span class="comment"># 实例话interval对象,如果不实例话的话有可能会报错没有interval这个</span></span><br><span class="line"> interval = IntervalTrigger(</span><br><span class="line"> days = <span class="number">2</span>,</span><br><span class="line"> start_date=<span class="string">'2019-4-24 08:00:00'</span>,</span><br><span class="line"> end_date=<span class="string">'2099-4-24 08:00:00'</span>,</span><br><span class="line"> timezone=<span class="string">'Asia/Shanghai'</span>)</span><br><span class="line"> <span class="comment"># dbDump 是一个备份数据库的函数,这个根据自己的实际情况来看</span></span><br><span class="line"> scheduler.add_job(func=dbDump,trigger=interval,id=<span class="string">'bak_one'</span>)</span><br><span class="line"> scheduler.start()</span><br><span class="line"><span class="comment">######################################################下面代码忽略</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">###初始化上传下载和导出目录</span></span><br><span class="line"> <span class="comment"># init_static_path()</span></span><br><span class="line"> <span class="comment">###注册蓝图</span></span><br><span class="line"> register_app(app)</span><br><span class="line"> <span class="comment"># ###初始化日志</span></span><br><span class="line"> init_log()</span><br><span class="line"> <span class="keyword">return</span> app</span><br></pre></td></tr></table></figure><p>如果需要重新替换上面的任务可以在任务中多添加一个参数<code>replace_existing=True</code>由上面的两天备份一次 变成每天备份一次。配置成功后他会自动去替换上面的定时器。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"> <span class="comment"># 判断配置文件变化 更新定时任务</span></span><br><span class="line"><span class="keyword">if</span> os.environ.get(<span class="string">'WERKZEUG_RUN_MAIN'</span>) == <span class="string">'true'</span>:</span><br><span class="line">interval = IntervalTrigger(</span><br><span class="line"> days=<span class="number">1</span>,</span><br><span class="line"> start_date=<span class="string">'2019-4-24 08:00:00'</span>,</span><br><span class="line"> end_date=<span class="string">'2099-4-24 08:00:00'</span>,</span><br><span class="line"> timezone=<span class="string">'Asia/Shanghai'</span>)</span><br><span class="line">scheduler.add_job(</span><br><span class="line"> func=dbDump,</span><br><span class="line">trigger=interval,</span><br><span class="line">id=<span class="string">'bak_one'</span>, </span><br><span class="line">replace_existing=<span class="keyword">True</span>)</span><br></pre></td></tr></table></figure><blockquote><p>replace_existing=True 这个参数非常重要,在这个地方弄了很久,开始一直不能替换第一次任务。</p></blockquote><p>问题解决:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">scheduler.add_job(dbDump,'interval',id='bak_one',days=1,start_date='2019-4-24 08:00:00',end_date='2099-4-24 08:00:00',replace_existing=True)</span><br></pre></td></tr></table></figure><p>如果是按照上面创建的任务的话在使用pyinstaller打包生成的可执行文件,运行的时候会出现如下面的问题</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">APScheduler: LookupError: No trigger by the name “interval” was found</span><br></pre></td></tr></table></figure><p>解决方案是:替换成我上面的方式去创建任务就可以解决的。</p>]]></content>
</entry>
<entry>
<title>python中pyinstaller库的使用</title>
<link href="/2018/11/09/python%E4%B8%ADpyinstaller%E5%BA%93%E7%9A%84%E4%BD%BF%E7%94%A8/"/>
<url>/2018/11/09/python%E4%B8%ADpyinstaller%E5%BA%93%E7%9A%84%E4%BD%BF%E7%94%A8/</url>
<content type="html"><![CDATA[<p>使用pyinstaller打包python程序为exe文件</p><p>安装pyinstaller库</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install pyinstaller</span><br></pre></td></tr></table></figure><p>拿一个我以前写过的简单项目来测试打包</p><p>以前的项目结构如下</p><p><img src="/2018/11/09/python中pyinstaller库的使用/2.png" alt="2"></p><p>安装完成之后看到如下界面</p><p><img src="/2018/11/09/python中pyinstaller库的使用/1.png" alt="1"></p><p>在虚拟环境下面运行如下命令</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">(axfenv) lizhonglindeMacBook-Pro:stuflask lizhonglin$ pyinstaller -F manage.py</span><br></pre></td></tr></table></figure><p>会得到如下结果就说明打包成功</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br></pre></td><td class="code"><pre><span class="line">(axfenv) lizhonglindeMacBook-Pro:stuflask lizhonglin$ pyinstaller -F manage.py </span><br><span class="line">48 INFO: PyInstaller: 3.4</span><br><span class="line">48 INFO: Python: 3.6.5</span><br><span class="line">63 INFO: Platform: Darwin-16.7.0-x86_64-i386-64bit</span><br><span class="line">64 INFO: wrote /Users/lizhonglin/Desktop/stuflask/manage.spec</span><br><span class="line">67 INFO: UPX is not available.</span><br><span class="line">69 INFO: Extending PYTHONPATH with paths</span><br><span class="line">['/Users/lizhonglin/Desktop/stuflask', '/Users/lizhonglin/Desktop/stuflask']</span><br><span class="line">69 INFO: checking Analysis</span><br><span class="line">69 INFO: Building Analysis because Analysis-00.toc is non existent</span><br><span class="line">69 INFO: Initializing module dependency graph...</span><br><span class="line">71 INFO: Initializing module graph hooks...</span><br><span class="line">72 INFO: Analyzing base_library.zip ...</span><br><span class="line">3562 INFO: running Analysis Analysis-00.toc</span><br><span class="line">3574 INFO: Caching module hooks...</span><br><span class="line">3579 INFO: Analyzing /Users/lizhonglin/Desktop/stuflask/manage.py</span><br><span class="line">4249 INFO: Processing pre-find module path hook distutils</span><br><span class="line">4249 INFO: distutils: retargeting to non-venv dir '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/distutils'</span><br><span class="line">7924 INFO: Processing pre-safe import module hook six.moves</span><br><span class="line">10606 INFO: Processing pre-find module path hook site</span><br><span class="line">10607 INFO: site: retargeting to fake-dir '/Users/lizhonglin/Desktop/Code/axfenv/lib/python3.6/site-packages/PyInstaller/fake-modules'</span><br><span class="line">14279 INFO: Loading module hooks...</span><br><span class="line">14279 INFO: Loading module hook "hook-_tkinter.py"...</span><br><span class="line">14289 INFO: checking Tree</span><br><span class="line">14289 INFO: Building Tree because Tree-00.toc is non existent</span><br><span class="line">14289 INFO: Building Tree Tree-00.toc</span><br><span class="line">14314 INFO: checking Tree</span><br><span class="line">14314 INFO: Building Tree because Tree-01.toc is non existent</span><br><span class="line">14314 INFO: Building Tree Tree-01.toc</span><br><span class="line">14326 INFO: Loading module hook "hook-distutils.py"...</span><br><span class="line">14328 INFO: Loading module hook "hook-encodings.py"...</span><br><span class="line">14412 INFO: Loading module hook "hook-IPython.py"...</span><br><span class="line">14421 INFO: Excluding import 'matplotlib'</span><br><span class="line">14426 INFO: Removing import of matplotlib from module IPython.core.pylabtools</span><br><span class="line">14428 INFO: Import to be excluded not found: 'PyQt4'</span><br><span class="line">14428 INFO: Import to be excluded not found: 'PyQt5'</span><br><span class="line">14428 INFO: Excluding import 'tkinter'</span><br><span class="line">14432 INFO: Removing import of tkinter from module IPython.lib.clipboard</span><br><span class="line">14434 INFO: Import to be excluded not found: 'gtk'</span><br><span class="line">14434 INFO: Import to be excluded not found: 'PySide'</span><br><span class="line">14434 INFO: Loading module hook "hook-jedi.py"...</span><br><span class="line">14436 INFO: Loading module hook "hook-jinja2.py"...</span><br><span class="line">14463 INFO: Loading module hook "hook-pkg_resources.py"...</span><br><span class="line">15022 INFO: Processing pre-safe import module hook win32com</span><br><span class="line">15023 INFO: Loading module hook "hook-pydoc.py"...</span><br><span class="line">15024 INFO: Loading module hook "hook-pygments.py"...</span><br><span class="line">17298 INFO: Loading module hook "hook-sqlalchemy.py"...</span><br><span class="line">17485 INFO: Found 6 sqlalchemy hidden imports</span><br><span class="line">17486 WARNING: Hidden import "MySQLdb" not found!</span><br><span class="line">17517 WARNING: Hidden import "sqlalchemy.orm.state", "sqlalchemy.orm.strategies" not found!</span><br><span class="line">17518 WARNING: Hidden import "sqlalchemy.sql.functions.func" not found!</span><br><span class="line">17523 INFO: Excluding import 'sqlalchemy.testing'</span><br><span class="line">17527 INFO: Removing import of sqlalchemy.testing.util from module sqlalchemy.orm.util</span><br><span class="line">17528 INFO: Removing import of sqlalchemy.testing from module sqlalchemy.testing</span><br><span class="line">17528 INFO: Removing import of sqlalchemy.testing.engines from module sqlalchemy.testing</span><br><span class="line">17528 INFO: Removing import of sqlalchemy.testing.exclusions from module sqlalchemy.testing</span><br><span class="line">17528 INFO: Removing import of sqlalchemy.testing.util from module sqlalchemy.testing</span><br><span class="line">17528 INFO: Removing import of sqlalchemy.testing.warnings from module sqlalchemy.testing</span><br><span class="line">17528 INFO: Removing import of sqlalchemy.testing.config from module sqlalchemy.testing</span><br><span class="line">17528 INFO: Removing import of sqlalchemy.testing.mock from module sqlalchemy.testing</span><br><span class="line">17528 INFO: Removing import of sqlalchemy.testing.assertions from module sqlalchemy.testing</span><br><span class="line">17529 INFO: Removing import of sqlalchemy.testing.assertsql from module sqlalchemy.testing</span><br><span class="line">17529 INFO: Removing import of sqlalchemy.testing from module sqlalchemy.testing.warnings</span><br><span class="line">17529 INFO: Removing import of sqlalchemy.testing.assertions from module sqlalchemy.testing.warnings</span><br><span class="line">17529 INFO: Removing import of sqlalchemy.testing from module sqlalchemy.testing.assertions</span><br><span class="line">17529 INFO: Removing import of sqlalchemy.testing.exclusions from module sqlalchemy.testing.assertions</span><br><span class="line">17529 INFO: Removing import of sqlalchemy.testing.util from module sqlalchemy.testing.assertions</span><br><span class="line">17529 INFO: Removing import of sqlalchemy.testing.mock from module sqlalchemy.testing.assertions</span><br><span class="line">17529 INFO: Removing import of sqlalchemy.testing.config from module sqlalchemy.testing.assertions</span><br><span class="line">17529 INFO: Removing import of sqlalchemy.testing.assertsql from module sqlalchemy.testing.assertions</span><br><span class="line">17529 INFO: Removing import of sqlalchemy.testing from module sqlalchemy.testing.util</span><br><span class="line">17529 INFO: Removing import of sqlalchemy.testing.engines from module sqlalchemy.testing.util</span><br><span class="line">17529 INFO: Removing import of sqlalchemy.testing.config from module sqlalchemy.testing.util</span><br><span class="line">17529 INFO: Removing import of sqlalchemy.testing from module sqlalchemy.testing.config</span><br><span class="line">17530 INFO: Removing import of sqlalchemy.testing from module sqlalchemy.testing.engines</span><br><span class="line">17530 INFO: Removing import of sqlalchemy.testing.assertions from module sqlalchemy.testing.engines</span><br><span class="line">17530 INFO: Removing import of sqlalchemy.testing.util from module sqlalchemy.testing.engines</span><br><span class="line">17530 INFO: Removing import of sqlalchemy.testing.config from module sqlalchemy.testing.engines</span><br><span class="line">17532 INFO: Removing import of sqlalchemy.testing from module sqlalchemy.testing.exclusions</span><br><span class="line">17532 INFO: Removing import of sqlalchemy.testing.config from module sqlalchemy.testing.exclusions</span><br><span class="line">17532 INFO: Removing import of sqlalchemy.testing from module sqlalchemy.testing.assertsql</span><br><span class="line">17532 INFO: Removing import of sqlalchemy.testing from module sqlalchemy.testing.mock</span><br><span class="line">17533 INFO: Loading module hook "hook-sqlite3.py"...</span><br><span class="line">17622 INFO: Loading module hook "hook-sysconfig.py"...</span><br><span class="line">17632 INFO: Loading module hook "hook-xml.dom.domreg.py"...</span><br><span class="line">17632 INFO: Loading module hook "hook-xml.py"...</span><br><span class="line">17633 INFO: Loading module hook "hook-PIL.Image.py"...</span><br><span class="line">17971 INFO: Loading module hook "hook-PIL.py"...</span><br><span class="line">17977 INFO: Excluding import 'PyQt4'</span><br><span class="line">17980 INFO: Removing import of PyQt4 from module PIL.ImageQt</span><br><span class="line">17981 INFO: Excluding import 'PyQt5'</span><br><span class="line">17984 INFO: Removing import of PyQt5 from module PIL.ImageQt</span><br><span class="line">17986 INFO: Excluding import 'tkinter'</span><br><span class="line">17991 INFO: Removing import of tkinter from module PIL.ImageTk</span><br><span class="line">17991 INFO: Import to be excluded not found: 'FixTk'</span><br><span class="line">17991 INFO: Excluding import 'PySide'</span><br><span class="line">17994 INFO: Removing import of PySide from module PIL.ImageQt</span><br><span class="line">17995 INFO: Loading module hook "hook-PIL.SpiderImagePlugin.py"...</span><br><span class="line">17997 INFO: Excluding import 'tkinter'</span><br><span class="line">17999 INFO: Import to be excluded not found: 'FixTk'</span><br><span class="line">18058 INFO: Looking for ctypes DLLs</span><br><span class="line">18108 WARNING: library ktmw32.dll required via ctypes not found</span><br><span class="line">18114 INFO: Analyzing run-time hooks ...</span><br><span class="line">18126 INFO: Including run-time hook 'pyi_rth_pkgres.py'</span><br><span class="line">18127 INFO: Including run-time hook 'pyi_rth_multiprocessing.py'</span><br><span class="line">18131 INFO: Including run-time hook 'pyi_rth_traitlets.py'</span><br><span class="line">18159 INFO: Looking for dynamic libraries</span><br><span class="line">18707 INFO: Looking for eggs</span><br><span class="line">18707 INFO: Using Python library /Users/lizhonglin/Desktop/Code/axfenv/bin/../.Python</span><br><span class="line">18720 INFO: Warnings written to /Users/lizhonglin/Desktop/stuflask/build/manage/warn-manage.txt</span><br><span class="line">18851 INFO: Graph cross-reference written to /Users/lizhonglin/Desktop/stuflask/build/manage/xref-manage.html</span><br><span class="line">18914 INFO: checking PYZ</span><br><span class="line">18914 INFO: Building PYZ because PYZ-00.toc is non existent</span><br><span class="line">18914 INFO: Building PYZ (ZlibArchive) /Users/lizhonglin/Desktop/stuflask/build/manage/PYZ-00.pyz</span><br><span class="line">20558 INFO: Building PYZ (ZlibArchive) /Users/lizhonglin/Desktop/stuflask/build/manage/PYZ-00.pyz completed successfully.</span><br><span class="line">20600 INFO: checking PKG</span><br><span class="line">20601 INFO: Building PKG because PKG-00.toc is non existent</span><br><span class="line">20601 INFO: Building PKG (CArchive) PKG-00.pkg</span><br><span class="line">27758 INFO: Building PKG (CArchive) PKG-00.pkg completed successfully.</span><br><span class="line">27763 INFO: Bootloader /Users/lizhonglin/Desktop/Code/axfenv/lib/python3.6/site-packages/PyInstaller/bootloader/Darwin-64bit/run</span><br><span class="line">27763 INFO: checking EXE</span><br><span class="line">27763 INFO: Building EXE because EXE-00.toc is non existent</span><br><span class="line">27763 INFO: Building EXE from EXE-00.toc</span><br><span class="line">27763 INFO: Appending archive to EXE /Users/lizhonglin/Desktop/stuflask/dist/manage</span><br><span class="line">27794 INFO: Fixing EXE for code signing /Users/lizhonglin/Desktop/stuflask/dist/manage</span><br><span class="line">27797 INFO: Building EXE from EXE-00.toc completed successfully.</span><br><span class="line">(axfenv) lizhonglindeMacBook-Pro:stuflask lizhonglin$</span><br></pre></td></tr></table></figure><p>打包完成后项目的文件夹下面就多了两个文件夹和一个文件</p><blockquote><p>如果想要给打包后的exe文件添加一个图标在打包的时候需要输入如下命令</p></blockquote><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pyinstaller -F -i b.ico 打包的文件.py</span><br></pre></td></tr></table></figure><p><img src="/2018/11/09/python中pyinstaller库的使用/3.png" alt="3"></p><p>在dist目录就有打包好的manage.exe可执行程序了。</p><p>在windows中双击就可以运行后端程序了。启动后的效果</p><p><img src="/2018/11/09/python中pyinstaller库的使用/4.png" alt="4"></p><p>原创出品,喜欢可以收藏转载哦!!!</p><blockquote><p>作者:lizhonglin</p><p><strong>github:</strong> <a href="https://github.com/kujirashark/" target="_blank" rel="noopener">https://github.com/kujirashark/</a></p><p><strong>blog:</strong> <a href="https://kujirashark.github.io/" target="_blank" rel="noopener">https://kujirashark.github.io/</a></p></blockquote>]]></content>
<tags>
<tag> pyinstaller库的使用 </tag>
</tags>
</entry>
<entry>
<title>nginx+uwsgi或nginx+python中manage部署多个网站</title>
<link href="/2018/11/09/nginx-uwsgi%E6%88%96nginx-python%E4%B8%ADmanage%E9%83%A8%E7%BD%B2%E5%A4%9A%E4%B8%AA%E7%BD%91%E7%AB%99/"/>
<url>/2018/11/09/nginx-uwsgi%E6%88%96nginx-python%E4%B8%ADmanage%E9%83%A8%E7%BD%B2%E5%A4%9A%E4%B8%AA%E7%BD%91%E7%AB%99/</url>
<content type="html"><![CDATA[<p>现在遇到一个问题自己有两个网站需要发布,但是自己只有一台服务器,想要发布两个网站。自己研究了两种方案。</p><p>一个服务器部署多个网站。</p><h5 id="方案一:不推荐"><a href="#方案一:不推荐" class="headerlink" title="方案一:不推荐"></a>方案一:不推荐</h5><h5 id="1、blog-网站"><a href="#1、blog-网站" class="headerlink" title="1、blog 网站"></a>1、blog 网站</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">使用python虚拟环境进入/home/code/blog_web目录</span><br><span class="line">使用python manage.py 启动项目</span><br></pre></td></tr></table></figure><h5 id="2、学习-网站"><a href="#2、学习-网站" class="headerlink" title="2、学习 网站"></a>2、学习 网站</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">使用python虚拟环境进入/home/code/study_web目录</span><br><span class="line">使用python manage.py 启动项目</span><br></pre></td></tr></table></figure><h5 id="3、启动nginx"><a href="#3、启动nginx" class="headerlink" title="3、启动nginx"></a>3、启动nginx</h5><blockquote><p>注: </p><p>Debian系统需要编译安装nginx</p><p>下面的命令是Debian系统的启动命令</p></blockquote><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">启动 nginx </span><br><span class="line">关闭 nginx -s stop</span><br></pre></td></tr></table></figure><p>centos的启动命令是</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">systemctl start nginx 启动</span><br><span class="line">systemctl stop nginx 停止</span><br><span class="line">systemctl restart nginx 重启</span><br><span class="line">systemctl status nginx 查看nginx状态</span><br></pre></td></tr></table></figure><h5 id="4、nginx配置"><a href="#4、nginx配置" class="headerlink" title="4、nginx配置"></a>4、nginx配置</h5><p>单独启动两个网站使用 python manage.py文件</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">#网站1端口转发</span><br><span class="line">server {</span><br><span class="line"> listen 80;</span><br><span class="line"> server_name www.blog.com;</span><br><span class="line"> access_log /home/code/blog_web/logs/blog_web.log;</span><br><span class="line"> error_log /home/code/blog_web/logs/blog_web.error;</span><br><span class="line"> </span><br><span class="line"> #将所有请求转发给demo_pool池的应用处理</span><br><span class="line"> location / {</span><br><span class="line"> proxy_set_header Host $host;</span><br><span class="line"> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</span><br><span class="line"> proxy_pass http://127.0.0.1:8000;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">#网站2端口转发</span><br><span class="line">server {</span><br><span class="line"> listen 80;</span><br><span class="line"> server_name www.study.com;</span><br><span class="line"> access_log /home/code/study_web/logs/study_web.log;</span><br><span class="line"> error_log /home/code/study_web/logs/study_web.error;</span><br><span class="line"> </span><br><span class="line"> #将所有请求转发给demo_pool池的应用处理</span><br><span class="line"> location / {</span><br><span class="line"> proxy_set_header Host $host;</span><br><span class="line"> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</span><br><span class="line"> proxy_pass http://127.0.0.1:8001;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这个需要在后台一直运行的话可以使用linux自带的nohup命令 到有manage.py文件夹下面运行:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nohup python manage.py &</span><br></pre></td></tr></table></figure><p>不推荐这种方案。</p><h5 id="方案二:推荐"><a href="#方案二:推荐" class="headerlink" title="方案二:推荐"></a>方案二:推荐</h5><h5 id="1、nginx配合uwsgi的配置"><a href="#1、nginx配合uwsgi的配置" class="headerlink" title="1、nginx配合uwsgi的配置"></a>1、nginx配合uwsgi的配置</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line">#网站一端口转发</span><br><span class="line">server {</span><br><span class="line"> listen 80; </span><br><span class="line"> server_name www.blog.com;</span><br><span class="line"> access_log /home/code/blog_web/logs/blog_web.log;</span><br><span class="line"> error_log /home/code/blog_web/logs/blog_web.error;</span><br><span class="line"> </span><br><span class="line"> #将所有请求转发给demo_pool池的应用处理</span><br><span class="line"> location / { </span><br><span class="line"> include uwsgi_params;</span><br><span class="line"> proxy_set_header Host $host;</span><br><span class="line"> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</span><br><span class="line"> uwsgi_pass 127.0.0.1:8000;</span><br><span class="line"> } </span><br><span class="line">}</span><br><span class="line">#网站二端口转发</span><br><span class="line">server {</span><br><span class="line"> listen 80; </span><br><span class="line"> server_name www.study.com;</span><br><span class="line"> access_log /home/code/study_web/logs/study_web.log;</span><br><span class="line"> error_log /home/code/study_web/logs/study_web.error;</span><br><span class="line"> </span><br><span class="line"> #将所有请求转发给demo_pool池的应用处理</span><br><span class="line"> location / { </span><br><span class="line"> include uwsgi_params;</span><br><span class="line"> proxy_set_header Host $host;</span><br><span class="line"> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</span><br><span class="line"> uwsgi_pass 127.0.0.1:8001;</span><br><span class="line"> } </span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="2、blog网站uwsgi配置"><a href="#2、blog网站uwsgi配置" class="headerlink" title="2、blog网站uwsgi配置"></a>2、blog网站uwsgi配置</h5><p>blog的uwsgi配置文件</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">[uwsgi]</span><br><span class="line"># chdir — 项目所在的目录</span><br><span class="line">chdir=/home/code/blog_web</span><br><span class="line"># virtualenv — 项目虚拟环境的目录</span><br><span class="line">virtualenv = /home/blogenv</span><br><span class="line"># 启动的model</span><br><span class="line">module = manage:app</span><br><span class="line"># 启动文件</span><br><span class="line">wsgi-file=manage.py</span><br><span class="line">callable=app</span><br><span class="line">#启动一个master进程来管理其他进程,以上述配置为例,其中的4个uwsgi进程都是这个master进程的子进程,如果kill这个master进程,相当于重启所有的uwsgi进程</span><br><span class="line">master=true</span><br><span class="line">#进程数量</span><br><span class="line">processes = 4 </span><br><span class="line">#线程数量</span><br><span class="line">threads=2</span><br><span class="line">###使进程在后台运行,并将日志打到指定的日志文件或者udp服务器,日志文件会自动创建</span><br><span class="line">daemonize=/var/log/uwsgi/blog_web.log</span><br><span class="line">#其中socket是用来uwsgi与nginx之间通信的</span><br><span class="line">socket = 127.0.0.1:8000</span><br></pre></td></tr></table></figure><h5 id="3、学习-网站uwsgi配置"><a href="#3、学习-网站uwsgi配置" class="headerlink" title="3、学习 网站uwsgi配置"></a>3、学习 网站uwsgi配置</h5><p>学习网站uwsgi配置文件</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">[uwsgi]</span><br><span class="line"># chdir — 项目所在的目录</span><br><span class="line">chdir=/home/code/study_web</span><br><span class="line"># virtualenv — 项目虚拟环境的目录</span><br><span class="line">virtualenv = /home/studyenv</span><br><span class="line"># 启动的model</span><br><span class="line">module = manage:app</span><br><span class="line"># 启动文件</span><br><span class="line">wsgi-file=manage.py</span><br><span class="line">callable=app</span><br><span class="line">#启动一个master进程来管理其他进程,以上述配置为例,其中的4个uwsgi进程都是这个master进程的子进程,如果kill这个master进程,相当于重启所有的uwsgi进程</span><br><span class="line">master=true</span><br><span class="line">#进程数量</span><br><span class="line">processes = 4 </span><br><span class="line">#线程数量</span><br><span class="line">threads=2</span><br><span class="line">###使进程在后台运行,并将日志打到指定的日志文件或者udp服务器,日志文件会自动创建</span><br><span class="line">daemonize=/var/log/uwsgi/study_web.log</span><br><span class="line">#其中socket是用来uwsgi与nginx之间通信的</span><br><span class="line">socket = 127.0.0.1:8001</span><br></pre></td></tr></table></figure><p>推荐方案:也是我现在用的方案。</p><p>部署一个网站可以参考文章《<a href="https://kujirashark.github.io/2018/06/23/Flask%E9%A1%B9%E7%9B%AE%E9%83%A8%E7%BD%B2/" target="_blank" rel="noopener">Flask项目部署</a>》</p><p>原创出品,喜欢可以收藏转载哦!!!</p><blockquote><p>作者:lizhonglin</p><p><strong>github:</strong> <a href="https://github.com/kujirashark/" target="_blank" rel="noopener">https://github.com/kujirashark/</a></p><p><strong>blog:</strong> <a href="https://kujirashark.github.io/" target="_blank" rel="noopener">https://kujirashark.github.io/</a></p></blockquote>]]></content>
<tags>
<tag> nginx部署多个网站 </tag>
</tags>
</entry>
<entry>
<title>python操作sqlserver的数据到mysql的实例</title>
<link href="/2018/10/31/python%E6%93%8D%E4%BD%9Csqlserver%E7%9A%84%E6%95%B0%E6%8D%AE%E5%88%B0mysql%E7%9A%84%E5%AE%9E%E4%BE%8B/"/>
<url>/2018/10/31/python%E6%93%8D%E4%BD%9Csqlserver%E7%9A%84%E6%95%B0%E6%8D%AE%E5%88%B0mysql%E7%9A%84%E5%AE%9E%E4%BE%8B/</url>
<content type="html"><![CDATA[<p> 今天有这样一个需求,需要把Sqlserver中的多张表中的不同字段的数据写入到Mysql表中对应的数据表中去。这个可以难为人了。自己想了一个办法使用python来操作两个数据库。python都能很好的支持两种数据库的操作。</p><p>首先我们需要相应的库:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">pymysql 操作mysql数据库</span><br><span class="line">pymssql 操作sqlserver数据库</span><br></pre></td></tr></table></figure><h5 id="一-、安装相关库"><a href="#一-、安装相关库" class="headerlink" title="一 、安装相关库"></a>一 、安装相关库</h5><p>首先我们需要安装以上两个包,安装命令分别为:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">pip install pymysql</span><br><span class="line">pip install pymssql</span><br></pre></td></tr></table></figure><h5 id="二、建立相关python-文件"><a href="#二、建立相关python-文件" class="headerlink" title="二、建立相关python 文件"></a>二、建立相关python 文件</h5><p>下面就上来我们的第一个实例。代码如下</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> pymssql</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MSSQL</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 对pymssql的简单封装</span></span><br><span class="line"><span class="string"> 使用该库时,需要在Sql Server Configuration Manager里面将TCP/IP协议开启</span></span><br><span class="line"><span class="string"> 用法:</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self,host,user,pwd,db)</span>:</span></span><br><span class="line"> self.host = host</span><br><span class="line"> self.user = user</span><br><span class="line"> self.pwd = pwd</span><br><span class="line"> self.db = db</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__GetConnect</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 得到连接信息</span></span><br><span class="line"><span class="string"> 返回: conn.cursor()</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> self.db:</span><br><span class="line"> <span class="keyword">raise</span>(NameError,<span class="string">"没有设置数据库信息"</span>)</span><br><span class="line"> self.conn = pymssql.connect(host=self.host,user=self.user,password=self.pwd,database=self.db,charset=<span class="string">"utf8"</span>)</span><br><span class="line"> cur = self.conn.cursor()</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> cur:</span><br><span class="line"> <span class="keyword">raise</span>(NameError,<span class="string">"连接数据库失败"</span>)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> cur</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">ExecQuery</span><span class="params">(self,sql)</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 执行查询语句</span></span><br><span class="line"><span class="string"> 返回的是一个包含tuple的list,list的元素是记录行,tuple的元素是每行记录的字段</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> cur = self.__GetConnect()</span><br><span class="line"> cur.execute(sql)</span><br><span class="line"> resList = cur.fetchall()</span><br><span class="line"></span><br><span class="line"> <span class="comment">#查询完毕后必须关闭连接</span></span><br><span class="line"> self.conn.close()</span><br><span class="line"> <span class="keyword">return</span> resList</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">ExecNonQuery</span><span class="params">(self,sql)</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 执行非查询语句</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> cur = self.__GetConnect()</span><br><span class="line"> cur.execute(sql)</span><br><span class="line"> self.conn.commit()</span><br><span class="line"> self.conn.close()</span><br><span class="line"><span class="comment">##</span></span><br><span class="line"><span class="comment">## 调用案例</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">main</span><span class="params">()</span>:</span></span><br><span class="line"> ms = MSSQL(host=<span class="string">"localhost"</span>,user=<span class="string">"sa"</span>,pwd=<span class="string">"P@ssword"</span>,db=<span class="string">"TP_TEST"</span>)</span><br><span class="line"> sql = <span class="string">'select T_JH.ID,T_JH.jhName,T_JHTemplate_SJ.TemplateID,T_JHTemplate_SJ.sjID,T_SJMB.sjName,T_JHTemplate.StartDate from T_JH LEFT JOIN T_JHTemplate on T_JH.ID = T_JHTemplate.JHId LEFT JOIN T_JHTemplate_SJ on T_JHTemplate_SJ.TemplateID = T_JHTemplate.Id LEFT JOIN T_SJMB on T_SJMB.Id = T_JHTemplate_SJ.sjID;'</span></span><br><span class="line"> <span class="keyword">return</span> ms.ExecQuery(sql)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">#################################</span></span><br><span class="line"><span class="keyword">import</span> pymysql</span><br><span class="line"><span class="comment"># mysql连接</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">connMySql</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self,host,user,pwd,db,port)</span>:</span></span><br><span class="line"> self.host = host</span><br><span class="line"> self.user = user</span><br><span class="line"> self.pwd = pwd</span><br><span class="line"> self.db = db</span><br><span class="line"> self.port = port</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 执行插入数据函数</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">insert_into_data</span><span class="params">(self,sql)</span>:</span></span><br><span class="line"> db = pymysql.connect(host=self.host, user=self.user, password=self.pwd, db=self.db, port=self.port)</span><br><span class="line"> cur = db.cursor()</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> cur.execute(sql)</span><br><span class="line"> <span class="comment"># 提交</span></span><br><span class="line"> db.commit()</span><br><span class="line"> <span class="keyword">except</span> Exception <span class="keyword">as</span> e:</span><br><span class="line"> <span class="comment"># 错误回滚</span></span><br><span class="line"> db.rollback()</span><br><span class="line"> <span class="keyword">finally</span>:</span><br><span class="line"> db.close()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">Changestamp</span><span class="params">(dt1)</span>:</span></span><br><span class="line"> <span class="comment"># datetime时间转为时间戳</span></span><br><span class="line"> Unixtime = time.mktime(time.strptime(dt1.strftime(<span class="string">'%Y-%m-%d %H:%M:%S'</span>), <span class="string">'%Y-%m-%d %H:%M:%S'</span>))</span><br><span class="line"> <span class="keyword">return</span> Unixtime</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> <span class="comment"># 获取sqlserver数据</span></span><br><span class="line"> data = main()</span><br><span class="line"> <span class="comment"># 链接mysql</span></span><br><span class="line"> db = connMySql(host=<span class="string">'192.168.0.147'</span>,user=<span class="string">'test'</span>,pwd=<span class="string">'123456'</span>,db=<span class="string">'missionplan'</span>,port=<span class="number">3306</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> da <span class="keyword">in</span> data:</span><br><span class="line"> d1 = da[<span class="number">0</span>]</span><br><span class="line"> d2 = da[<span class="number">1</span>]</span><br><span class="line"> d3 = da[<span class="number">2</span>]</span><br><span class="line"> d4 = da[<span class="number">3</span>]</span><br><span class="line"> d5 = da[<span class="number">4</span>]</span><br><span class="line"> d6 = da[<span class="number">5</span>]</span><br><span class="line"> <span class="keyword">if</span> d6 != <span class="keyword">None</span>:</span><br><span class="line"> d7 =Changestamp(d6)</span><br><span class="line"> sql = <span class="string">'''insert into planout(PlanId,PlanName,PlanVersion,EventId,EventName,StartTime) VALUES ('%s','%s','%s','%s','%s','%s');'''</span> %(d1,d2,d3,d4,d5,d7)</span><br><span class="line"> db.insert_into_data(sql)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> sql = <span class="string">'''insert into planout(PlanId,PlanName,PlanVersion,EventId,EventName,StartTime) VALUES ('%s','%s','%s','%s','%s',NULL);'''</span> %(d1,d2,d3,d4,d5)</span><br><span class="line"> db.insert_into_data(sql)</span><br><span class="line"> print(<span class="string">'数据插入成功'</span>)</span><br></pre></td></tr></table></figure><p>到此,一个完整的从sqlserver中查询初需要的数据,在完成mysql数据库的写入操作就完成了。</p><p>原创出品,喜欢可以收藏转载哦!!!</p><blockquote><p>作者:lizhonglin</p><p><strong>github:</strong> <a href="https://github.com/kujirashark/" target="_blank" rel="noopener">https://github.com/kujirashark/</a></p><p><strong>blog:</strong> <a href="https://kujirashark.github.io/" target="_blank" rel="noopener">https://kujirashark.github.io/</a></p></blockquote>]]></content>
<tags>
<tag> python操作sqlserver的数据到mysql的实例 </tag>
</tags>
</entry>
<entry>
<title>使用Hbuilder构建跨平台的移动app</title>
<link href="/2018/10/25/%E4%BD%BF%E7%94%A8Hbuilder%E6%9E%84%E5%BB%BA%E8%B7%A8%E5%B9%B3%E5%8F%B0%E7%9A%84%E7%A7%BB%E5%8A%A8app/"/>
<url>/2018/10/25/%E4%BD%BF%E7%94%A8Hbuilder%E6%9E%84%E5%BB%BA%E8%B7%A8%E5%B9%B3%E5%8F%B0%E7%9A%84%E7%A7%BB%E5%8A%A8app/</url>
<content type="html"><![CDATA[<p> 现在我们要开发一款通用的app,如果web端需要写,安卓、ios也需要写。这样岂不是太麻烦,也增加了公司的开发成本。于是乎就有了能跨平台的东西出来,所有的平台只需要写一次就ok。今天在这里我就介绍一下使用Hbuilder构建跨平台的移动app。需要准备的东西如下:</p><p>安装Hbuilder软件,这里不多介绍了。软件<a href="http://www.dcloud.io/" target="_blank" rel="noopener">下载地址</a></p><p>下载好之后我们还要准备好自己要打包的项目。</p><h5 id="一、安装Hbuilder"><a href="#一、安装Hbuilder" class="headerlink" title="一、安装Hbuilder"></a>一、安装Hbuilder</h5><p> 此处省略。不是本文重点,有关安装问题自行百度。</p><h5 id="二、打开Hbuilder"><a href="#二、打开Hbuilder" class="headerlink" title="二、打开Hbuilder"></a>二、打开Hbuilder</h5><p> 选中红色区域内新建项目</p><p><img src="/2018/10/25/使用Hbuilder构建跨平台的移动app/1.png" alt="1"></p><p> 会弹出如下界面</p><p><img src="/2018/10/25/使用Hbuilder构建跨平台的移动app/2.png" alt="2"></p><p> 填好名称和路径然后点击创建。创建好之后项目的目录结构如下</p><p><img src="/2018/10/25/使用Hbuilder构建跨平台的移动app/3.png" alt="3"></p><h5 id="三、编辑好项目代码"><a href="#三、编辑好项目代码" class="headerlink" title="三、编辑好项目代码"></a>三、编辑好项目代码</h5><p>整理好需要打包的项目代码。主要为了测试打包。简单的测试代码</p><p><img src="/2018/10/25/使用Hbuilder构建跨平台的移动app/4.png" alt="1540448632068"></p><h5 id="四、进行manifest-json配置"><a href="#四、进行manifest-json配置" class="headerlink" title="四、进行manifest.json配置"></a>四、进行manifest.json配置</h5><h6 id="基础配置"><a href="#基础配置" class="headerlink" title="基础配置"></a>基础配置</h6><p><img src="/2018/10/25/使用Hbuilder构建跨平台的移动app/5.png" alt="5"></p><h6 id="图标配置"><a href="#图标配置" class="headerlink" title="图标配置"></a>图标配置</h6><p><img src="/2018/10/25/使用Hbuilder构建跨平台的移动app/6.png" alt="6"></p><p>点击自动生成所有图标并替换就会生成下面所有的图标。也可以自己制作对应的图片</p><h6 id="启动图配置"><a href="#启动图配置" class="headerlink" title="启动图配置"></a>启动图配置</h6><p><img src="/2018/10/25/使用Hbuilder构建跨平台的移动app/7.png" alt="7"></p><p>下面的图片尺寸大小需要自己设计好。延时按照要求设置对应的数值就可以。</p><h6 id="SDK配置"><a href="#SDK配置" class="headerlink" title="SDK配置"></a>SDK配置</h6><p><img src="/2018/10/25/使用Hbuilder构建跨平台的移动app/8.png" alt="8"></p><p>这个地方根据自己的需求去配置相应的值。</p><h6 id="模块权限配置"><a href="#模块权限配置" class="headerlink" title="模块权限配置"></a>模块权限配置</h6><p><img src="/2018/10/25/使用Hbuilder构建跨平台的移动app/9.png" alt="9"></p><p>配置软件获取的系统权限</p><h6 id="源码视图"><a href="#源码视图" class="headerlink" title="源码视图"></a>源码视图</h6><p>主要查看上面的配置的json文件。如下:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"> "@platforms" : [ "android", "iPhone", "iPad" ],</span><br><span class="line"> "id" : "H590E31E9", /*应用的标识*/</span><br><span class="line"> "name" : "my_demo", /*应用名称,程序桌面图标名称*/</span><br><span class="line"> "version" : {</span><br><span class="line"> "name" : "1.0", /*应用版本名称*/</span><br><span class="line"> "code" : 1</span><br><span class="line"> },</span><br><span class="line"> "description" : "第一个测试的app", /*应用描述信息*/</span><br><span class="line"> "icons" : {</span><br><span class="line"> "72" : "icon.png"</span><br><span class="line"> },</span><br><span class="line"> "launch_path" : "index.html", /*应用的入口页面,默认为根目录下的index.html;支持网络地址,必须以http://或https://开头*/</span><br><span class="line"> "developer" : {</span><br><span class="line"> "name" : "", /*开发者名称*/</span><br><span class="line"> "email" : "", /*开发者邮箱地址*/</span><br><span class="line"> "url" : "" /*开发者个人主页地址*/</span><br><span class="line"> },</span><br><span class="line"> "permissions" : {</span><br><span class="line"> "Accelerometer" : {</span><br><span class="line"> "description" : "访问加速度感应器"</span><br><span class="line"> },</span><br><span class="line"> "Audio" : {</span><br><span class="line"> "description" : "访问麦克风"</span><br><span class="line"> },</span><br><span class="line"> "Messaging" : {</span><br><span class="line"> "description" : "短彩邮件插件"</span><br><span class="line"> },</span><br><span class="line"> "Cache" : {</span><br><span class="line"> "description" : "管理应用缓存"</span><br><span class="line"> },</span><br><span class="line"> "Camera" : {</span><br><span class="line"> "description" : "访问摄像头"</span><br><span class="line"> },</span><br><span class="line"> "Console" : {</span><br><span class="line"> "description" : "跟踪调试输出日志"</span><br><span class="line"> },</span><br><span class="line"> "Contacts" : {</span><br><span class="line"> "description" : "访问系统联系人信息"</span><br><span class="line"> },</span><br><span class="line"> "Device" : {</span><br><span class="line"> "description" : "访问设备信息"</span><br><span class="line"> },</span><br><span class="line"> "Downloader" : {</span><br><span class="line"> "description" : "文件下载管理"</span><br><span class="line"> },</span><br><span class="line"> "Events" : {</span><br><span class="line"> "description" : "应用扩展事件"</span><br><span class="line"> },</span><br><span class="line"> "File" : {</span><br><span class="line"> "description" : "访问本地文件系统"</span><br><span class="line"> },</span><br><span class="line"> "Gallery" : {</span><br><span class="line"> "description" : "访问系统相册"</span><br><span class="line"> },</span><br><span class="line"> "Geolocation" : {</span><br><span class="line"> "description" : "访问位置信息"</span><br><span class="line"> },</span><br><span class="line"> "Invocation" : {</span><br><span class="line"> "description" : "使用Native.js能力"</span><br><span class="line"> },</span><br><span class="line"> "Orientation" : {</span><br><span class="line"> "description" : "访问方向感应器"</span><br><span class="line"> },</span><br><span class="line"> "Proximity" : {</span><br><span class="line"> "description" : "访问距离感应器"</span><br><span class="line"> },</span><br><span class="line"> "Storage" : {</span><br><span class="line"> "description" : "管理应用本地数据"</span><br><span class="line"> },</span><br><span class="line"> "Uploader" : {</span><br><span class="line"> "description" : "管理文件上传任务"</span><br><span class="line"> },</span><br><span class="line"> "Runtime" : {</span><br><span class="line"> "description" : "访问运行期环境"</span><br><span class="line"> },</span><br><span class="line"> "XMLHttpRequest" : {</span><br><span class="line"> "description" : "跨域网络访问"</span><br><span class="line"> },</span><br><span class="line"> "Zip" : {</span><br><span class="line"> "description" : "文件压缩与解压缩"</span><br><span class="line"> },</span><br><span class="line"> "Barcode" : {</span><br><span class="line"> "description" : "管理二维码扫描插件"</span><br><span class="line"> },</span><br><span class="line"> "Maps" : {</span><br><span class="line"> "description" : "管理地图插件"</span><br><span class="line"> },</span><br><span class="line"> "Speech" : {</span><br><span class="line"> "description" : "管理语音识别插件"</span><br><span class="line"> },</span><br><span class="line"> "Webview" : {</span><br><span class="line"> "description" : "窗口管理"</span><br><span class="line"> },</span><br><span class="line"> "NativeUI" : {</span><br><span class="line"> "description" : "原生UI控件"</span><br><span class="line"> },</span><br><span class="line"> "Navigator" : {</span><br><span class="line"> "description" : "浏览器信息"</span><br><span class="line"> },</span><br><span class="line"> "NativeObj" : {</span><br><span class="line"> "description" : "原生对象"</span><br><span class="line"> }</span><br><span class="line"> },</span><br><span class="line"> "plus" : {</span><br><span class="line"> "splashscreen" : {</span><br><span class="line"> "autoclose" : true, /*是否自动关闭程序启动界面,true表示应用加载应用入口页面后自动关闭;false则需调plus.navigator.closeSplashscreen()关闭*/</span><br><span class="line"> "waiting" : true, /*是否在程序启动界面显示等待雪花,true表示显示,false表示不显示。*/</span><br><span class="line"> "delay" : 3000</span><br><span class="line"> },</span><br><span class="line"> "popGesture" : "close", /*设置应用默认侧滑返回关闭Webview窗口,"none"为无侧滑返回功能,"hide"为侧滑隐藏Webview窗口。参考http://ask.dcloud.net.cn/article/102*/</span><br><span class="line"> "runmode" : "normal", /*应用的首次启动运行模式,可取liberate或normal,liberate模式在第一次启动时将解压应用资源(Android平台File API才可正常访问_www目录)*/</span><br><span class="line"> "signature" : "Sk9JTiBVUyBtYWlsdG86aHIyMDEzQGRjbG91ZC5pbw==", /*可选,保留给应用签名,暂不使用*/</span><br><span class="line"> "distribute" : {</span><br><span class="line"> "apple" : {</span><br><span class="line"> "appid" : "", /*iOS应用标识,苹果开发网站申请的appid,如io.dcloud.HelloH5*/</span><br><span class="line"> "mobileprovision" : "", /*iOS应用打包配置文件*/</span><br><span class="line"> "password" : "", /*iOS应用打包个人证书导入密码*/</span><br><span class="line"> "p12" : "", /*iOS应用打包个人证书,打包配置文件关联的个人证书*/</span><br><span class="line"> "devices" : "universal", /*iOS应用支持的设备类型,可取值iphone/ipad/universal*/</span><br><span class="line"> "frameworks" : [] /*调用Native.js调用原生Objective-c API需要引用的FrameWork,如需调用GameCenter,则添加"GameKit.framework"*/</span><br><span class="line"> },</span><br><span class="line"> "google" : {</span><br><span class="line"> "packagename" : "", /*Android应用包名,如io.dcloud.HelloH5*/</span><br><span class="line"> "keystore" : "", /*Android应用打包使用的密钥库文件*/</span><br><span class="line"> "password" : "", /*Android应用打包使用密钥库中证书的密码*/</span><br><span class="line"> "aliasname" : "", /*Android应用打包使用密钥库中证书的别名*/</span><br><span class="line"> "permissions" : [</span><br><span class="line"> "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.VIBRATE\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",</span><br><span class="line"> "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.CAMERA\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",</span><br><span class="line"> "<uses-feature android:name=\"android.hardware.camera\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",</span><br><span class="line"> "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"</span><br><span class="line"> ]</span><br><span class="line"> },</span><br><span class="line"> /*使用Native.js调用原生安卓API需要使用到的系统权限*/</span><br><span class="line"> "orientation" : [ "portrait-primary" ], /*应用支持的方向,portrait-primary:竖屏正方向;portrait-secondary:竖屏反方向;landscape-primary:横屏正方向;landscape-secondary:横屏反方向*/</span><br><span class="line"> "icons" : {</span><br><span class="line"> "ios" : {</span><br><span class="line"> "prerendered" : true, /*应用图标是否已经高亮处理,在iOS6及以下设备上有效*/</span><br><span class="line"> "auto" : "", /*应用图标,分辨率:512x512,用于自动生成各种尺寸程序图标*/</span><br><span class="line"> "iphone" : {</span><br><span class="line"> "normal" : "", /*iPhone3/3GS程序图标,分辨率:57x57*/</span><br><span class="line"> "retina" : "", /*iPhone4程序图标,分辨率:114x114*/</span><br><span class="line"> "retina7" : "", /*iPhone4S/5/6程序图标,分辨率:120x120*/</span><br><span class="line"> "retina8" : "", /*iPhone6 Plus程序图标,分辨率:180x180*/</span><br><span class="line"> "spotlight-normal" : "", /*iPhone3/3GS Spotlight搜索程序图标,分辨率:29x29*/</span><br><span class="line"> "spotlight-retina" : "", /*iPhone4 Spotlight搜索程序图标,分辨率:58x58*/</span><br><span class="line"> "spotlight-retina7" : "", /*iPhone4S/5/6 Spotlight搜索程序图标,分辨率:80x80*/</span><br><span class="line"> "settings-normal" : "", /*iPhone4设置页面程序图标,分辨率:29x29*/</span><br><span class="line"> "settings-retina" : "", /*iPhone4S/5/6设置页面程序图标,分辨率:58x58*/</span><br><span class="line"> "settings-retina8" : "", /*iPhone6Plus设置页面程序图标,分辨率:87x87*/</span><br><span class="line"> "app@2x" : "unpackage/res/icons/120x120.png",</span><br><span class="line"> "app@3x" : "unpackage/res/icons/180x180.png",</span><br><span class="line"> "notification@2x" : "unpackage/res/icons/40x40.png",</span><br><span class="line"> "notification@3x" : "unpackage/res/icons/60x60.png",</span><br><span class="line"> "settings@2x" : "unpackage/res/icons/58x58.png",</span><br><span class="line"> "settings@3x" : "unpackage/res/icons/87x87.png",</span><br><span class="line"> "spotlight@2x" : "unpackage/res/icons/80x80.png",</span><br><span class="line"> "spotlight@3x" : "unpackage/res/icons/120x120.png"</span><br><span class="line"> },</span><br><span class="line"> "ipad" : {</span><br><span class="line"> "normal" : "", /*iPad普通屏幕程序图标,分辨率:72x72*/</span><br><span class="line"> "retina" : "", /*iPad高分屏程序图标,分辨率:144x144*/</span><br><span class="line"> "normal7" : "", /*iPad iOS7程序图标,分辨率:76x76*/</span><br><span class="line"> "retina7" : "", /*iPad iOS7高分屏程序图标,分辨率:152x152*/</span><br><span class="line"> "spotlight-normal" : "", /*iPad Spotlight搜索程序图标,分辨率:50x50*/</span><br><span class="line"> "spotlight-retina" : "", /*iPad高分屏Spotlight搜索程序图标,分辨率:100x100*/</span><br><span class="line"> "spotlight-normal7" : "", /*iPad iOS7 Spotlight搜索程序图标,分辨率:40x40*/</span><br><span class="line"> "spotlight-retina7" : "", /*iPad iOS7高分屏Spotlight搜索程序图标,分辨率:80x80*/</span><br><span class="line"> "settings-normal" : "", /*iPad设置页面程序图标,分辨率:29x29*/</span><br><span class="line"> "settings-retina" : "", /*iPad高分屏设置页面程序图标,分辨率:58x58*/</span><br><span class="line"> "app" : "unpackage/res/icons/76x76.png",</span><br><span class="line"> "app@2x" : "unpackage/res/icons/152x152.png",</span><br><span class="line"> "notification" : "unpackage/res/icons/20x20.png",</span><br><span class="line"> "notification@2x" : "unpackage/res/icons/40x40.png",</span><br><span class="line"> "proapp@2x" : "unpackage/res/icons/167x167.png",</span><br><span class="line"> "settings" : "unpackage/res/icons/29x29.png",</span><br><span class="line"> "settings@2x" : "unpackage/res/icons/58x58.png",</span><br><span class="line"> "spotlight" : "unpackage/res/icons/40x40.png",</span><br><span class="line"> "spotlight@2x" : "unpackage/res/icons/80x80.png"</span><br><span class="line"> },</span><br><span class="line"> "appstore" : "img/logo.png"</span><br><span class="line"> },</span><br><span class="line"> "android" : {</span><br><span class="line"> "mdpi" : "unpackage/res/icons/48x48.png", /*普通屏程序图标,分辨率:48x48*/</span><br><span class="line"> "ldpi" : "unpackage/res/icons/48x48.png", /*大屏程序图标,分辨率:48x48*/</span><br><span class="line"> "hdpi" : "unpackage/res/icons/72x72.png", /*高分屏程序图标,分辨率:72x72*/</span><br><span class="line"> "xhdpi" : "unpackage/res/icons/96x96.png", /*720P高分屏程序图标,分辨率:96x96*/</span><br><span class="line"> "xxhdpi" : "unpackage/res/icons/144x144.png", /*1080P 高分屏程序图标,分辨率:144x144*/</span><br><span class="line"> "xxxhdpi" : "unpackage/res/icons/192x192.png"</span><br><span class="line"> }</span><br><span class="line"> },</span><br><span class="line"> "splashscreen" : {</span><br><span class="line"> "ios" : {</span><br><span class="line"> "iphone" : {</span><br><span class="line"> "default" : "", /*iPhone3启动图片选,分辨率:320x480*/</span><br><span class="line"> "retina35" : "", /*3.5英寸设备(iPhone4)启动图片,分辨率:640x960*/</span><br><span class="line"> "retina40" : "", /*4.0 英寸设备(iPhone5/iPhone5s)启动图片,分辨率:640x1136*/</span><br><span class="line"> "retina47" : "", /*4.7 英寸设备(iPhone6)启动图片,分辨率:750x1334*/</span><br><span class="line"> "retina55" : "", /*5.5 英寸设备(iPhone6 Plus)启动图片,分辨率:1242x2208*/</span><br><span class="line"> "retina55l" : "" /*5.5 英寸设备(iPhone6 Plus)横屏启动图片,分辨率:2208x1242*/</span><br><span class="line"> },</span><br><span class="line"> "ipad" : {</span><br><span class="line"> "portrait" : "", /*iPad竖屏启动图片,分辨率:768x1004*/</span><br><span class="line"> "portrait-retina" : "", /*iPad高分屏竖屏图片,分辨率:1536x2008*/</span><br><span class="line"> "landscape" : "", /*iPad横屏启动图片,分辨率:1024x748*/</span><br><span class="line"> "landscape-retina" : "", /*iPad高分屏横屏启动图片,分辨率:2048x1496*/</span><br><span class="line"> "portrait7" : "", /*iPad iOS7竖屏启动图片,分辨率:768x1024*/</span><br><span class="line"> "portrait-retina7" : "", /*iPad iOS7高分屏竖屏图片,分辨率:1536x2048*/</span><br><span class="line"> "landscape7" : "", /*iPad iOS7横屏启动图片,分辨率:1024x768*/</span><br><span class="line"> "landscape-retina7" : "" /*iPad iOS7高分屏横屏启动图片,分辨率:2048x1536*/</span><br><span class="line"> }</span><br><span class="line"> },</span><br><span class="line"> "android" : {</span><br><span class="line"> "mdpi" : "", /*普通屏启动图片,分辨率:240x282*/</span><br><span class="line"> "ldpi" : "", /*大屏启动图片,分辨率:320x442*/</span><br><span class="line"> "hdpi" : "", /*高分屏启动图片,分辨率:480x762*/</span><br><span class="line"> "xhdpi" : "", /*720P高分屏启动图片,分辨率:720x1242*/</span><br><span class="line"> "xxhdpi" : "" /*1080P高分屏启动图片,分辨率:1080x1882*/</span><br><span class="line"> }</span><br><span class="line"> },</span><br><span class="line"> "plugins" : {</span><br><span class="line"> "speech" : {</span><br><span class="line"> "ifly" : {}</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="五、打包"><a href="#五、打包" class="headerlink" title="五、打包"></a>五、打包</h5><p>选择上面菜单栏的发行,原生App在线云端打包</p><p><img src="/2018/10/25/使用Hbuilder构建跨平台的移动app/10.png" alt="10"></p><p>选择完之后就来到这个位置。</p><p><img src="/2018/10/25/使用Hbuilder构建跨平台的移动app/11.png" alt="11"></p><p>上面如果选择了自己的证书 下面的(证书别名、私钥密码、证书文件)都需要填写自己的。</p><p>因为我这里没有证书我就选择了 使用DCloud公用证书。下面的的信息就不需要填写。这里都填写好之后就可以点击下面的打包按钮。进行app打包了。</p><p>打包成功后会显示</p><p><img src="/2018/10/25/使用Hbuilder构建跨平台的移动app/12.png" alt="12"></p><p>成功之后就可以在控制台看到如下app在队列中的信息。</p><p><img src="/2018/10/25/使用Hbuilder构建跨平台的移动app/13.png" alt="13"></p><p>等待完成之后就可以下载你的apx文件了。</p><p><img src="/2018/10/25/使用Hbuilder构建跨平台的移动app/14.png" alt="14"></p><p>下载完成之后</p><p><img src="/2018/10/25/使用Hbuilder构建跨平台的移动app/15.png" alt="15"></p><p>这样打包工作就完成了。</p><p>Ios的打包前面的操作都是一样的就后面的配置有一些区别按照要求进行配置就好。</p><p>原创出品,喜欢可以收藏转载哦!!!</p><blockquote><p>作者:lizhonglin</p><p><strong>github:</strong> <a href="https://github.com/kujirashark/" target="_blank" rel="noopener">https://github.com/kujirashark/</a></p><p><strong>blog:</strong> <a href="https://kujirashark.github.io/" target="_blank" rel="noopener">https://kujirashark.github.io/</a></p></blockquote>]]></content>
<tags>
<tag> Hbuilder构建跨平台的移动app </tag>
</tags>
</entry>
<entry>
<title>NSIS打包electron生成的文件为exe安装包</title>
<link href="/2018/10/25/NSIS%E6%89%93%E5%8C%85electron%E7%94%9F%E6%88%90%E7%9A%84%E6%96%87%E4%BB%B6%E4%B8%BAexe%E5%AE%89%E8%A3%85%E5%8C%85/"/>
<url>/2018/10/25/NSIS%E6%89%93%E5%8C%85electron%E7%94%9F%E6%88%90%E7%9A%84%E6%96%87%E4%BB%B6%E4%B8%BAexe%E5%AE%89%E8%A3%85%E5%8C%85/</url>
<content type="html"><![CDATA[<p> 接着上一篇文章最后的的内容开始。上面我们使用electron生成相应的项目文件包,只是一个绿色版本的应用,不一定是我们最喜欢的。懂软件的人使用起来还是比较简单。有一个需求是我们能不能打包成像qq微信这样下载下来可以自己安装,并且能选择自己喜欢的安装目录呢? 答案肯定是可以的。接下来我们就开始我们的编译打包。</p><h5 id="一、需要的工具"><a href="#一、需要的工具" class="headerlink" title="一、需要的工具"></a>一、需要的工具</h5><ol><li><p>NSIS软件 </p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">下载地址:https://pan.baidu.com/s/1mitSQU0</span><br></pre></td></tr></table></figure></li><li><p>asar插件</p><p>可以参考官方文档 <a href="https://www.w3cschool.cn/electronmanual/cexo1qkn.html" target="_blank" rel="noopener">地址</a></p></li></ol><p>安装NSIS就直接下一步下一步就ok.</p><p>安装asar的命令为:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install -g asar</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">PS C:\Users\lzl\Desktop\test> npm install -g asar</span><br><span class="line">C:\Users\lzl\AppData\Roaming\npm\asar -> C:\Users\lzl\AppData\Roaming\npm\node_modules\asar\bin\asar.js</span><br><span class="line">+ [email protected]</span><br><span class="line">updated 1 package in 12.708s</span><br><span class="line">PS C:\Users\lzl\Desktop\test></span><br></pre></td></tr></table></figure><h5 id="二、打包"><a href="#二、打包" class="headerlink" title="二、打包"></a>二、打包</h5><p>运行命令</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">asar pack ./index.html app.asar</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">PS C:\Users\lj\Desktop\test> asar pack ./index.html app.asar</span><br><span class="line">PS C:\Users\lj\Desktop\test></span><br></pre></td></tr></table></figure><p>然后将生成的<code>app.asar</code> 的文件拷贝到项目文件的<code>test\app\resources</code>文件夹下面</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/1.png" alt="1"></p><h5 id="三、打开NSIS软件进行操作"><a href="#三、打开NSIS软件进行操作" class="headerlink" title="三、打开NSIS软件进行操作"></a>三、打开NSIS软件进行操作</h5><p>选择<code>HW VNISEdit</code>选项。</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/2.png" alt="2"></p><p>来到如下界面</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/3.png" alt="3"></p><p>选择文件—-》新建脚本向导</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/4.png" alt="4"></p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/5.png" alt="5"></p><p>直接点击下一步。填写下面的信息</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/6.png" alt="6"></p><p>填写好上面的信息后点击下一步。来选择安装程序的图标、安装程序文件名称、安装程序语言、用户图形界面、压缩算法等信息。</p><p>我添加了一个ico图标<img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/7.png" alt="7"></p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/8.png" alt="8"></p><p>其他设置选择了简体中文。然后在点击下一步。这一步默认处理</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/9.png" alt="9"></p><p>然后在点击下一步,授权文件有就填,没有就填空白。</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/10.png" alt="10"></p><p>然后在点击下一步,添加应用程序文件,默认两个文件选中,删除</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/11.png" alt="11"></p><p>删除完默认的文件之后在点击添加按钮添加我们自己的文件</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/12.png" alt="12"></p><p>选择自己已经编译好的<code>muise.exe</code>文件</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/13.png" alt="13"></p><p>选好之后在点击确认。然后回到这个界面在点击添加目录按钮来添加整个要打包的目录。</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/14.png" alt="14"></p><p>添加好打包的目录和他的子目录</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/15.png" alt="15"></p><p>然后在点击确定,在回到当前页面</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/16.png" alt="16"></p><p>在点击下一步进入应用程序图标的设置,这个地方可以根据自己的情况选择</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/17.png" alt="17"></p><p>选择好之后在点击下一步。设置安装程序之后运行,默认就是我们打包后的启动程序</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/18.png" alt="18"></p><p>在点击下一步,进入解除安装程序设置。我这里选择的默认</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/19.png" alt="19"></p><p>点击下一步完成向导</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/20.png" alt="20"></p><p>点击完成按钮,保存向导设置的nsi文件,位置自己指定。</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/21.png" alt="21"></p><p>保存完成后就来在最初的主页面,就能看见我们刚才配置的信息。</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/22.png" alt="22"></p><p>到了这一步了我们就可以开始编译了。点击有上面的编译并运行。</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/23.png" alt="23"></p><p>等待程序编译结果。</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/24.png" alt="24"></p><p>到了这一步我们的程序已经打包成功。点击下图是我们打包成功的效果图</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/26.png" alt="26"></p><p>双击程序就可以开始安装</p><p><img src="/2018/10/25/NSIS打包electron生成的文件为exe安装包/25.png" alt="25"></p><p>原创出品,欢迎转载收藏。</p><blockquote><p>作者:lizhonglin</p><p><strong>github:</strong> <a href="https://github.com/kujirashark/" target="_blank" rel="noopener">https://github.com/kujirashark/</a></p><p><strong>blog:</strong> <a href="https://kujirashark.github.io/" target="_blank" rel="noopener">https://kujirashark.github.io/</a></p></blockquote>]]></content>
<tags>
<tag> NSIS打包可安装的exe文件 </tag>
</tags>
</entry>
<entry>
<title>使用electron构建基于html的桌面应用</title>
<link href="/2018/10/24/%E4%BD%BF%E7%94%A8electron%E6%9E%84%E5%BB%BA%E5%9F%BA%E4%BA%8Ehtml%E7%9A%84%E6%A1%8C%E9%9D%A2%E5%BA%94%E7%94%A8/"/>
<url>/2018/10/24/%E4%BD%BF%E7%94%A8electron%E6%9E%84%E5%BB%BA%E5%9F%BA%E4%BA%8Ehtml%E7%9A%84%E6%A1%8C%E9%9D%A2%E5%BA%94%E7%94%A8/</url>
<content type="html"><![CDATA[<pre><code>有一个需求是需要构建系统的桌面的应用,搜索了很多资料发现了electron这个平台。功能非常强大,在git上面也有很多星星。自己研究了一番总结了一些。可以供大家参考。那么electron是如何构建桌面应用的呢?</code></pre><h5 id="1、新建项目文件夹-my"><a href="#1、新建项目文件夹-my" class="headerlink" title="1、新建项目文件夹 my"></a>1、新建项目文件夹 my</h5><p><img src="/2018/10/24/使用electron构建基于html的桌面应用/8.png" alt="8"></p><h5 id="2、用命令行打开项目文件夹"><a href="#2、用命令行打开项目文件夹" class="headerlink" title="2、用命令行打开项目文件夹"></a>2、用命令行打开项目文件夹</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">shift + 鼠标右键 =》 在此处打开Powershell窗口</span><br></pre></td></tr></table></figure><h5 id="3、创建index-js文件写入如下内容"><a href="#3、创建index-js文件写入如下内容" class="headerlink" title="3、创建index.js文件写入如下内容"></a>3、创建index.js文件写入如下内容</h5><p>(官方代码拷贝过去就可以)</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> electron = <span class="built_in">require</span>(<span class="string">'electron'</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> {</span><br><span class="line"> app, <span class="comment">// 控制应用生命周期的模块</span></span><br><span class="line"> BrowserWindow, <span class="comment">// 创建原生浏览器窗口的模块</span></span><br><span class="line">} = electron;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 保持一个对于 window 对象的全局引用,如果不这样做,</span></span><br><span class="line"><span class="comment">// 当 JavaScript 对象被垃圾回收, window 会被自动地关闭</span></span><br><span class="line"><span class="keyword">let</span> mainWindow;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">createWindow</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="comment">// 创建浏览器窗口。</span></span><br><span class="line"> mainWindow = <span class="keyword">new</span> BrowserWindow({<span class="attr">width</span>: <span class="number">800</span>, <span class="attr">height</span>: <span class="number">600</span>});</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 加载应用的 index.html。</span></span><br><span class="line"> <span class="comment">// 这里使用的是 file 协议,加载当前目录下的 index.html 文件。</span></span><br><span class="line"> <span class="comment">// 也可以使用 http 协议,如 mainWindow.loadURL('http://nodejh.com')。</span></span><br><span class="line"> mainWindow.loadURL(<span class="string">`file://<span class="subst">${__dirname}</span>/index.html`</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 启用开发工具。</span></span><br><span class="line"> mainWindow.webContents.openDevTools();</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 当 window 被关闭,这个事件会被触发。</span></span><br><span class="line"> mainWindow.on(<span class="string">'closed'</span>, () => {</span><br><span class="line"> <span class="comment">// 取消引用 window 对象,如果你的应用支持多窗口的话,</span></span><br><span class="line"> <span class="comment">// 通常会把多个 window 对象存放在一个数组里面,</span></span><br><span class="line"> <span class="comment">// 与此同时,你应该删除相应的元素。</span></span><br><span class="line"> mainWindow = <span class="literal">null</span>;</span><br><span class="line"> });</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// Electron 会在初始化后并准备</span></span><br><span class="line"><span class="comment">// 创建浏览器窗口时,调用这个函数。</span></span><br><span class="line"><span class="comment">// 部分 API 在 ready 事件触发后才能使用。</span></span><br><span class="line">app.on(<span class="string">'ready'</span>, createWindow);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 当全部窗口关闭时退出。</span></span><br><span class="line">app.on(<span class="string">'window-all-closed'</span>, () => {</span><br><span class="line"> <span class="comment">// 在 macOS 上,除非用户用 Cmd + Q 确定地退出,</span></span><br><span class="line"> <span class="comment">// 否则绝大部分应用及其菜单栏会保持激活。</span></span><br><span class="line"> <span class="keyword">if</span> (process.platform !== <span class="string">'darwin'</span>) {</span><br><span class="line"> app.quit();</span><br><span class="line"> }</span><br><span class="line">});</span><br><span class="line"></span><br><span class="line">app.on(<span class="string">'activate'</span>, () => {</span><br><span class="line"> <span class="comment">// 在 macOS 上,当点击 dock 图标并且该应用没有打开的窗口时,</span></span><br><span class="line"> <span class="comment">// 绝大部分应用会重新创建一个窗口。</span></span><br><span class="line"> <span class="keyword">if</span> (mainWindow === <span class="literal">null</span>) {</span><br><span class="line"> createWindow();</span><br><span class="line"> }</span><br><span class="line">});</span><br></pre></td></tr></table></figure><h5 id="4、在powershell中使用命令初始化项目"><a href="#4、在powershell中使用命令初始化项目" class="headerlink" title="4、在powershell中使用命令初始化项目"></a>4、在powershell中使用命令初始化项目</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm init</span><br></pre></td></tr></table></figure><h5 id="5、拷贝项目的需要的html、css、static等资源到项目目录"><a href="#5、拷贝项目的需要的html、css、static等资源到项目目录" class="headerlink" title="5、拷贝项目的需要的html、css、static等资源到项目目录"></a>5、拷贝项目的需要的html、css、static等资源到项目目录</h5><p><img src="/2018/10/24/使用electron构建基于html的桌面应用/9.png" alt="9"></p><h5 id="6、安装项目需要依赖"><a href="#6、安装项目需要依赖" class="headerlink" title="6、安装项目需要依赖"></a>6、安装项目需要依赖</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install electron --save-dev</span><br></pre></td></tr></table></figure><blockquote><p>故障:</p><p>PS C:\Users\lj\Desktop\my> npm install electron-prebuilt –save-dev<br>npm WARN deprecated <a href="mailto:[email protected]" target="_blank" rel="noopener">[email protected]</a>: electron-prebuilt has been renamed to electron. For more details, see <a href="http://electron.atom.io/blog/2016/08/16/npm-install-electron" target="_blank" rel="noopener">http://electron.atom.io/blog/2016/08/16/npm-install-electron</a></p><blockquote><p><a href="mailto:[email protected]" target="_blank" rel="noopener">[email protected]</a> postinstall C:\Users\lj\Desktop\my\node_modules\electron-prebuilt<br>node install.js</p></blockquote><p>npm WARN <a href="mailto:[email protected]" target="_blank" rel="noopener">[email protected]</a> No description<br>npm WARN <a href="mailto:[email protected]" target="_blank" rel="noopener">[email protected]</a> No repository field.</p><ul><li><a href="mailto:[email protected]" target="_blank" rel="noopener">[email protected]</a><br>added 1 package in 6.303s</li></ul></blockquote><p>故障解决:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">如果只是在本机上开发可以在 package,json 文件中加入以下字段,</span><br><span class="line">{</span><br><span class="line">.</span><br><span class="line">.</span><br><span class="line">.</span><br><span class="line">"private": true</span><br><span class="line">.</span><br><span class="line">. </span><br><span class="line">.</span><br><span class="line">}</span><br><span class="line">再次安装时即不会出现此问题</span><br></pre></td></tr></table></figure><h5 id="7、运行-命令启动程序"><a href="#7、运行-命令启动程序" class="headerlink" title="7、运行 命令启动程序"></a>7、运行 命令启动程序</h5><p>electron 在开发阶段的启动方式</p><p>找到node_modules.bin\election.cmd文件执行下面的代码:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">.\node_modules\.bin\electron .\index.js</span><br></pre></td></tr></table></figure><p>可以把上面的命令写入入口文件中的script中</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"> "name": "my",</span><br><span class="line"> "version": "1.0.0",</span><br><span class="line"> "description": "",</span><br><span class="line"> "main": "index.js",</span><br><span class="line"> "scripts": {</span><br><span class="line"> "test": "electron ."</span><br><span class="line"> },</span><br><span class="line"> "private": true,</span><br><span class="line"> "author": "",</span><br><span class="line"> "license": "ISC",</span><br><span class="line"> "devDependencies": {</span><br><span class="line"> "electron": "^3.0.5",</span><br><span class="line"> "electron-prebuilt": "^1.4.13"</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>启动方式就变成</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run test 或者 electron .</span><br></pre></td></tr></table></figure><p>都可以完成启动。</p><p>上面两种方式运行的效果如下图:</p><p><img src="/2018/10/24/使用electron构建基于html的桌面应用/7.png" alt="7"></p><h5 id="8、打包"><a href="#8、打包" class="headerlink" title="8、打包"></a>8、打包</h5><h6 id="1-方法一"><a href="#1-方法一" class="headerlink" title="1.方法一"></a>1.方法一</h6><p>首先进入项目目录找到如图文件夹(省略 ….. 项目文件夹\node_modules\electron )</p><p><img src="/2018/10/24/使用electron构建基于html的桌面应用/1.png" alt="1"></p><p>里面有一个dist文件夹</p><p><img src="/2018/10/24/使用electron构建基于html的桌面应用/2.png" alt="2"></p><p>拷贝出来如下图</p><p><img src="/2018/10/24/使用electron构建基于html的桌面应用/3.png" alt="3"></p><p>图中标记的文件夹是我们需要操作的文件夹</p><p>进入省略……… dist\resources文件夹新建一个文件夹为app或者自己喜欢的名字</p><p><img src="/2018/10/24/使用electron构建基于html的桌面应用/4.png" alt="4"></p><p>将我们刚才创建好的能够启动的项目文件拷贝到app文件夹中</p><p><img src="/2018/10/24/使用electron构建基于html的桌面应用/5.png" alt="5"></p><p>除上图标记不需要的文件外全部拷贝到app文件夹中拷贝后的结果是:</p><p><img src="/2018/10/24/使用electron构建基于html的桌面应用/6.png" alt="6"></p><p>这下我们在回到dist目录能看见一个叫<code>electron.exe</code>的可执行程序,我们双击他就可以运行我们的程序了。</p><p>效果如下图:</p><p><img src="/2018/10/24/使用electron构建基于html的桌面应用/7.png" alt="7"></p><h6 id="2-方法二:"><a href="#2-方法二:" class="headerlink" title="2. 方法二:"></a>2. 方法二:</h6><p>安装electron-packager 如果提示没有权限请在命令前面加上<code>sodu</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">lizhonglindeMacBook-Pro:nodetest lizhonglin$ npm install electron-packager --save</span><br></pre></td></tr></table></figure><p>安装好之后入下</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">+ [email protected]</span><br><span class="line">updated 19 packages in 8.189s</span><br><span class="line">lizhonglindeMacBook-Pro:nodetest lizhonglin$</span><br></pre></td></tr></table></figure><p>这下我们就可以开始打包了</p><p>大概的命令格式是这样的</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">electron-packager <location of project> <name of project> <platform> <architecture> <electron version> <optional options> <icon></span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">electron-packager <应用目录> <应用名称> <打包平台> --out <输出目录> <架构> <应用版本> <图标></span><br></pre></td></tr></table></figure><blockquote><p>命令说明: </p><ul><li>location of project:项目所在路径 </li><li>name of project:打包的项目名字 </li><li>platform:确定了你要构建哪个平台的应用(Windows、Mac 还是 Linux) </li><li>architecture:决定了使用 x86 还是 x64 还是两个架构都用 </li><li>electron version:electron 的版本 </li><li>optional options:可选选项</li><li>icon : 图标</li></ul></blockquote><p>我目前项目的情况,用终端切换到这个目录</p><p><img src="/2018/10/24/使用electron构建基于html的桌面应用/10.png" alt=""></p><p>但是这样并不够,会提示:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Unable to determine Electron version. Please specify an Electron version</span><br></pre></td></tr></table></figure><p>我们需要指明Electron version。这个参数是当前安装Electron的版本,不知道的可以直接electron就能看到了,我这里是1.4.13,经过改进后如下:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">electron-packager . nodetest --win --out ../demoApp --arch=x64 --electron-version=1.4.13 --icon=./o.ico</span><br></pre></td></tr></table></figure><p>为了每次不输入这么多命令 我们可以把写好的命令加入到<code>package.json</code>的配置文件中去。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"> "name": "testapp",</span><br><span class="line"> "version": "1.0.0",</span><br><span class="line"> "description": "跨平台应用",</span><br><span class="line"> "main": "main.js",</span><br><span class="line"> "scripts": {</span><br><span class="line"> "start": "electron .",</span><br><span class="line"> "package": "electron-packager . nodetest --win --out ../demoApp --arch=x64 --electron-version=1.4.13 --icon=./o.ico"</span><br><span class="line"> },</span><br><span class="line"> "author": "",</span><br><span class="line"> "license": "ISC",</span><br><span class="line"> "devDependencies": {</span><br><span class="line"> "electron": "^3.0.5",</span><br><span class="line"> "electron-prebuilt": "^1.4.13"</span><br><span class="line"> },</span><br><span class="line"> "dependencies": {</span><br><span class="line"> "electron-packager": "^12.2.0"</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>使用命令</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run-script package</span><br></pre></td></tr></table></figure><p>就可以开始打包了</p><p>执行完毕后,看到父级目录下已经产生了我们希望看到的应用文件夹。里面的应用程序demo.exe就可以直接打开桌面应用了。</p><p>这样我们就能使用打包好的东西了。如果是windows还可以使用<code>NSIS</code>工具打包成可以安装的桌面应用。见下一篇</p><p>欢迎转载收藏。</p><blockquote><p>作者:lizhonglin</p><p><strong>github:</strong> <a href="https://github.com/kujirashark/" target="_blank" rel="noopener">https://github.com/kujirashark/</a></p><p><strong>blog:</strong> <a href="https://kujirashark.github.io/" target="_blank" rel="noopener">https://kujirashark.github.io/</a></p></blockquote>]]></content>
<tags>
<tag> electron使用 </tag>
</tags>
</entry>
<entry>
<title>vue项目构建</title>
<link href="/2018/09/02/vue%E9%A1%B9%E7%9B%AE%E6%9E%84%E5%BB%BA/"/>
<url>/2018/09/02/vue%E9%A1%B9%E7%9B%AE%E6%9E%84%E5%BB%BA/</url>
<content type="html"><![CDATA[<p>Mac系统下面如何搭建vue环境</p><h5 id="必备软件"><a href="#必备软件" class="headerlink" title="必备软件"></a>必备软件</h5><p>Homebrew :Mac系统的包管理器,用于安装NodeJS和一些其他必需的工具软件</p><p>Node.js:JavaScript运行环境(runtime)</p><p>npm: node.js下的包管理器,NPM 能很好地和诸如 <a href="https://link.jianshu.com?t=https%3A%2F%2Fwebpack.js.org%2F" target="_blank" rel="noopener">webpack</a> 或 <a href="https://link.jianshu.com?t=http%3A%2F%2Fbrowserify.org%2F" target="_blank" rel="noopener">Browserify</a> 模块打包器配合使用</p><p>webpack : vue的组件都是.vue或者像微信小程序的.wxml或者.wxss等自定义组件都无法被用户端的浏览器解析,需要编译和打包成js文件 </p><p>vue-cli :用来生成模板的Vue工程</p><h5 id="1、安装Homebrew"><a href="#1、安装Homebrew" class="headerlink" title="1、安装Homebrew"></a>1、安装Homebrew</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"</span><br></pre></td></tr></table></figure><p>安装成功后,查看一下brew的版本信息:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew -v</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">lizhonglindeMacBook-Pro:~ lizhonglin$ brew -v</span><br><span class="line">Homebrew 1.7.2-98-gad66d54</span><br><span class="line">Homebrew/homebrew-core (git revision ed03; last commit 2018-08-03)</span><br><span class="line">lizhonglindeMacBook-Pro:~ lizhonglin$</span><br></pre></td></tr></table></figure><h5 id="2、安装node-js"><a href="#2、安装node-js" class="headerlink" title="2、安装node.js"></a>2、安装node.js</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew install nodejs</span><br></pre></td></tr></table></figure><p>安装完之后使用如下命令可以看到nodejs版本</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">node -v</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">lizhonglindeMacBook-Pro:~ lizhonglin$ node -v</span><br><span class="line">v8.11.1</span><br></pre></td></tr></table></figure><h5 id="3、获取nodejs模块安装目录访问权限"><a href="#3、获取nodejs模块安装目录访问权限" class="headerlink" title="3、获取nodejs模块安装目录访问权限"></a>3、获取nodejs模块安装目录访问权限</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo chmod -R 777 /usr/local/lib/node_modules/</span><br></pre></td></tr></table></figure><h5 id="4、安装淘宝镜像(npm)"><a href="#4、安装淘宝镜像(npm)" class="headerlink" title="4、安装淘宝镜像(npm)"></a>4、安装淘宝镜像(npm)</h5><p>安装成功之后,就可以用 cnpm 替代 npm</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo npm install -g cnpm –registry=https://registry.npm.taobao.org</span><br></pre></td></tr></table></figure><blockquote><p>如果出现:Unexpected end of JSON input while parsing near *** 等错误执行:npm cache clean –force(清除缓存)</p></blockquote><h5 id="5、安装全局vue-cli脚手架-用于帮助搭建所需的模板框架"><a href="#5、安装全局vue-cli脚手架-用于帮助搭建所需的模板框架" class="headerlink" title="5、安装全局vue-cli脚手架,用于帮助搭建所需的模板框架"></a>5、安装全局vue-cli脚手架,用于帮助搭建所需的模板框架</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo cnpm install -g vue-cli / sudo cnpm i -g vue-cli</span><br></pre></td></tr></table></figure><blockquote><p>输入:vue,回车,若出现vue如下信息说明表示成功</p></blockquote><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">lizhonglindeMacBook-Pro:lizhonglin$ vue</span><br><span class="line"></span><br><span class="line"> Usage: vue <command> [options]</span><br><span class="line"></span><br><span class="line"> Options:</span><br><span class="line"></span><br><span class="line"> -V, --version output the version number</span><br><span class="line"> -h, --help output usage information</span><br><span class="line"></span><br><span class="line"> Commands:</span><br><span class="line"></span><br><span class="line"> init generate a new project from a template</span><br><span class="line"> list list available official templates</span><br><span class="line"> build prototype a new project</span><br><span class="line"> create (for v3 warning only)</span><br><span class="line"> help [cmd] display help for [cmd]</span><br></pre></td></tr></table></figure><h5 id="使用vue-cli脚手架创建新项目"><a href="#使用vue-cli脚手架创建新项目" class="headerlink" title="使用vue-cli脚手架创建新项目"></a>使用vue-cli脚手架创建新项目</h5><blockquote><p>前提条件:已安装node可以正常使用npm命令,并全局安装vue-cli工具。</p></blockquote><h5 id="开始创建项目"><a href="#开始创建项目" class="headerlink" title="开始创建项目"></a>开始创建项目</h5><ul><li>选择项目所在的位置,通过命令行进入该目录(或者直接在该目录,右键,打开命令行)</li></ul><ul><li><p>使用vue初始化基于webpack的新项目</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vue init webpack xxx(项目名称)</span><br></pre></td></tr></table></figure><blockquote><p>项目创建过程中会提示是否安装eslint,可以选择不安装,否则项目编译过程中出现各种代码格式的问题;</p></blockquote><blockquote><p>Project name(工程名):回车<br>Project description(工程介绍):回车<br>Author:作者名<br>Vue build(是否安装编译器):回车<br>Install vue-router(是否安装Vue路由):回车<br>Use ESLint to lint your code(是否使用ESLint检查js代码):n<br>Set up unit tests(安装单元测试工具):n<br>Setup e2e tests with Nightwatch(是否安装端到端测试工具):n<br>Should we run <code>npm install</code> for you after the project has been created? (recommended):回车。</p></blockquote></li><li><p>项目创建完成后,安装基础模块</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cd xxx</span><br><span class="line">sudo npm install</span><br></pre></td></tr></table></figure><blockquote><p> 模块安装时间有可能会很长,依赖于你的网速</p></blockquote></li></ul><ul><li><p>安装完成之后可在开发模式下运行项目并预览项目效果</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run dev</span><br></pre></td></tr></table></figure><p>会出现这个就说明我们的项目已经启动成功</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">lizhonglindeMacBook-Pro:my-project lizhonglin$ npm run dev</span><br><span class="line"></span><br><span class="line">> [email protected] dev /Users/lizhonglin/Desktop/Code/vuep/my-project</span><br><span class="line">> webpack-dev-server --inline --progress --config build/webpack.dev.conf.js</span><br><span class="line"></span><br><span class="line"> 95% emitting b </span><br><span class="line"> DONE Compiled successfully in 2801ms 08:36:53</span><br><span class="line"></span><br><span class="line"> I Your application is running here: http://localhost:8080</span><br></pre></td></tr></table></figure></li></ul><p> 这下我们在浏览器中输入<code>http://localhost:8080</code> 就能看见如下效果</p><p><img src="/2018/09/02/vue项目构建/hello.png" alt="ell"></p><ul><li><p>如果项目可以正常启动,即可继续安装vue的辅助工具</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">npm install vue-router --save (路由管理模块)</span><br><span class="line">npm install vuex --save (状态管理模块)</span><br><span class="line">npm install vue-resource --save (网路请求模块)</span><br></pre></td></tr></table></figure></li></ul><h5 id="项目目录结构"><a href="#项目目录结构" class="headerlink" title="项目目录结构"></a>项目目录结构</h5><p> <img src="/2018/09/02/vue项目构建/项目结构.png" alt="目结"></p><h5 id="package-json"><a href="#package-json" class="headerlink" title="package.json"></a>package.json</h5><p><img src="/2018/09/02/vue项目构建/packeagejson.png" alt="ackeagejso"></p><blockquote><p>作者:lizhonglin</p><p><strong>github:</strong> <a href="https://github.com/kujirashark/" target="_blank" rel="noopener">https://github.com/kujirashark/</a></p><p><strong>blog:</strong> <a href="https://kujirashark.github.io/" target="_blank" rel="noopener">https://kujirashark.github.io/</a></p></blockquote>]]></content>
<tags>
<tag> vue安装 </tag>
</tags>
</entry>
<entry>
<title>Docker常见使用</title>
<link href="/2018/08/26/Docker%E5%B8%B8%E8%A7%81%E4%BD%BF%E7%94%A8/"/>
<url>/2018/08/26/Docker%E5%B8%B8%E8%A7%81%E4%BD%BF%E7%94%A8/</url>
<content type="html"><![CDATA[<h2 id="Centos7上安装和使用Docker"><a href="#Centos7上安装和使用Docker" class="headerlink" title="Centos7上安装和使用Docker"></a>Centos7上安装和使用Docker</h2><h4 id="Docker介绍"><a href="#Docker介绍" class="headerlink" title="Docker介绍"></a>Docker介绍</h4><p>Docker是一个为开发者和系统管理员在容器中开发、部署和运行的平台</p><p>特点:</p><p>灵活、轻量级、可互换、部署简单、扩展性强</p><p>应用场景:</p><p>Web应用的自动化大包和发布、自动化测试和持续集成、发布。</p><p>Docker从1.13版本之后采用时间线的方式作为版本号,分为社区版CE和企业版EE。</p><p>社区版是免费提供给个人开发者和小型团体使用的,企业版会提供额外的收费服务,比如经过官方测试认证过的基础设施、容器、插件等。</p><p>社区版按照stable和edge两种方式发布,每个季度更新stable版本,如17.06,17.09;每个月份更新edge版本,如17.09,17.10。</p><h5 id="需要知道的概念"><a href="#需要知道的概念" class="headerlink" title="需要知道的概念"></a>需要知道的概念</h5><p>镜像(Image)和容器(Container)</p><ul><li>容器是运行镜像后产生的</li><li>镜像是一个包含所有需要运行的文件组成的包,比如代码、可运行文件、库、环境变量和配置文件等。</li><li>镜像是容器运行的一个实例。(查看运行的容器命令:<code>docker ps</code>)</li></ul><p>容器和虚拟机的区别</p><ul><li>容器和普通的进程一样直接在主机操作系统上运行,不占用更多的资源</li><li>虚拟机直接模拟一个虚拟操作系统,程序最后是在虚拟操作系统里面运行,占用过多的资源</li></ul><p><img src="/2018/08/26/Docker常见使用/docker1.png" alt="ocker"></p><h5 id="一、安装docker"><a href="#一、安装docker" class="headerlink" title="一、安装docker"></a>一、安装docker</h5><h6 id="1、Docker-要求-CentOS-系统的内核版本高于-3-10-,查看本页面的前提条件来验证你的CentOS-版本是否支持-Docker-。"><a href="#1、Docker-要求-CentOS-系统的内核版本高于-3-10-,查看本页面的前提条件来验证你的CentOS-版本是否支持-Docker-。" class="headerlink" title="1、Docker 要求 CentOS 系统的内核版本高于 3.10 ,查看本页面的前提条件来验证你的CentOS 版本是否支持 Docker 。"></a>1、Docker 要求 CentOS 系统的内核版本高于 3.10 ,查看本页面的前提条件来验证你的CentOS 版本是否支持 Docker 。</h6><p>通过 <strong>uname -r</strong> 命令查看你当前的内核版本</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">uname -r</span><br></pre></td></tr></table></figure><h6 id="2、使用-root-权限登录-Centos。确保-yum-包更新到最新。"><a href="#2、使用-root-权限登录-Centos。确保-yum-包更新到最新。" class="headerlink" title="2、使用 root 权限登录 Centos。确保 yum 包更新到最新。"></a>2、使用 <code>root</code> 权限登录 Centos。确保 yum 包更新到最新。</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo yum update</span><br></pre></td></tr></table></figure><h6 id="3、卸载旧版本-如果安装过旧版本的话"><a href="#3、卸载旧版本-如果安装过旧版本的话" class="headerlink" title="3、卸载旧版本(如果安装过旧版本的话)"></a>3、卸载旧版本(如果安装过旧版本的话)</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo yum remove docker docker-common docker-selinux docker-engine</span><br></pre></td></tr></table></figure><h6 id="4、安装需要的软件包,-yum-util-提供yum-config-manager功能,另外两个是devicemapper驱动依赖的"><a href="#4、安装需要的软件包,-yum-util-提供yum-config-manager功能,另外两个是devicemapper驱动依赖的" class="headerlink" title="4、安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的"></a>4、安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo yum install -y yum-utils device-mapper-persistent-data lvm2</span><br></pre></td></tr></table></figure><h6 id="5、设置yum源"><a href="#5、设置yum源" class="headerlink" title="5、设置yum源"></a>5、设置yum源</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo</span><br></pre></td></tr></table></figure><h6 id="6、可以查看所有仓库中所有docker版本,并选择特定版本安装"><a href="#6、可以查看所有仓库中所有docker版本,并选择特定版本安装" class="headerlink" title="6、可以查看所有仓库中所有docker版本,并选择特定版本安装"></a>6、可以查看所有仓库中所有docker版本,并选择特定版本安装</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum list docker-ce --showduplicates | sort -r</span><br></pre></td></tr></table></figure><h6 id="7、安装docker"><a href="#7、安装docker" class="headerlink" title="7、安装docker"></a>7、安装docker</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo yum install docker-ce #由于repo中默认只开启stable仓库,故这里安装的是最新稳定版 18.06.0-ce</span><br><span class="line">$ sudo yum install <FQPN> # 例如:sudo yum install docker-ce-17.12.0.ce</span><br></pre></td></tr></table></figure><h6 id="8、启动并加入开机启动"><a href="#8、启动并加入开机启动" class="headerlink" title="8、启动并加入开机启动"></a>8、启动并加入开机启动</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo systemctl start docker</span><br><span class="line">sudo systemctl enable docker</span><br></pre></td></tr></table></figure><h6 id="9、验证安装是否成功-有client和service两部分表示docker安装启动都成功了"><a href="#9、验证安装是否成功-有client和service两部分表示docker安装启动都成功了" class="headerlink" title="9、验证安装是否成功(有client和service两部分表示docker安装启动都成功了)"></a>9、验证安装是否成功(有client和service两部分表示docker安装启动都成功了)</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">docker version</span><br><span class="line"></span><br><span class="line"># 验证docker是否成功</span><br><span class="line">sudo docker run hello-world</span><br></pre></td></tr></table></figure><p><img src="/2018/08/26/Docker常见使用/version.png" alt="ersio"></p><h5 id="二-、卸载docker"><a href="#二-、卸载docker" class="headerlink" title="二 、卸载docker"></a>二 、卸载docker</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo yum remove docker-ce </span><br><span class="line">sudo rm -rf varlib/docker</span><br></pre></td></tr></table></figure><h5 id="三、常用命令"><a href="#三、常用命令" class="headerlink" title="三、常用命令"></a>三、常用命令</h5><h6 id="1、查看docker信息"><a href="#1、查看docker信息" class="headerlink" title="1、查看docker信息"></a>1、查看docker信息</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker info</span><br></pre></td></tr></table></figure><h6 id="2-、列出docker容器-查看docker镜像"><a href="#2-、列出docker容器-查看docker镜像" class="headerlink" title="2 、列出docker容器/查看docker镜像"></a>2 、列出docker容器/查看docker镜像</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker image ls</span><br></pre></td></tr></table></figure><h6 id="3、创建docker镜像"><a href="#3、创建docker镜像" class="headerlink" title="3、创建docker镜像"></a>3、创建docker镜像</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker build -t myproject .</span><br></pre></td></tr></table></figure><h6 id="4、重新-启动-停止-docker"><a href="#4、重新-启动-停止-docker" class="headerlink" title="4、重新/启动/停止 docker"></a>4、重新/启动/停止 docker</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">systemctl restart docker</span><br><span class="line">systemctl start docker</span><br><span class="line">systemctl stop docker</span><br></pre></td></tr></table></figure><p>未完待续……</p>]]></content>
<tags>
<tag> Docker使用 </tag>
</tags>
</entry>
<entry>
<title>vim 操作命令大全</title>
<link href="/2018/08/21/vim-%E6%93%8D%E4%BD%9C%E5%91%BD%E4%BB%A4%E5%A4%A7%E5%85%A8/"/>
<url>/2018/08/21/vim-%E6%93%8D%E4%BD%9C%E5%91%BD%E4%BB%A4%E5%A4%A7%E5%85%A8/</url>
<content type="html"><![CDATA[<p>【转发】曾经使用了两年多的Vim,手册也翻过一遍。虽然现在不怎么用vim了,曾经的笔记还是贴出来,与喜欢vim的朋友分享。</p><h1 id="1-关于Vim"><a href="#1-关于Vim" class="headerlink" title="1. 关于Vim"></a>1. 关于Vim</h1><p>vim是我最喜欢的编辑器,也是<a href="http://lib.csdn.net/base/linux" target="_blank" rel="noopener">Linux</a>下第二强大的编辑器。 虽然emacs是公认的世界第一,我认为使用emacs并没有使用vi进行编辑来得高效。 如果是初学vi,运行一下vimtutor是个聪明的决定。 (如果你的系统环境不是中文,而你想使用中文的vimtutor,就运行vimtutor zh)</p><h2 id="1-1-Vim的几种模式"><a href="#1-1-Vim的几种模式" class="headerlink" title="1.1 Vim的几种模式"></a>1.1 Vim的几种模式</h2><ul><li>正常模式:可以使用快捷键命令,或按:输入命令行。</li><li>插入模式:可以输入文本,在正常模式下,按i、a、o等都可以进入插入模式。</li><li>可视模式:正常模式下按v可以进入可视模式, 在可视模式下,移动光标可以选择文本。按V进入可视行模式, 总是整行整行的选中。ctrl+v进入可视块模式。</li><li>替换模式:正常模式下,按R进入。</li></ul><h1 id="2-启动Vim"><a href="#2-启动Vim" class="headerlink" title="2. 启动Vim"></a>2. 启动Vim</h1><ul><li>vim -c cmd file: 在打开文件前,先执行指定的命令;</li><li>vim -r file: 恢复上次异常退出的文件;</li><li>vim -R file: 以只读的方式打开文件,但可以强制保存;</li><li>vim -M file: 以只读的方式打开文件,不可以强制保存;</li><li>vim -y num file: 将编辑窗口的大小设为num行;</li><li>vim + file: 从文件的末尾开始;</li><li>vim +num file: 从第num行开始;</li><li>vim +/string file: 打开file,并将光标停留在第一个找到的string上。</li><li>vim –remote file: 用已有的vim进程打开指定的文件。 如果你不想启用多个vim会话,这个很有用。但要注意, 如果你用vim,会寻找名叫VIM的服务器;如果你已经有一个gvim在运行了, 你可以用gvim –remote file在已有的gvim中打开文件。</li></ul><h1 id="3-文档操作"><a href="#3-文档操作" class="headerlink" title="3. 文档操作"></a>3. 文档操作</h1><ul><li>:e file –关闭当前编辑的文件,并开启新的文件。 如果对当前文件的修改未保存,vi会警告。</li><li>:e! file –放弃对当前文件的修改,编辑新的文件。</li><li>:e+file – 开始新的文件,并从文件尾开始编辑。</li><li>:e+n file – 开始新的文件,并从第n行开始编辑。</li><li>:enew –编译一个未命名的新文档。(CTRL-W n)</li><li>:e – 重新加载当前文档。</li><li>:e! – 重新加载当前文档,并丢弃已做的改动。</li><li>:e#或ctrl+^ – 回到刚才编辑的文件,很实用。</li><li>:f或ctrl+g – 显示文档名,是否修改,和光标位置。</li><li>:f filename – 改变编辑的文件名,这时再保存相当于另存为。</li><li>gf – 打开以光标所在字符串为文件名的文件。</li><li>:w – 保存修改。</li><li>:n1,n2w filename – 选择性保存从某n1行到另n2行的内容。</li><li>:wq – 保存并退出。</li><li>ZZ – 保存并退出。</li><li>:x – 保存并退出。</li><li>:q[uit] ——退出当前窗口。(CTRL-W q或CTRL-W CTRL-Q)</li><li>:saveas newfilename – 另存为</li><li>:browse e – 会打开一个文件浏览器让你选择要编辑的文件。 如果是终端中,则会打开netrw的文件浏览窗口; 如果是gvim,则会打开一个图形界面的浏览窗口。 实际上:browse后可以跟任何编辑文档的命令,如sp等。 用browse打开的起始目录可以由browsedir来设置:<ul><li>:set browsedir=last – 用上次访问过的目录(默认);</li><li>:set browsedir=buffer – 用当前文件所在目录;</li><li>:set browsedir=current – 用当前工作目录;</li></ul></li><li>:Sex – 水平分割一个窗口,浏览文件系统;</li><li>:Vex – 垂直分割一个窗口,浏览文件系统;</li></ul><h1 id="4-光标的移动"><a href="#4-光标的移动" class="headerlink" title="4. 光标的移动"></a>4. 光标的移动</h1><h2 id="4-1-基本移动"><a href="#4-1-基本移动" class="headerlink" title="4.1 基本移动"></a>4.1 基本移动</h2><p>以下移动都是在normal模式下。</p><ul><li>h或退格: 左移一个字符;</li><li>l或空格: 右移一个字符;</li><li>j: 下移一行;</li><li>k: 上移一行;</li><li>gj: 移动到一段内的下一行;</li><li>gk: 移动到一段内的上一行;</li><li>+或Enter: 把光标移至下一行第一个非空白字符。</li><li>-: 把光标移至上一行第一个非空白字符。</li><li>w: 前移一个单词,光标停在下一个单词开头;</li><li>W: 移动下一个单词开头,但忽略一些标点;</li><li>e: 前移一个单词,光标停在下一个单词末尾;</li><li>E: 移动到下一个单词末尾,如果词尾有标点,则移动到标点;</li><li>b: 后移一个单词,光标停在上一个单词开头;</li><li>B: 移动到上一个单词开头,忽略一些标点;</li><li>ge: 后移一个单词,光标停在上一个单词末尾;</li><li>gE: 同 ge ,不过‘单词’包含单词相邻的标点。</li><li>(: 前移1句。</li><li>): 后移1句。</li><li>{: 前移1段。</li><li>}: 后移1段。</li><li>fc: 把光标移到同一行的下一个c字符处</li><li>Fc: 把光标移到同一行的上一个c字符处</li><li>tc: 把光标移到同一行的下一个c字符前</li><li>Tc: 把光标移到同一行的上一个c字符后</li><li>;: 配合f & t使用,重复一次</li><li>,: 配合f & t使用,反向重复一次</li></ul><p>上面的操作都可以配合n使用,比如在正常模式(下面会讲到)下输入3h, 则光标向左移动3个字符。</p><ul><li>0: 移动到行首。</li><li>g0: 移到光标所在屏幕行行首。</li><li>^: 移动到本行第一个非空白字符。</li><li>g^: 同 ^ ,但是移动到当前屏幕行第一个非空字符处。</li><li>:移动到行尾。</li><listyle=”list−style:inherit!important”>g:移动到行尾。<listyle=”list−style:inherit!important”>g: 移动光标所在屏幕行行尾。<li>n|: 把光标移到递n列上。</li><li>nG: 到文件第n行。</li><li>:n<cr> 移动到第n行。</cr></li><li>:$<cr> 移动到最后一行。</cr></li><li>H: 把光标移到屏幕最顶端一行。</li><li>M: 把光标移到屏幕中间一行。</li><li>L: 把光标移到屏幕最底端一行。</li><li>gg: 到文件头部。</li><li>G: 到文件尾部。</li></ul><h2 id="4-2-翻屏"><a href="#4-2-翻屏" class="headerlink" title="4.2 翻屏"></a>4.2 翻屏</h2><ul><li>ctrl+f: 下翻一屏。</li><li>ctrl+b: 上翻一屏。</li><li>ctrl+d: 下翻半屏。</li><li>ctrl+u: 上翻半屏。</li><li>ctrl+e: 向下滚动一行。</li><li>ctrl+y: 向上滚动一行。</li><li>n%: 到文件n%的位置。</li><li>zz: 将当前行移动到屏幕中央。</li><li>zt: 将当前行移动到屏幕顶端。</li><li>zb: 将当前行移动到屏幕底端。</li></ul><h2 id="4-3-标记"><a href="#4-3-标记" class="headerlink" title="4.3 标记"></a>4.3 标记</h2><p>使用标记可以快速移动。到达标记后,可以用Ctrl+o返回原来的位置。 Ctrl+o和Ctrl+i 很像浏览器上的 <em>后退</em> 和 <em>前进</em> 。</p><ul><li>m{a-z}: 标记光标所在位置,局部标记,只用于当前文件。</li><li>m{A-Z}: 标记光标所在位置,全局标记。标记之后,退出Vim, 重新启动,标记仍然有效。</li><li>`{a-z}: 移动到标记位置。</li><li>‘{a-z}: 移动到标记行的行首。</li><li>`{0-9}:回到上[2-10]次关闭vim时最后离开的位置。</li><li>“: 移动到上次编辑的位置。”也可以,不过“精确到列,而”精确到行 。如果想跳转到更老的位置,可以按C-o,跳转到更新的位置用C-i。</li><li>`”: 移动到上次离开的地方。</li><li>`.: 移动到最后改动的地方。</li><li>:marks 显示所有标记。</li><li>:delmarks a b – 删除标记a和b。</li><li>:delmarks a-c – 删除标记a、b和c。</li><li>:delmarks a c-f – 删除标记a、c、d、e、f。</li><li>:delmarks! – 删除当前缓冲区的所有标记。</li><li>:help mark-motions 查看更多关于mark的知识。</li></ul><h1 id="5-插入文本"><a href="#5-插入文本" class="headerlink" title="5. 插入文本"></a>5. 插入文本</h1><h2 id="5-1-基本插入"><a href="#5-1-基本插入" class="headerlink" title="5.1 基本插入"></a>5.1 基本插入</h2><ul><li>i: 在光标前插入;一个小技巧:按8,再按i,进入插入模式,输入=, 按esc进入命令模式,就会出现8个=。 这在插入分割线时非常有用,如30i+<esc>就插入了36个+组成的分割线。</esc></li><li>I: 在当前行第一个非空字符前插入;</li><li>gI: 在当前行第一列插入;</li><li>a: 在光标后插入;</li><li>A: 在当前行最后插入;</li><li>o: 在下面新建一行插入;</li><li>O: 在上面新建一行插入;</li><li>:r filename在当前位置插入另一个文件的内容。</li><li>:[n]r filename在第n行插入另一个文件的内容。</li><li>:r !date 在光标处插入当前日期与时间。同理,:r !command可以将其它shell命令的输出插入当前文档。</li></ul><h2 id="5-2-改写插入"><a href="#5-2-改写插入" class="headerlink" title="5.2 改写插入"></a>5.2 改写插入</h2><ul><li>c[n]w: 改写光标后1(n)个词。</li><li>c[n]l: 改写光标后n个字母。</li><li>c[n]h: 改写光标前n个字母。</li><li>[n]cc: 修改当前[n]行。</li><li>[n]s: 以输入的文本替代光标之后1(n)个字符,相当于c[n]l。</li><li>[n]S: 删除指定数目的行,并以所输入文本代替之。</li></ul><p>注意,类似cnw,dnw,ynw的形式同样可以写为ncw,ndw,nyw。</p><h1 id="6-剪切复制和寄存器"><a href="#6-剪切复制和寄存器" class="headerlink" title="6. 剪切复制和寄存器"></a>6. 剪切复制和寄存器</h1><h2 id="6-1-剪切和复制、粘贴"><a href="#6-1-剪切和复制、粘贴" class="headerlink" title="6.1 剪切和复制、粘贴"></a>6.1 剪切和复制、粘贴</h2><ul><li>[n]x: 剪切光标右边n个字符,相当于d[n]l。</li><li>[n]X: 剪切光标左边n个字符,相当于d[n]h。</li><li>y: 复制在可视模式下选中的文本。</li><li>yy or Y: 复制整行文本。</li><li>y[n]w: 复制一(n)个词。</li><li>y[n]l: 复制光标右边1(n)个字符。</li><li>y[n]h: 复制光标左边1(n)个字符。</li><li>y: 从光标当前位置复制到行尾。</li><li style="list-style:inherit!important">y0: 从光标当前位置复制到行首。</li><li style="list-style:inherit!important">:m,ny<cr> 复制m行到n行的内容。</li><li style="list-style:inherit!important">y1G或ygg: 复制光标以上的所有行。</li><li style="list-style:inherit!important">yG: 复制光标以下的所有行。</li><li style="list-style:inherit!important">yaw和yas:复制一个词和复制一个句子,即使光标不在词首和句首也没关系。</li><li style="list-style:inherit!important">d: 删除(剪切)在可视模式下选中的文本。</li><li style="list-style:inherit!important">d: 从光标当前位置复制到行尾。</li><li style="list-style:inherit!important">y0: 从光标当前位置复制到行首。</li><li style="list-style:inherit!important">:m,ny<cr> 复制m行到n行的内容。</li><li style="list-style:inherit!important">y1G或ygg: 复制光标以上的所有行。</li><li style="list-style:inherit!important">yG: 复制光标以下的所有行。</li><li style="list-style:inherit!important">yaw和yas:复制一个词和复制一个句子,即使光标不在词首和句首也没关系。</li><li style="list-style:inherit!important">d: 删除(剪切)在可视模式下选中的文本。</li><li style="list-style:inherit!important">dor D: 删除(剪切)当前位置到行尾的内容。</li><li>d[n]w: 删除(剪切)1(n)个单词</li><li>d[n]l: 删除(剪切)光标右边1(n)个字符。</li><li>d[n]h: 删除(剪切)光标左边1(n)个字符。</li><li>d0: 删除(剪切)当前位置到行首的内容</li><li>[n] dd: 删除(剪切)1(n)行。</li><li>:m,nd<cr> 剪切m行到n行的内容。</cr></li><li>d1G或dgg: 剪切光标以上的所有行。</li><li>dG: 剪切光标以下的所有行。</li><li>daw和das:剪切一个词和剪切一个句子,即使光标不在词首和句首也没关系。</li><li>d/f<cr>:这是一个比较高级的组合命令,它将删除当前位置 到下一个f之间的内容。</cr></li><li>p: 在光标之后粘贴。</li><li>P: 在光标之前粘贴。</li></ul><h2 id="6-2-文本对象"><a href="#6-2-文本对象" class="headerlink" title="6.2 文本对象"></a>6.2 文本对象</h2><ul><li>aw:一个词</li><li>as:一句。</li><li>ap:一段。</li><li>ab:一块(包含在圆括号中的)。</li></ul><p>y, d, c, v都可以跟文本对象。</p><h2 id="6-3-寄存器"><a href="#6-3-寄存器" class="headerlink" title="6.3 寄存器"></a>6.3 寄存器</h2><ul><li>a-z:都可以用作寄存器名。”ayy把当前行的内容放入a寄存器。</li><li>A-Z:用大写字母索引寄存器,可以在寄存器中追加内容。 如”Ayy把当前行的内容追加到a寄存器中。</li><li>:reg 显示所有寄存器的内容。</li><li>“”:不加寄存器索引时,默认使用的寄存器。</li><li>“<em>:当前选择缓冲区,”</em>yy把当前行的内容放入当前选择缓冲区。</li><li>“+:系统剪贴板。”+yy把当前行的内容放入系统剪贴板。</li></ul><h1 id="7-查找与替换"><a href="#7-查找与替换" class="headerlink" title="7. 查找与替换"></a>7. 查找与替换</h1><h2 id="7-1-查找"><a href="#7-1-查找" class="headerlink" title="7.1 查找"></a>7.1 查找</h2><ul><li>/something: 在后面的文本中查找something。</li><li>?something: 在前面的文本中查找something。</li><li>/pattern/+number: 将光标停在包含pattern的行后面第number行上。</li><li>/pattern/-number: 将光标停在包含pattern的行前面第number行上。</li><li>n: 向后查找下一个。</li><li>N: 向前查找下一个。</li></ul><p>可以用grep或vimgrep查找一个模式都在哪些地方出现过,</p><p>其中:grep是调用外部的grep程序,而:vimgrep是vim自己的查找算法。</p><p>用法为: :vim[grep]/pattern/[g][j] files</p><p>g的含义是如果一个模式在一行中多次出现,则这一行也在结果中多次出现。</p><p>j的含义是grep结束后,结果停在第j项,默认是停在第一项。</p><p>vimgrep前面可以加数字限定搜索结果的上限,如</p><p>:1vim/pattern/ % 只查找那个模式在本文件中的第一个出现。</p><p>其实vimgrep在读纯文本电子书时特别有用,可以生成导航的目录。</p><p>比如电子书中每一节的标题形式为:n. xxxx。你就可以这样:</p><p>:vim/^d{1,}./ %</p><p>然后用:cw或:copen查看结果,可以用C-w H把quickfix窗口移到左侧,</p><p>就更像个目录了。</p><h2 id="7-2-替换"><a href="#7-2-替换" class="headerlink" title="7.2 替换"></a>7.2 替换</h2><ul><li>:s/old/new - 用new替换当前行第一个old。</li><li>:s/old/new/g - 用new替换当前行所有的old。</li><li>:n1,n2s/old/new/g - 用new替换文件n1行到n2行所有的old。</li><li>:%s/old/new/g - 用new替换文件中所有的old。</li><li>:%s/^/xxx/g - 在每一行的行首插入xxx,^表示行首。</li><li>:%s//xxx/g−在每一行的行尾插入xxx,/xxx/g−在每一行的行尾插入xxx,表示行尾。</li><li>所有替换命令末尾加上c,每个替换都将需要用户确认。 如:%s/old/new/gc,加上i则忽略大小写(ignore)。</li></ul><p>还有一种比替换更灵活的方式,它是匹配到某个模式后执行某种命令,</p><p>语法为 :[range]g/pattern/command</p><p>例如 :%g/^ xyz/normal dd。</p><p>表示对于以一个空格和xyz开头的行执行normal模式下的dd命令。</p><p>关于range的规定为:</p><ul><li>如果不指定range,则表示当前行。</li><li>m,n: 从m行到n行。</li><li>0: 最开始一行(可能是这样)。</li><li>$: 最后一行</li><li>.: 当前行</li><li>%: 所有行</li></ul><h2 id="7-3-正则表达式"><a href="#7-3-正则表达式" class="headerlink" title="7.3 正则表达式"></a>7.3 正则表达式</h2><p>高级的查找替换就要用到正则表达式。</p><ul><li>\d: 表示十进制数(我猜的)</li><li>\s: 表示空格</li><li>\S: 非空字符</li><li>\a: 英文字母</li><li>|: 表示 或</li><li>.: 表示.</li><li>{m,n}: 表示m到n个字符。这要和 \s与\a等连用,如 \a{m,n} 表示m 到n个英文字母。</li><li>{m,}: 表示m到无限多个字符。</li><li>**: 当前目录下的所有子目录。</li></ul><p>:help pattern得到更多帮助。</p><hr><h1 id="8-排版"><a href="#8-排版" class="headerlink" title="8. 排版"></a>8. 排版</h1><h2 id="8-1-基本排版"><a href="#8-1-基本排版" class="headerlink" title="8.1 基本排版"></a>8.1 基本排版</h2><ul><li><p><< 向左缩进一个shiftwidth</p></li><li><blockquote><blockquote><p>向右缩进一个shiftwidth</p></blockquote></blockquote></li><li><p>:ce(nter) 本行文字居中</p></li><li><p>:le(ft) 本行文字靠左</p></li><li><p>:ri(ght) 本行文字靠右</p></li><li><p>gq 对选中的文字重排,即对过长的文字进行断行</p></li><li><p>gqq 重排当前行</p></li><li><p>gqnq 重排n行</p></li><li><p>gqap 重排当前段</p></li><li><p>gqnap 重排n段</p></li><li><p>gqnj 重排当前行和下面n行</p></li><li><p>gqQ 重排当前段对文章末尾</p></li><li><p>J 拼接当前行和下一行</p></li><li><p>gJ 同 J ,不过合并后不留空格。</p></li></ul><h2 id="8-2-拼写检查"><a href="#8-2-拼写检查" class="headerlink" title="8.2 拼写检查"></a>8.2 拼写检查</h2><ul><li>:set spell-开启拼写检查功能</li><li>:set nospell-关闭拼写检查功能</li><li>]s-移到下一个拼写错误的单词</li><li>[s-作用与上一命令类似,但它是从相反方向进行搜索</li><li>z=-显示一个有关拼写错误单词的列表,可从中选择</li><li>zg-告诉拼写检查器该单词是拼写正确的</li><li>zw-与上一命令相反,告诉拼写检查器该单词是拼写错误的</li></ul><h2 id="8-3-统计字数"><a href="#8-3-统计字数" class="headerlink" title="8.3 统计字数"></a>8.3 统计字数</h2><p>g ^g可以统计文档字符数,行数。 将光标放在最后一个字符上,用字符数减去行数可以粗略统计中文文档的字数。 以上对 Mac 或 Unix 的文件格式适用。 如果是 Windows 文件格式(即换行符有两个字节),字数的统计方法为: 字符数 - 行数 * 2。</p><hr><h1 id="9-编辑多个文件"><a href="#9-编辑多个文件" class="headerlink" title="9. 编辑多个文件"></a>9. 编辑多个文件</h1><h2 id="9-1-一次编辑多个文件"><a href="#9-1-一次编辑多个文件" class="headerlink" title="9.1 一次编辑多个文件"></a>9.1 一次编辑多个文件</h2><p>我们可以一次打开多个文件,如</p><blockquote><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">> vi a.txt b.txt c.txt</span><br><span class="line">></span><br></pre></td></tr></table></figure></blockquote><ul><li>使用:next(:n)编辑下一个文件。</li><li>:2n 编辑下2个文件。</li><li>使用:previous或:N编辑上一个文件。</li><li>使用:wnext,保存当前文件,并编辑下一个文件。</li><li>使用:wprevious,保存当前文件,并编辑上一个文件。</li><li>使用:args 显示文件列表。</li><li>:n filenames或:args filenames 指定新的文件列表。</li><li>vi -o filenames 在水平分割的多个窗口中编辑多个文件。</li><li>vi -O filenames 在垂直分割的多个窗口中编辑多个文件。</li></ul><h2 id="9-2-多标签编辑"><a href="#9-2-多标签编辑" class="headerlink" title="9.2 多标签编辑"></a>9.2 多标签编辑</h2><ul><li>vim -p files: 打开多个文件,每个文件占用一个标签页。</li><li>:tabe, tabnew – 如果加文件名,就在新的标签中打开这个文件, 否则打开一个空缓冲区。</li><li>^w gf – 在新的标签页里打开光标下路径指定的文件。</li><li>:tabn – 切换到下一个标签。Control + PageDown,也可以。</li><li>:tabp – 切换到上一个标签。Control + PageUp,也可以。</li><li>[n] gt – 切换到下一个标签。如果前面加了 n , 就切换到第n个标签。第一个标签的序号就是1。</li><li>:tab split – 将当前缓冲区的内容在新页签中打开。</li><li>:tabc[lose] – 关闭当前的标签页。</li><li>:tabo[nly] – 关闭其它的标签页。</li><li>:tabs – 列出所有的标签页和它们包含的窗口。</li><li>:tabm[ove][N] – 移动标签页,移动到第N个标签页之后。 如 tabm 0 当前标签页,就会变成第一个标签页。</li></ul><h2 id="9-3-缓冲区"><a href="#9-3-缓冲区" class="headerlink" title="9.3 缓冲区"></a>9.3 缓冲区</h2><ul><li>:buffers或:ls或:files 显示缓冲区列表。</li><li>ctrl+^:在最近两个缓冲区间切换。</li><li>:bn – 下一个缓冲区。</li><li>:bp – 上一个缓冲区。</li><li>:bl – 最后一个缓冲区。</li><li>:b[n]或:[n]b – 切换到第n个缓冲区。</li><li>:nbw(ipeout) – 彻底删除第n个缓冲区。</li><li>:nbd(elete) – 删除第n个缓冲区,并未真正删除,还在unlisted列表中。</li><li>:ba[ll] – 把所有的缓冲区在当前页中打开,每个缓冲区占一个窗口。</li></ul><h1 id="10-分屏编辑"><a href="#10-分屏编辑" class="headerlink" title="10. 分屏编辑"></a>10. 分屏编辑</h1><ul><li>vim -o file1 file2:水平分割窗口,同时打开file1和file2</li><li>vim -O file1 file2:垂直分割窗口,同时打开file1和file2</li></ul><h2 id="10-1-水平分割"><a href="#10-1-水平分割" class="headerlink" title="10.1 水平分割"></a>10.1 水平分割</h2><ul><li>:split(:sp) – 把当前窗水平分割成两个窗口。(CTRL-W s 或 CTRL-W CTRL-S) 注意如果在终端下,CTRL-S可能会冻结终端,请按CTRL-Q继续。</li><li>:split filename – 水平分割窗口,并在新窗口中显示另一个文件。</li><li>:nsplit(:nsp) – 水平分割出一个n行高的窗口。</li><li>:[N]new – 水平分割出一个N行高的窗口,并编辑一个新文件。 (CTRL-W n或 CTRL-W CTRL-N)</li><li>ctrl+w f –水平分割出一个窗口,并在新窗口打开名称为光标所在词的文件 。</li><li>C-w C-^ – 水平分割一个窗口,打开刚才编辑的文件。</li></ul><h2 id="10-2-垂直分割"><a href="#10-2-垂直分割" class="headerlink" title="10.2 垂直分割"></a>10.2 垂直分割</h2><ul><li>:vsplit(:vsp) – 把当前窗口分割成水平分布的两个窗口。 (CTRL-W v或CTRL CTRL-V)</li><li>:[N]vne[w] – 垂直分割出一个新窗口。</li><li>:vertical 水平分割的命令: 相应的垂直分割。</li></ul><h2 id="10-3-关闭子窗口"><a href="#10-3-关闭子窗口" class="headerlink" title="10.3 关闭子窗口"></a>10.3 关闭子窗口</h2><ul><li>:qall – 关闭所有窗口,退出vim。</li><li>:wall – 保存所有修改过的窗口。</li><li>:only – 只保留当前窗口,关闭其它窗口。(CTRL-W o)</li><li>:close – 关闭当前窗口,CTRL-W c能实现同样的功能。 (象 :q :x同样工作 )</li></ul><h2 id="10-4-调整窗口大小"><a href="#10-4-调整窗口大小" class="headerlink" title="10.4 调整窗口大小"></a>10.4 调整窗口大小</h2><ul><li>ctrl+w + –当前窗口增高一行。也可以用n增高n行。</li><li>ctrl+w - –当前窗口减小一行。也可以用n减小n行。</li><li>ctrl+w _ –当前窗口扩展到尽可能的大。也可以用n设定行数。</li><li>:resize n – 当前窗口n行高。</li><li>ctrl+w = – 所有窗口同样高度。</li><li>n ctrl+w _ – 当前窗口的高度设定为n行。</li><li>ctrl+w < –当前窗口减少一列。也可以用n减少n列。</li><li>ctrl+w > –当前窗口增宽一列。也可以用n增宽n列。</li><li>ctrl+w | –当前窗口尽可能的宽。也可以用n设定列数。</li></ul><h2 id="10-5-切换和移动窗口"><a href="#10-5-切换和移动窗口" class="headerlink" title="10.5 切换和移动窗口"></a>10.5 切换和移动窗口</h2><p>如果支持鼠标,切换和调整子窗口的大小就简单了。</p><ul><li>ctrl+w ctrl+w: 切换到下一个窗口。或者是ctrl+w w。</li><li>ctrl+w p: 切换到前一个窗口。</li><li>ctrl+w h(l,j,k):切换到左(右,下,上)的窗口。</li><li>ctrl+w t(b):切换到最上(下)面的窗口。<br></li><li>ctrl+w H(L,K,J): 将当前窗口移动到最左(右、上、下)面。</li><li>ctrl+w r:旋转窗口的位置。</li><li>ctrl+w T: 将当前的窗口移动到新的标签页上。</li></ul><h1 id="11-快速编辑"><a href="#11-快速编辑" class="headerlink" title="11. 快速编辑"></a>11. 快速编辑</h1><h2 id="11-1-改变大小写"><a href="#11-1-改变大小写" class="headerlink" title="11.1 改变大小写"></a>11.1 改变大小写</h2><ul><li>~: 反转光标所在字符的大小写。</li><li>可视模式下的U或u:把选中的文本变为大写或小写。</li><li>gu(U)接范围(如$,或G),可以把从光标当前位置到指定位置之间字母全部 转换成小写或大写。如ggguG,就是把开头到最后一行之间的字母全部变为小 写。再如gu5j,把当前行和下面四行全部变成小写。</li></ul><h2 id="11-2-替换(normal模式)"><a href="#11-2-替换(normal模式)" class="headerlink" title="11.2 替换(normal模式)"></a>11.2 替换(normal模式)</h2><ul><li>r: 替换光标处的字符,同样支持汉字。</li><li>R: 进入替换模式,按esc回到正常模式。</li></ul><h2 id="11-3-撤消与重做(normal模式)"><a href="#11-3-撤消与重做(normal模式)" class="headerlink" title="11.3 撤消与重做(normal模式)"></a>11.3 撤消与重做(normal模式)</h2><ul><li>[n] u: 取消一(n)个改动。</li><li>:undo 5 – 撤销5个改变。</li><li>:undolist – 你的撤销历史。</li><li>ctrl + r: 重做最后的改动。</li><li>U: 取消当前行中所有的改动。</li><li>:earlier 4m – 回到4分钟前</li><li>:later 55s – 前进55秒</li></ul><h2 id="11-4-宏"><a href="#11-4-宏" class="headerlink" title="11.4 宏"></a>11.4 宏</h2><ul><li>. –重复上一个编辑动作</li><li>qa:开始录制宏a(键盘操作记录)</li><li>q:停止录制</li><li>@a:播放宏a</li></ul><h1 id="12-编辑特殊文件"><a href="#12-编辑特殊文件" class="headerlink" title="12. 编辑特殊文件"></a>12. 编辑特殊文件</h1><h2 id="12-1-文件加解密"><a href="#12-1-文件加解密" class="headerlink" title="12.1 文件加解密"></a>12.1 文件加解密</h2><ul><li>vim -x file: 开始编辑一个加密的文件。</li><li>:X – 为当前文件设置密码。</li><li>:set key= – 去除文件的密码。</li></ul><p><a href="http://www.cnblogs.com/jiqingwu/admin/vim-quick-edit.html" target="_blank" rel="noopener">这里是</a> 滇狐总结的比较高级的vi技巧。</p><h2 id="12-2-文件的编码"><a href="#12-2-文件的编码" class="headerlink" title="12.2 文件的编码"></a>12.2 文件的编码</h2><ul><li>:e ++enc=utf8 filename, 让vim用utf-8的编码打开这个文件。</li><li>:w ++enc=gbk,不管当前文件什么编码,把它转存成gbk编码。</li><li>:set fenc或:set fileencoding,查看当前文件的编码。</li><li>在vimrc中添加set fileencoding=ucs-bom,utf-8,cp936,vim会根据要打开的文件选择合适的编码。 注意:编码之间不要留空格。 cp936对应于gbk编码。 ucs-bom对应于windows下的文件格式。</li></ul><p>让vim 正确处理文件格式和文件编码,有赖于 <a href="http://www.cnblogs.com/jiqingwu/admin/vimrc.html" target="_blank" rel="noopener">~/.vimrc的正确配置</a></p><h2 id="12-3-文件格式"><a href="#12-3-文件格式" class="headerlink" title="12.3 文件格式"></a>12.3 文件格式</h2><p>大致有三种文件格式:unix, dos, mac. 三种格式的区别主要在于回车键的编码:dos 下是回车加换行,unix 下只有 换行符,mac 下只有回车符。</p><ul><li>:e ++ff=dos filename, 让vim用dos格式打开这个文件。</li><li>:w ++ff=mac filename, 以mac格式存储这个文件。</li><li>:set ff,显示当前文件的格式。</li><li>在vimrc中添加set fileformats=unix,dos,mac,让vim自动识别文件格式。</li></ul><h1 id="13-编程辅助"><a href="#13-编程辅助" class="headerlink" title="13. 编程辅助"></a>13. 编程辅助</h1><h2 id="13-1-一些按键"><a href="#13-1-一些按键" class="headerlink" title="13.1 一些按键"></a>13.1 一些按键</h2><ul><li>gd: 跳转到局部变量的定义处;</li><li>gD: 跳转到全局变量的定义处,从当前文件开头开始搜索;</li><li>g;: 上一个修改过的地方;</li><li>g,: 下一个修改过的地方;</li><li>[[: 跳转到上一个函数块开始,需要有单独一行的{。</li><li>]]: 跳转到下一个函数块开始,需要有单独一行的{。</li><li>[]: 跳转到上一个函数块结束,需要有单独一行的}。</li><li>][: 跳转到下一个函数块结束,需要有单独一行的}。</li><li>[{: 跳转到当前块开始处;</li><li>]}: 跳转到当前块结束处;</li><li>[/: 跳转到当前注释块开始处;</li><li>]/: 跳转到当前注释块结束处;</li><li>%: 不仅能移动到匹配的(),{}或[]上,而且能在#if,#else, #endif之间跳跃。</li></ul><p>下面的括号匹配对编程很实用的。</p><ul><li>ci’, di’, yi’:修改、剪切或复制’之间的内容。</li><li>ca’, da’, ya’:修改、剪切或复制’之间的内容,包含’。</li><li>ci”, di”, yi”:修改、剪切或复制”之间的内容。</li><li>ca”, da”, ya”:修改、剪切或复制”之间的内容,包含”。</li><li>ci(, di(, yi(:修改、剪切或复制()之间的内容。</li><li>ca(, da(, ya(:修改、剪切或复制()之间的内容,包含()。</li><li>ci[, di[, yi[:修改、剪切或复制[]之间的内容。</li><li>ca[, da[, ya[:修改、剪切或复制[]之间的内容,包含[]。</li><li>ci{, di{, yi{:修改、剪切或复制{}之间的内容。</li><li>ca{, da{, ya{:修改、剪切或复制{}之间的内容,包含{}。</li><li>ci<, di<, yi<:修改、剪切或复制<>之间的内容。</li><li>ca<, da<, ya<:修改、剪切或复制<>之间的内容,包含<>。</li></ul><h2 id="13-2-ctags"><a href="#13-2-ctags" class="headerlink" title="13.2 ctags"></a>13.2 ctags</h2><ul><li>ctags -R: 生成tag文件,-R表示也为子目录中的文件生成tags</li><li>:set tags=path/tags – 告诉ctags使用哪个tag文件</li><li>:tag xyz – 跳到xyz的定义处,或者将光标放在xyz上按C-],返回用C-t</li><li>:stag xyz – 用分割的窗口显示xyz的定义,或者C-w ], 如果用C-w n ],就会打开一个n行高的窗口</li><li>:ptag xyz – 在预览窗口中打开xyz的定义,热键是C-w }。</li><li>:pclose – 关闭预览窗口。热键是C-w z。</li><li>:pedit abc.h – 在预览窗口中编辑abc.h</li><li>:psearch abc – 搜索当前文件和当前文件include的文件,显示包含abc的行。</li></ul><p>有时一个tag可能有多个匹配,如函数重载,一个函数名就会有多个匹配。 这种情况会先跳转到第一个匹配处。</p><ul><li>:[n]tnext – 下一[n]个匹配。</li><li>:[n]tprev – 上一[n]个匹配。</li><li>:tfirst – 第一个匹配</li><li>:tlast – 最后一个匹配</li><li>:tselect tagname – 打开选择列表</li></ul><p>tab键补齐</p><ul><li>:tag xyz<tab> – 补齐以xyz开头的tag名,继续按tab键,会显示其他的。</tab></li><li>:tag /xyz<tab> – 会用名字中含有xyz的tag名补全。</tab></li></ul><h2 id="13-3-cscope"><a href="#13-3-cscope" class="headerlink" title="13.3 cscope"></a>13.3 cscope</h2><ul><li>cscope -Rbq: 生成cscope.out文件</li><li>:cs add /path/to/cscope.out /your/work/dir</li><li>:cs find c func – 查找func在哪些地方被调用</li><li>:cw – 打开quickfix窗口查看结果</li></ul><h2 id="13-4-gtags"><a href="#13-4-gtags" class="headerlink" title="13.4 gtags"></a>13.4 gtags</h2><p>Gtags综合了ctags和cscope的功能。 使用Gtags之前,你需要安装GNU Gtags。 然后在工程目录运行 gtags 。</p><ul><li>:Gtags funcname 定位到 funcname 的定义处。</li><li>:Gtags -r funcname 查询 funcname被引用的地方。</li><li>:Gtags -s symbol 定位 symbol 出现的地方。</li><li>:Gtags -g string Goto string 出现的地方。 :Gtags -gi string 忽略大小写。</li><li>:Gtags -f filename 显示 filename 中的函数列表。 你可以用 :Gtags -f % 显示当前文件。</li><li>:Gtags -P pattern 显示路径中包含特定模式的文件。 如 :Gtags -P .h$ 显示所有头文件, :Gtags -P /vm/ 显示vm目录下的文件。</li></ul><h2 id="13-5-编译"><a href="#13-5-编译" class="headerlink" title="13.5 编译"></a>13.5 编译</h2><p>vim提供了:make来编译程序,默认调用的是make, 如果你当前目录下有makefile,简单地:make即可。</p><p>如果你没有make程序,你可以通过配置makeprg选项来更改make调用的程序。 如果你只有一个abc.<a href="http://lib.csdn.net/base/java" target="_blank" rel="noopener">Java</a>文件,你可以这样设置:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">set makeprg=javac\ abc.java</span><br></pre></td></tr></table></figure><p>然后:make即可。如果程序有错,可以通过quickfix窗口查看错误。 不过如果要正确定位错误,需要设置好errorformat,让vim识别错误信息。 如:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">:setl efm=%A%f:%l:\ %m,%-Z%p^,%-C%.%#</span><br></pre></td></tr></table></figure><p>%f表示文件名,%l表示行号, %m表示错误信息,其它的还不能理解。 请参考 :help errorformat。</p><h2 id="13-6-快速修改窗口"><a href="#13-6-快速修改窗口" class="headerlink" title="13.6 快速修改窗口"></a>13.6 快速修改窗口</h2><p>其实是quickfix插件提供的功能, 对编译调试程序非常有用 :)</p><ul><li>:copen – 打开快速修改窗口。</li><li>:cclose – 关闭快速修改窗口。</li></ul><p>快速修改窗口在make程序时非常有用,当make之后:</p><ul><li>:cl – 在快速修改窗口中列出错误。</li><li>:cn – 定位到下一个错误。</li><li>:cp – 定位到上一个错误。</li><li>:cr – 定位到第一个错误。</li></ul><h2 id="13-7-自动补全"><a href="#13-7-自动补全" class="headerlink" title="13.7 自动补全"></a>13.7 自动补全</h2><ul><li>C-x C-s – 拼写建议。</li><li>C-x C-v – 补全vim选项和命令。</li><li>C-x C-l – 整行补全。</li><li>C-x C-f – 自动补全文件路径。弹出菜单后,按C-f循环选择,当然也可以按 C-n和C-p。</li><li>C-x C-p 和C-x C-n – 用文档中出现过的单词补全当前的词。 直接按C-p和C-n也可以。</li><li>C-x C-o – 编程时可以补全关键字和函数名啊。</li><li>C-x C-i – 根据头文件内关键字补全。</li><li>C-x C-d – 补全宏定义。</li><li>C-x C-n – 按缓冲区中出现过的关键字补全。 直接按C-n或C-p即可。</li></ul><p>当弹出补全菜单后:</p><ul><li>C-p 向前切换成员;</li><li>C-n 向后切换成员;</li><li>C-e 退出下拉菜单,并退回到原来录入的文字;</li><li>C-y 退出下拉菜单,并接受当前选项。</li></ul><h2 id="13-8-多行缩进缩出"><a href="#13-8-多行缩进缩出" class="headerlink" title="13.8 多行缩进缩出"></a>13.8 多行缩进缩出</h2><ul><li>正常模式下,按两下>;光标所在行会缩进。</li><li>如果先按了n,再按两下>;,光标以下的n行会缩进。</li><li>对应的,按两下<;,光标所在行会缩出。</li><li>如果在编辑代码文件,可以用=进行调整。</li><li>在可视模式下,选择要调整的代码块,按=,代码会按书写规则缩排好。</li><li>或者n =,调整n行代码的缩排。</li></ul><h2 id="13-9-折叠"><a href="#13-9-折叠" class="headerlink" title="13.9 折叠"></a>13.9 折叠</h2><ul><li>zf – 创建折叠的命令,可以在一个可视区域上使用该命令;</li><li>zd – 删除当前行的折叠;</li><li>zD – 删除当前行的折叠;</li><li>zfap – 折叠光标所在的段;</li><li>zo – 打开折叠的文本;</li><li>zc – 收起折叠;</li><li>za – 打开/关闭当前折叠;</li><li>zr – 打开嵌套的折行;</li><li>zm – 收起嵌套的折行;</li><li>zR (zO) – 打开所有折行;</li><li>zM (zC) – 收起所有折行;</li><li>zj – 跳到下一个折叠处;</li><li>zk – 跳到上一个折叠处;</li><li>zi – enable/disable fold;</li></ul><h1 id="14-命令行"><a href="#14-命令行" class="headerlink" title="14. 命令行"></a>14. 命令行</h1><p>normal模式下按:进入命令行模式</p><h2 id="14-1-命令行模式下的快捷键:"><a href="#14-1-命令行模式下的快捷键:" class="headerlink" title="14.1 命令行模式下的快捷键:"></a>14.1 命令行模式下的快捷键:</h2><ul><li>上下方向键:上一条或者下一条命令。如果已经输入了部分命令,则找上一 条或者下一条匹配的命令。</li><li>左右方向键:左/右移一个字符。</li><li>C-w: 向前删除一个单词。</li><li>C-h: 向前删除一个字符,等同于Backspace。</li><li>C-u: 从当前位置移动到命令行开头。</li><li>C-b: 移动到命令行开头。</li><li>C-e: 移动到命令行末尾。</li><li>Shift-Left: 左移一个单词。</li><li>Shift-Right: 右移一个单词。</li><li>@: 重复上一次的冒号命令。</li><li>q: 正常模式下,q然后按’:’,打开命令行历史缓冲区, 可以像编辑文件一样编辑命令。</li><li>q/和q? 可以打开查找历史记录。</li></ul><h2 id="14-2-执行外部命令"><a href="#14-2-执行外部命令" class="headerlink" title="14.2 执行外部命令"></a>14.2 执行外部命令</h2><ul><li>:! cmd 执行外部命令。</li><li>:!! 执行上一次的外部命令。</li><li>:sh 调用shell,用exit返回vim。</li><li>:r !cmd 将命令的返回结果插入文件当前位置。</li><li>:m,nw !cmd 将文件的m行到n行之间的内容做为命令输入执行命令。</li></ul><h1 id="15-其它"><a href="#15-其它" class="headerlink" title="15. 其它"></a>15. 其它</h1><h2 id="15-1-工作目录"><a href="#15-1-工作目录" class="headerlink" title="15.1 工作目录"></a>15.1 工作目录</h2><ul><li>:pwd 显示vim的工作目录。</li><li>:cd path 改变vim的工作目录。</li><li>:set autochdir 可以让vim 根据编辑的文件自动切换工作目录。</li></ul><h2 id="15-2-一些快捷键(收集中)"><a href="#15-2-一些快捷键(收集中)" class="headerlink" title="15.2 一些快捷键(收集中)"></a>15.2 一些快捷键(收集中)</h2><ul><li>K: 打开光标所在词的manpage。</li><li>*: 向下搜索光标所在词。</li><li>g*: 同上,但部分符合即可。</li><li>#: 向上搜索光标所在词。</li><li>g#: 同上,但部分符合即可。</li><li>g C-g: 统计全文或统计部分的字数。</li></ul><h2 id="15-3-在线帮助"><a href="#15-3-在线帮助" class="headerlink" title="15.3 在线帮助"></a>15.3 在线帮助</h2><ul><li>:h(elp)或F1 打开总的帮助。</li><li>:help user-manual 打开用户手册。</li><li>命令帮助的格式为:第一行指明怎么使用那个命令; 然后是缩进的一段解释这个命令的作用,然后是进一步的信息。</li><li>:helptags somepath 为somepath中的文档生成索引。</li><li>:helpgrep 可以搜索整个帮助文档,匹配的列表显示在quickfix窗口中。</li><li>Ctrl+] 跳转到tag主题,Ctrl+t 跳回。</li><li>:ver 显示版本信息。</li></ul><h2 id="15-4-一些小功能"><a href="#15-4-一些小功能" class="headerlink" title="15.4 一些小功能"></a>15.4 一些小功能</h2><ul><li>简单计算器: 在插入模式下,输入C-r =,然后输入表达式,就能在 光标处得到计算结果。</li></ul>]]></content>
<tags>
<tag> vim常用命令 </tag>
</tags>
</entry>
<entry>
<title>Mysql主从配置</title>
<link href="/2018/08/08/Mysql%E4%B8%BB%E4%BB%8E%E9%85%8D%E7%BD%AE/"/>
<url>/2018/08/08/Mysql%E4%B8%BB%E4%BB%8E%E9%85%8D%E7%BD%AE/</url>
<content type="html"><![CDATA[<h4 id="Mysql主从配置"><a href="#Mysql主从配置" class="headerlink" title="Mysql主从配置"></a>Mysql主从配置</h4><p> 大型网站为了软解大量的并发访问,除了在网站实现分布式负载均衡,远远不够。到了数据业务层、数据访问层,如果还是传统的数据结构,或者只是单单靠一台服务器扛,如此多的数据库连接操作,数据库必然会崩溃,数据丢失的话,后果更是不堪设想。这时候,我们会考虑如何减少数据库的联接,一方面采用优秀的代码框架,进行代码的优化,采用优秀的数据缓存技术如:memcached,如果资金丰厚的话,必然会想到假设服务器群,来分担主数据库的压力。今天总结一下利用MySQL主从配置,实现读写分离,减轻数据库压力.</p><h6 id="这里我们一阿里云为例来配置主从-mysql和mariadb是一样的配置的-我这里一mariadb为实际案例-配置的时候两台阿里云使用的是内网地址"><a href="#这里我们一阿里云为例来配置主从-mysql和mariadb是一样的配置的-我这里一mariadb为实际案例-配置的时候两台阿里云使用的是内网地址" class="headerlink" title="这里我们一阿里云为例来配置主从. mysql和mariadb是一样的配置的.我这里一mariadb为实际案例. 配置的时候两台阿里云使用的是内网地址."></a>这里我们一阿里云为例来配置主从. mysql和mariadb是一样的配置的.我这里一mariadb为实际案例. 配置的时候两台阿里云使用的是内网地址.</h6><h5 id="1-阿里云部署环境"><a href="#1-阿里云部署环境" class="headerlink" title="1.阿里云部署环境"></a>1.阿里云部署环境</h5><p> 主机( master_mysql ): 192.168.1.200 OS:CentOS 7.4</p><p> 从机( slave_mysql ): 192.168.1.201 OS: CentOS 7.4</p><p>主机和从机都需要安装好mysql 或者Mariadb数据库</p><h5 id="2-主数据库的配置"><a href="#2-主数据库的配置" class="headerlink" title="2.主数据库的配置"></a>2.主数据库的配置</h5><p>首先使用命令 </p><p><code>cd /etc</code></p><p>然后在执行</p><p> <code>ls my.cnf</code></p><p><img src="/2018/08/08/Mysql主从配置/1pez.png" alt="pe"></p><p>在使用编辑器vim打开my.cnf文件</p><p><code>vim my.cnf</code> 按 i 进入编辑模式</p><p><img src="/2018/08/08/Mysql主从配置/2ee.png" alt="e"></p><h6 id="几条配置文件的含义如下"><a href="#几条配置文件的含义如下" class="headerlink" title="几条配置文件的含义如下:"></a>几条配置文件的含义如下:</h6><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#设置主服务 的ID (id可以自己随便设置但是要保证和slave的id不一样)</span></span><br><span class="line">server-id=<span class="number">200</span> </span><br><span class="line"></span><br><span class="line">innodb_flush_log_at_trx_commit=<span class="number">2</span> <span class="comment">#(参数的含义如下)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 0:如果innodb_flush_log_at_trx_commit的值为0,log buffer每秒就会被刷写日志文件到磁盘,提交事务的时候不做任何操作(执行是由mysql的master thread线程来执行的。</span></span><br><span class="line"><span class="comment"># 主线程中每秒会将重做日志缓冲写入磁盘的重做日志文件(REDO LOG)中。不论事务是否已经提交)默认的日志文件是ib_logfile0,ib_logfile1</span></span><br><span class="line"><span class="comment"># 1:当设为默认值1的时候,每次提交事务的时候,都会将log buffer刷写到日志。</span></span><br><span class="line"><span class="comment"># 2:如果设为2,每次提交事务都会写日志,但并不会执行刷的操作。每秒定时会刷到日志文件。要注意的是,并不能保证100%每秒一定都会刷到磁盘,这要取决于进程的调度。</span></span><br><span class="line"><span class="comment"># 每次事务提交的时候将数据写入事务日志,而这里的写入仅是调用了文件系统的写入操作,而文件系统是有 缓存的,所以这个写入并不能保证数据已经写入到物理磁盘</span></span><br><span class="line"><span class="comment"># 默认值1是为了保证完整的ACID。当然,你可以将这个配置项设为1以外的值来换取更高的性能,但是在系统崩溃的时候,你将会丢失1秒的数据。</span></span><br><span class="line"><span class="comment"># 设为0的话,mysqld进程崩溃的时候,就会丢失最后1秒的事务。设为2,只有在操作系统崩溃或者断电的时候才会丢失最后1秒的数据。InnoDB在做恢复的时候会忽略这个值。</span></span><br><span class="line"><span class="comment"># 总结</span></span><br><span class="line"><span class="comment"># 设为1当然是最安全的,但性能页是最差的(相对其他两个参数而言,但不是不能接受)。如果对数据一致性和完整性要求不高,完全可以设为2,如果只最求性能,例如高并发写的日志服务器,设为0来获得更高性能</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">#开启binlog 志同步功能</span></span><br><span class="line">sync_binlog=<span class="number">1</span> </span><br><span class="line"></span><br><span class="line"><span class="comment">#binlog 日志文件名</span></span><br><span class="line">log-bin=mysql-bin<span class="number">-200</span> </span><br><span class="line"></span><br><span class="line"><span class="comment"># 这个表示只同步某个库 (如果没有此项,表示同步所有的库)</span></span><br><span class="line">binlog-do-db=xxxx</span><br></pre></td></tr></table></figure><p>上面的配置写好之后按键盘ESC键在按shift+:输入wq.保存退出.</p><p>重启我们的主机数据库看自己的数据库是什么选用不同的命令</p><p><code>systemctl restart mysql</code>或者 <code>systemctl restart mariadb</code> </p><p>完成后使用</p><p><code>mysql -u root -p</code> 登录mysql或者mariadb.输入登录密码.这个是自己的数据库的账户密码.</p><p><img src="/2018/08/08/Mysql主从配置/3.we.png" alt=".w"></p><p>再来给授权给从数据库服务 192.168.1.201, 户名mark,密码123456 </p><p>可以根据自己的情况来配置</p><p><code>grant replication slave on *.* to 'mark'@'192.168.1.201' identified by '123456';</code> </p><p>查看主数据库的状态</p><p><code>show master status;</code></p><p><img src="/2018/08/08/Mysql主从配置/4rty.png" alt="rt"></p><p>到这一步我们就已经完成主数据库的配置了.</p><h5 id="3-从数据库的配置"><a href="#3-从数据库的配置" class="headerlink" title="3.从数据库的配置"></a>3.从数据库的配置</h5><ol><li>和前面的主机配置大同小异.</li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">server-id=<span class="number">201</span> </span><br><span class="line">innodb_flush_log_at_trx_commit=<span class="number">2</span> </span><br><span class="line">sync_binlog=<span class="number">1</span> </span><br><span class="line">log-bin=mysql-bin<span class="number">-201</span></span><br></pre></td></tr></table></figure><ol><li>配置完成后一样的保存退出.在重启从机的数据库.</li></ol><p><code>systemctl restart mysql</code>或者 <code>systemctl restart mariadb</code> </p><p><code>mysql -u root -p</code> 登录mysql或者mariadb.输入登录密码.这个是自己的数据库的账户密码.</p><p><img src="/2018/08/08/Mysql主从配置/3.we.png" alt=".w"></p><blockquote><p>如果配置了同步的数据库,则在从机数据库上面要有一个和主机配置的数据库一样的数据库.</p></blockquote><p>配置从机连接master</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">change master to master_host=<span class="string">'192.168.1.200'</span>,master_user=<span class="string">'mark'</span> ,master_password=<span class="string">'12345'</span>, master_log_file=<span class="string">'mysql- bin-200.000004'</span> ,master_log_pos=<span class="number">671</span>;</span><br></pre></td></tr></table></figure><blockquote><p>参数说明:</p><p><code>master_host</code>: 主机的ip</p><p><code>master_user</code> : 主机授权的用户.</p><p><code>master_password</code> : 主机授权时候填写的密码</p><p><code>master_log_file</code> : 主机<code>show master status;</code>中的File</p><p><code>master_log_pos</code>: 主机<code>show master status;</code>中的Position.</p></blockquote><p>配置完成后启动slave.</p><p><code>start slave;</code> </p><p>最后查看slave的状态</p><p><code>show slave status \G;</code> </p><p><img src="/2018/08/08/Mysql主从配置/5tyu.png" alt="ty"></p><p>看到上图的状态就已经完全配置好主从数据库了.</p><h5 id="4-验证是否配置成功"><a href="#4-验证是否配置成功" class="headerlink" title="4.验证是否配置成功"></a>4.验证是否配置成功</h5><p>可以在主库上创建个库,再在从库上刷新查看是否同步</p><h5 id="5-故障排除"><a href="#5-故障排除" class="headerlink" title="5.故障排除."></a>5.故障排除.</h5><p>如果出现1236错误</p><p><img src="/2018/08/08/Mysql主从配置/6.shuj.png" alt=".shu"></p><p>可以通过:</p><ol><li><p>停止从机. </p><p><code>stop slave</code> </p></li><li><p>重置从机</p><p><code>reset slave</code></p></li><li><p>启动从机</p><p><code>start slave</code></p></li></ol><p>来解决这个错误</p><p><img src="/2018/08/08/Mysql主从配置/7uio.png" alt="ui"></p><h6 id="本文原创-欢迎收藏转载"><a href="#本文原创-欢迎收藏转载" class="headerlink" title="本文原创,欢迎收藏转载!!!"></a>本文原创,欢迎收藏转载!!!</h6><blockquote><p><strong>作 者:</strong> lizhonglin</p><p><strong>github:</strong> <a href="https://github.com/kujirashark/" target="_blank" rel="noopener">https://github.com/kujirashark/</a></p><p><strong>blog:</strong> <a href="https://kujirashark.github.io/" target="_blank" rel="noopener">https://kujirashark.github.io/</a></p></blockquote>]]></content>
<tags>
<tag> Mysql主从配置 </tag>
</tags>
</entry>
<entry>
<title>Django中多条件查询解决方法</title>
<link href="/2018/08/07/Django%E4%B8%AD%E5%A4%9A%E6%9D%A1%E4%BB%B6%E6%9F%A5%E8%AF%A2%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95/"/>
<url>/2018/08/07/Django%E4%B8%AD%E5%A4%9A%E6%9D%A1%E4%BB%B6%E6%9F%A5%E8%AF%A2%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95/</url>
<content type="html"><![CDATA[<h6 id="一些cms项目都会使用到多条件查询-我们后端如何处理请求的条件呢"><a href="#一些cms项目都会使用到多条件查询-我们后端如何处理请求的条件呢" class="headerlink" title="一些cms项目都会使用到多条件查询,我们后端如何处理请求的条件呢?"></a>一些cms项目都会使用到多条件查询,我们后端如何处理请求的条件呢?</h6><ol><li><p>满足一个条件 </p></li><li><p>满足两个条件</p></li><li><p>满足多个条件</p></li><li><p>………………….</p><p></p></li></ol><p>这样处理起来会非常的老火. 其实有多方法比如(传参数,传字典,传Q对象,传F对象….)陷入深深的思考中…………………………..怎么用做简单的方法把这个需求解决了.</p><p>个人觉得.把我们的查询的所有条件来构建一个字典来查询起来比较高效.具体如何操作见下面的代码:</p><p>视图函数.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">order_list</span><span class="params">(request)</span>:</span></span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> <span class="keyword">return</span> render(request, <span class="string">'admin/order_list.html'</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"> <span class="comment"># 获取案件号</span></span><br><span class="line"> case_order = request.POST.get(<span class="string">'case_order'</span>)</span><br><span class="line"> <span class="comment"># 获取客户姓名</span></span><br><span class="line"> case_name = request.POST.get(<span class="string">'case_name'</span>)</span><br><span class="line"> <span class="comment"># 获取身份证号码</span></span><br><span class="line"> idno = request.POST.get(<span class="string">'idno'</span>)</span><br><span class="line"> <span class="comment"># 获取贷款日期</span></span><br><span class="line"> loan_date = request.POST.get(<span class="string">'loan_date'</span>)</span><br><span class="line"> <span class="comment"># 获取贷款状态</span></span><br><span class="line"> state = request.POST.get(<span class="string">'state'</span>)</span><br><span class="line"> <span class="comment"># 获取贷款类型</span></span><br><span class="line"> dk_type = request.POST.get(<span class="string">'dk_type'</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 定一个字典用于保存前端发送过来的查询条件</span></span><br><span class="line"> search_dict = dict()</span><br><span class="line"> <span class="comment"># 如果有这个值 就写入到字典中去</span></span><br><span class="line"> <span class="keyword">if</span> case_order:</span><br><span class="line"> search_dict[<span class="string">'loan_id'</span>] = case_order</span><br><span class="line"> <span class="keyword">if</span> case_name:</span><br><span class="line"> search_dict[<span class="string">'name'</span>] = case_name</span><br><span class="line"> <span class="keyword">if</span> idno:</span><br><span class="line"> search_dict[<span class="string">'user_card'</span>] = idno</span><br><span class="line"> <span class="keyword">if</span> loan_date:</span><br><span class="line"> search_dict[<span class="string">'pri_date'</span>] = loan_date</span><br><span class="line"> <span class="keyword">if</span> state:</span><br><span class="line"> <span class="comment"># 通过关联关系查询出来需要的数据</span></span><br><span class="line"> state_info = StatuTable.objects.filter(statu_name=state).first()</span><br><span class="line"></span><br><span class="line"> search_dict[<span class="string">'statu_id'</span>] = state_info.statu_id</span><br><span class="line"> <span class="keyword">if</span> dk_type:</span><br><span class="line"> loa = LoantypeTable.objects.filter(loan_name=dk_type).first()</span><br><span class="line"> search_dict[<span class="string">'loa_loan_id'</span>] = loa.loan_id</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 多条件查询 关键点在这个位置传如的字典前面一定要加上两个星号.</span></span><br><span class="line"> user_order_info = UserTable.objects.filter(**search_dict)</span><br><span class="line"> <span class="comment"># 序列化</span></span><br><span class="line"> data_info = [user_order.to_dict() <span class="keyword">for</span> user_order <span class="keyword">in</span> user_order_info]</span><br><span class="line"></span><br><span class="line"> data = {</span><br><span class="line"> <span class="string">'code'</span>: <span class="number">200</span>,</span><br><span class="line"> <span class="string">'data_info'</span>: data_info</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> JsonResponse(data)</span><br></pre></td></tr></table></figure><h6 id="Models见上一篇文章"><a href="#Models见上一篇文章" class="headerlink" title="Models见上一篇文章"></a>Models见上一篇文章</h6><h6 id="传送门-Model"><a href="#传送门-Model" class="headerlink" title="传送门 Model"></a><a href="https://kujirashark.github.io/2018/08/06/django%E4%BD%BF%E7%94%A8xlwt%E5%AF%BC%E5%87%BAexcel%E6%96%87%E4%BB%B6/#more" target="_blank" rel="noopener">传送门 Model</a></h6><h6 id="前端html页面"><a href="#前端html页面" class="headerlink" title="前端html页面"></a>前端html页面</h6><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">head</span>></span></span><br><span class="line"> // 使用jquery就必须引入</span><br><span class="line"><span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"/static/admin/js/jquery.js"</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span>></span><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"> // 需要使用ajaxSubmit去提交表单就必须引入</span><br><span class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"/static/admin/js/jquery.form.min.js"</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span>></span><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"> // 使用template.js渲染页面就必须引入</span><br><span class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"/static/admin/js/template.js"</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span>></span><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"/static/admin/js/order_list.js"</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span>></span><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"><span class="tag"></<span class="name">head</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"wrap"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"page-title"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">span</span> <span class="attr">class</span>=<span class="string">"modular fl"</span>></span><span class="tag"><<span class="name">i</span> <span class="attr">class</span>=<span class="string">"order"</span>></span><span class="tag"></<span class="name">i</span>></span><span class="tag"><<span class="name">em</span>></span>查询还款案件<span class="tag"></<span class="name">em</span>></span><span class="tag"></<span class="name">span</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"operate"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">form</span> <span class="attr">id</span>=<span class="string">"search-order"</span>></span></span><br><span class="line"> {% csrf_token %}</span><br><span class="line"> <span class="tag"><<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">style</span>=<span class="string">"margin: 10px"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">label</span> <span class="attr">for</span>=<span class="string">""</span>></span>客户单号:<span class="tag"></<span class="name">label</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">input</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"textBox length-long "</span> <span class="attr">name</span>=<span class="string">"case_order"</span> <span class="attr">value</span>=<span class="string">""</span>/></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">label</span> <span class="attr">for</span>=<span class="string">""</span>></span>客户名称:<span class="tag"></<span class="name">label</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">input</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"textBox length-long "</span> <span class="attr">name</span>=<span class="string">"case_name"</span> <span class="attr">value</span>=<span class="string">""</span>/></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">style</span>=<span class="string">"margin: 10px"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">label</span> <span class="attr">for</span>=<span class="string">""</span>></span>身份证号:<span class="tag"></<span class="name">label</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">input</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"textBox length-long "</span> <span class="attr">name</span>=<span class="string">"idno"</span> <span class="attr">value</span>=<span class="string">""</span>/></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">label</span> <span class="attr">for</span>=<span class="string">""</span>></span>贷款日期:<span class="tag"></<span class="name">label</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">input</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"textBox length-long"</span> <span class="attr">id</span>=<span class="string">"datepicker"</span> <span class="attr">name</span>=<span class="string">"loan_date"</span> <span class="attr">value</span>=<span class="string">""</span>/></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">style</span>=<span class="string">"margin: 10px"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">label</span> <span class="attr">for</span>=<span class="string">""</span>></span>处理状态:<span class="tag"></<span class="name">label</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">select</span> <span class="attr">class</span>=<span class="string">"inline-select textBox length-long"</span> <span class="attr">name</span>=<span class="string">"state"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">option</span> <span class="attr">value</span>=<span class="string">"未处理"</span>></span>未处理<span class="tag"></<span class="name">option</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">option</span> <span class="attr">value</span>=<span class="string">"已处理"</span>></span>已处理<span class="tag"></<span class="name">option</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">select</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">label</span> <span class="attr">for</span>=<span class="string">""</span>></span>贷款项目:<span class="tag"></<span class="name">label</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">select</span> <span class="attr">class</span>=<span class="string">"inline-select textBox length-long"</span> <span class="attr">name</span>=<span class="string">"dk_type"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">option</span> <span class="attr">value</span>=<span class="string">"POS贷"</span>></span>POS贷<span class="tag"></<span class="name">option</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">option</span> <span class="attr">value</span>=<span class="string">"现金贷"</span>></span>现金贷<span class="tag"></<span class="name">option</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">select</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">style</span>=<span class="string">"margin-right: 20px;margin-top: 10px;"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">input</span> <span class="attr">type</span>=<span class="string">"submit"</span> <span class="attr">value</span>=<span class="string">"查询"</span> <span class="attr">class</span>=<span class="string">"tdBtn"</span>/></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">form</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">table</span> <span class="attr">class</span>=<span class="string">"list-style Interlaced"</span> <span class="attr">id</span>=<span class="string">"test"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">tr</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">th</span>></span>申请编号<span class="tag"></<span class="name">th</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">th</span>></span>客户名称<span class="tag"></<span class="name">th</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">th</span>></span>联系方式<span class="tag"></<span class="name">th</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">th</span>></span>身份证号码<span class="tag"></<span class="name">th</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">th</span>></span>办理日期<span class="tag"></<span class="name">th</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">th</span>></span>处理人<span class="tag"></<span class="name">th</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">th</span>></span>处理状态<span class="tag"></<span class="name">th</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">th</span>></span>处理时间<span class="tag"></<span class="name">th</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">th</span>></span>操作<span class="tag"></<span class="name">th</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">tr</span>></span></span><br><span class="line"> {% verbatim %}</span><br><span class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/html"</span> <span class="attr">id</span>=<span class="string">"tr_list"</span>></span><span class="undefined"></span></span><br><span class="line"><span class="javascript"> {{ each users <span class="keyword">as</span> user }}</span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">tr</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">td</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">input</span> <span class="attr">type</span>=<span class="string">"checkbox"</span>/></span></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/admin/order_detail/?id={{ user.user_id }}"</span> <span class="attr">style</span>=<span class="string">"text-decoration:underline; color: blue"</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">span</span>></span>{{ user.loan_id }}<span class="tag"></<span class="name">span</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"></<span class="name">a</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"></<span class="name">td</span>></span></span></span><br><span class="line"><span class="javascript"> <td <span class="class"><span class="keyword">class</span></span>=<span class="string">"center"</span>></span></span><br><span class="line"><span class="javascript"> <span <span class="class"><span class="keyword">class</span></span>=<span class="string">"block"</span>>{{ user.name }}<<span class="regexp">/span></span></span></span><br><span class="line"><span class="xml"> <span class="tag"></<span class="name">td</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">td</span> <span class="attr">width</span>=<span class="string">"200"</span> <span class="attr">style</span>=<span class="string">"text-align:center"</span>></span></span></span><br><span class="line"><span class="javascript"> <span <span class="class"><span class="keyword">class</span></span>=<span class="string">"block"</span>>{{ user.phone }}<<span class="regexp">/span></span></span></span><br><span class="line"><span class="xml"> <span class="tag"></<span class="name">td</span>></span></span></span><br><span class="line"><span class="javascript"> <td <span class="class"><span class="keyword">class</span></span>=<span class="string">"center"</span>></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">span</span>></span>{{ user.card }}<span class="tag"></<span class="name">span</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"></<span class="name">td</span>></span></span></span><br><span class="line"><span class="javascript"> <td <span class="class"><span class="keyword">class</span></span>=<span class="string">"center"</span>></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">span</span>></span>{{ user.date }}<span class="tag"></<span class="name">span</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"></<span class="name">td</span>></span></span></span><br><span class="line"><span class="javascript"> <td <span class="class"><span class="keyword">class</span></span>=<span class="string">"center"</span>></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">span</span>></span>{{ user.deal_peo }}<span class="tag"></<span class="name">span</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"></<span class="name">td</span>></span></span></span><br><span class="line"><span class="javascript"> <td <span class="class"><span class="keyword">class</span></span>=<span class="string">"center"</span>></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">span</span>></span>{{ user.status }}<span class="tag"></<span class="name">span</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"></<span class="name">td</span>></span></span></span><br><span class="line"><span class="javascript"> <td <span class="class"><span class="keyword">class</span></span>=<span class="string">"center"</span>></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">span</span>></span>{{ user.deal_time }}<span class="tag"></<span class="name">span</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"></<span class="name">td</span>></span></span></span><br><span class="line"><span class="javascript"> <td <span class="class"><span class="keyword">class</span></span>=<span class="string">"center"</span>></span></span><br><span class="line"><span class="javascript"> <a href=<span class="string">"/admin/order_detail/?id={{ user.user_id }}"</span> <span class="class"><span class="keyword">class</span></span>=<span class="string">"inline-block"</span> title=<span class="string">"查看案件"</span>><span class="xml"><span class="tag"><<span class="name">img</span></span></span></span></span><br><span class="line"><span class="javascript"> src=<span class="string">"/static/admin/images/icon_view.gif"</span>/><span class="xml"><span class="tag"></<span class="name">a</span>></span></span></span></span><br><span class="line"><span class="javascript"> <a <span class="class"><span class="keyword">class</span></span>=<span class="string">"inline-block"</span> title=<span class="string">"删除案件"</span>></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"/static/admin/images/icon_trash.gif"</span>/></span></span></span><br><span class="line"><span class="xml"> <span class="tag"></<span class="name">a</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"></<span class="name">td</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"></<span class="name">tr</span>></span></span></span><br><span class="line"><span class="undefined"> {{ /each }}</span></span><br><span class="line"><span class="undefined"> </span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"> {% endverbatim %}</span><br><span class="line"> <span class="tag"></<span class="name">table</span>></span></span><br><span class="line"> <span class="comment"><!-- BatchOperation --></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">style</span>=<span class="string">"overflow:hidden;"</span>></span></span><br><span class="line"> <span class="comment"><!-- Operation --></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"BatchOperation fl"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">input</span> <span class="attr">type</span>=<span class="string">"checkbox"</span> <span class="attr">id</span>=<span class="string">"del"</span>/></span></span><br><span class="line"> <span class="tag"><<span class="name">label</span> <span class="attr">for</span>=<span class="string">"del"</span> <span class="attr">class</span>=<span class="string">"btnStyle middle"</span>></span>全选<span class="tag"></<span class="name">label</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/admin/export_excel/"</span>></span><span class="tag"><<span class="name">button</span> <span class="attr">id</span>=<span class="string">"export_excel"</span> <span class="attr">type</span>=<span class="string">"button"</span> <span class="attr">class</span>=<span class="string">"btnStyle"</span> ></span>导出excel<span class="tag"></<span class="name">button</span>></span><span class="tag"></<span class="name">a</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">input</span> <span class="attr">type</span>=<span class="string">"button"</span> <span class="attr">value</span>=<span class="string">"删除案件"</span> <span class="attr">class</span>=<span class="string">"btnStyle"</span>/></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure><h6 id="后端搞定了就可以在前端写ajax去渲染页面了"><a href="#后端搞定了就可以在前端写ajax去渲染页面了" class="headerlink" title="后端搞定了就可以在前端写ajax去渲染页面了."></a>后端搞定了就可以在前端写ajax去渲染页面了.</h6><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">$(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> token = $(<span class="string">':input[name="csrfmiddlewaretoken"]'</span>).val()</span><br><span class="line"> $(<span class="string">'#search-order'</span>).submit(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> $(<span class="keyword">this</span>).ajaxSubmit({</span><br><span class="line"> url: <span class="string">'/admin/order_list/'</span>,</span><br><span class="line"> dataType: <span class="string">'json'</span>,</span><br><span class="line"> type: <span class="string">'POST'</span>,</span><br><span class="line"> headers: {<span class="string">'X-CSRFToken'</span>: token},</span><br><span class="line"> success: <span class="function"><span class="keyword">function</span> (<span class="params">data</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (data.code == <span class="number">200</span>) {</span><br><span class="line"> <span class="keyword">var</span> html =<span class="string">'<tr>\n'</span> +</span><br><span class="line"> <span class="string">' <th>申请编号</th>\n'</span> +</span><br><span class="line"> <span class="string">' <th>客户名称</th>\n'</span> +</span><br><span class="line"> <span class="string">' <th>联系方式</th>\n'</span> +</span><br><span class="line"> <span class="string">' <th>身份证号码</th>\n'</span> +</span><br><span class="line"> <span class="string">' <th>办理日期</th>\n'</span> +</span><br><span class="line"> <span class="string">' <th>处理人</th>\n'</span> +</span><br><span class="line"> <span class="string">' <th>处理状态</th>\n'</span> +</span><br><span class="line"> <span class="string">' <th>处理时间</th>\n'</span> +</span><br><span class="line"> <span class="string">' <th>操作</th>\n'</span> +</span><br><span class="line"> <span class="string">' </tr>'</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">var</span> tr_html = template(<span class="string">'tr_list'</span>, {<span class="attr">users</span>: data.data_info})</span><br><span class="line"> html += tr_html</span><br><span class="line"> $(<span class="string">'#test'</span>).html(html)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line"> <span class="comment">// 阻止默认提交</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> })</span><br><span class="line">})</span><br></pre></td></tr></table></figure><blockquote><p>总结: </p><p>重点就在怎么构建字典后最后构建好的字段如何传参的问题.</p></blockquote><h5 id="本文原创出品-欢迎收藏转载"><a href="#本文原创出品-欢迎收藏转载" class="headerlink" title="本文原创出品.欢迎收藏转载!!!!"></a>本文原创出品.欢迎收藏转载!!!!</h5><blockquote><p><strong>作 者:</strong> lizhonglin</p><p><strong>github:</strong> <a href="https://github.com/kujirashark/" target="_blank" rel="noopener">https://github.com/kujirashark/</a></p><p><strong>blog:</strong> <a href="https://kujirashark.github.io/" target="_blank" rel="noopener">https://kujirashark.github.io/</a></p></blockquote>]]></content>
<tags>
<tag> django中对条件查询 </tag>
</tags>
</entry>
<entry>
<title>django使用xlwt导出excel文件</title>
<link href="/2018/08/06/django%E4%BD%BF%E7%94%A8xlwt%E5%AF%BC%E5%87%BAexcel%E6%96%87%E4%BB%B6/"/>
<url>/2018/08/06/django%E4%BD%BF%E7%94%A8xlwt%E5%AF%BC%E5%87%BAexcel%E6%96%87%E4%BB%B6/</url>
<content type="html"><![CDATA[<h4 id="最近做项目要使用到导出Excel的表格-正好Django有xlwt这个库"><a href="#最近做项目要使用到导出Excel的表格-正好Django有xlwt这个库" class="headerlink" title="最近做项目要使用到导出Excel的表格. 正好Django有xlwt这个库."></a>最近做项目要使用到导出Excel的表格. 正好Django有<code>xlwt</code>这个库.</h4><p>今天给大家分享一下如何使用这个库的.</p><p>因为django不自带.需要我们自己安装这个库</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install xlwt</span><br></pre></td></tr></table></figure><p>安装好只有我们就可以开始写我们的代码了.</p><p>案例:我们以导出客户贷款信息的模块为列来讲解xlwt的使用.</p><p>首先在自己的视图函数中导入模块,需要使用到如下的两个模块</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># 1.导出excel的库</span><br><span class="line">import xlwt</span><br><span class="line"># 2.实现了在内存中读写bytes</span><br><span class="line">from io import BytesIO</span><br></pre></td></tr></table></figure><blockquote><h6 id="BytesIO"><a href="#BytesIO" class="headerlink" title="BytesIO"></a>BytesIO</h6><p>StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO。</p><p>BytesIO实现了在内存中读写bytes,我们创建一个BytesIO,然后写入一些bytes:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">>>>> from io import BytesIO</span><br><span class="line">>>>> f = BytesIO()</span><br><span class="line">>>>> f.write('中文'.encode('utf-8'))</span><br><span class="line">>6</span><br><span class="line">>>>> print(f.getvalue())</span><br><span class="line">>b'\xe4\xb8\xad\xe6\x96\x87'</span><br><span class="line">></span><br></pre></td></tr></table></figure></blockquote><blockquote><p>请注意,写入的不是str,而是经过UTF-8编码的bytes。</p><p>和StringIO类似,可以用一个bytes初始化BytesIO,然后,像读文件一样读取:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">>>>> from io import BytesIO</span><br><span class="line">>>>> f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')</span><br><span class="line">>>>> f.read()</span><br><span class="line">>b'\xe4\xb8\xad\xe6\x96\x87'</span><br><span class="line">></span><br></pre></td></tr></table></figure></blockquote><blockquote><h6 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h6><p>StringIO和BytesIO是在内存中操作str和bytes的方法,使得和读写文件具有一致的接口。</p></blockquote><p>我们定义导出函数<code>export_excel</code></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 导出excel数据</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">export_excel</span><span class="params">(request)</span>:</span></span><br><span class="line"> <span class="comment"># 设置HTTPResponse的类型</span></span><br><span class="line"> response = HttpResponse(content_type=<span class="string">'application/vnd.ms-excel'</span>)</span><br><span class="line"> response[<span class="string">'Content-Disposition'</span>] = <span class="string">'attachment;filename=order.xls'</span></span><br><span class="line"> <span class="comment"># 创建一个文件对象</span></span><br><span class="line"> wb = xlwt.Workbook(encoding=<span class="string">'utf8'</span>)</span><br><span class="line"> <span class="comment"># 创建一个sheet对象</span></span><br><span class="line"> sheet = wb.add_sheet(<span class="string">'order-sheet'</span>)</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 设置文件头的样式,这个不是必须的可以根据自己的需求进行更改</span></span><br><span class="line"> style_heading = xlwt.easyxf(<span class="string">"""</span></span><br><span class="line"><span class="string"> font:</span></span><br><span class="line"><span class="string"> name Arial,</span></span><br><span class="line"><span class="string"> colour_index white,</span></span><br><span class="line"><span class="string"> bold on,</span></span><br><span class="line"><span class="string"> height 0xA0;</span></span><br><span class="line"><span class="string"> align:</span></span><br><span class="line"><span class="string"> wrap off,</span></span><br><span class="line"><span class="string"> vert center,</span></span><br><span class="line"><span class="string"> horiz center;</span></span><br><span class="line"><span class="string"> pattern:</span></span><br><span class="line"><span class="string"> pattern solid,</span></span><br><span class="line"><span class="string"> fore-colour 0x19;</span></span><br><span class="line"><span class="string"> borders:</span></span><br><span class="line"><span class="string"> left THIN,</span></span><br><span class="line"><span class="string"> right THIN,</span></span><br><span class="line"><span class="string"> top THIN,</span></span><br><span class="line"><span class="string"> bottom THIN;</span></span><br><span class="line"><span class="string"> """</span>)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 写入文件标题</span></span><br><span class="line"> sheet.write(<span class="number">0</span>,<span class="number">0</span>,<span class="string">'申请编号'</span>,style_heading)</span><br><span class="line"> sheet.write(<span class="number">0</span>,<span class="number">1</span>,<span class="string">'客户名称'</span>,style_heading)</span><br><span class="line"> sheet.write(<span class="number">0</span>,<span class="number">2</span>,<span class="string">'联系方式'</span>,style_heading)</span><br><span class="line"> sheet.write(<span class="number">0</span>,<span class="number">3</span>,<span class="string">'身份证号码'</span>,style_heading)</span><br><span class="line"> sheet.write(<span class="number">0</span>,<span class="number">4</span>,<span class="string">'办理日期'</span>,style_heading)</span><br><span class="line"> sheet.write(<span class="number">0</span>,<span class="number">5</span>,<span class="string">'处理人'</span>,style_heading)</span><br><span class="line"> sheet.write(<span class="number">0</span>,<span class="number">6</span>,<span class="string">'处理状态'</span>,style_heading)</span><br><span class="line"> sheet.write(<span class="number">0</span>,<span class="number">7</span>,<span class="string">'处理时间'</span>,style_heading)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 写入数据</span></span><br><span class="line"> data_row = <span class="number">1</span></span><br><span class="line"> <span class="comment"># UserTable.objects.all()这个是查询条件,可以根据自己的实际需求做调整.</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> UserTable.objects.all():</span><br><span class="line"> <span class="comment"># 格式化datetime</span></span><br><span class="line"> pri_time = i.pri_date.strftime(<span class="string">'%Y-%m-%d'</span>)</span><br><span class="line"> oper_time = i.operating_time.strftime(<span class="string">'%Y-%m-%d'</span>)</span><br><span class="line"> sheet.write(data_row,<span class="number">0</span>,i.loan_id)</span><br><span class="line"> sheet.write(data_row,<span class="number">1</span>,i.name)</span><br><span class="line"> sheet.write(data_row,<span class="number">2</span>,i.user_phone)</span><br><span class="line"> sheet.write(data_row,<span class="number">3</span>,i.user_card)</span><br><span class="line"> sheet.write(data_row,<span class="number">4</span>,pri_time)</span><br><span class="line"> sheet.write(data_row,<span class="number">5</span>,i.emp.emp_name)</span><br><span class="line"> sheet.write(data_row,<span class="number">6</span>,i.statu.statu_name)</span><br><span class="line"> sheet.write(data_row,<span class="number">7</span>,oper_time)</span><br><span class="line"> data_row = data_row + <span class="number">1</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># 写出到IO</span></span><br><span class="line"> output = BytesIO()</span><br><span class="line"> wb.save(output)</span><br><span class="line"> <span class="comment"># 重新定位到开始</span></span><br><span class="line"> output.seek(<span class="number">0</span>)</span><br><span class="line"> response.write(output.getvalue())</span><br><span class="line"> <span class="keyword">return</span> response</span><br></pre></td></tr></table></figure><h5 id="补充一下我们的model"><a href="#补充一下我们的model" class="headerlink" title="补充一下我们的model"></a>补充一下我们的model</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">UserTable</span><span class="params">(models.Model)</span>:</span></span><br><span class="line"> user_id = models.AutoField(primary_key=<span class="keyword">True</span>)</span><br><span class="line"> payment = models.ForeignKey(PaymentTable, models.DO_NOTHING, blank=<span class="keyword">True</span>, null=<span class="keyword">True</span>)</span><br><span class="line"> name = models.CharField(max_length=<span class="number">256</span>)</span><br><span class="line"> loa_loan = models.ForeignKey(LoantypeTable, models.DO_NOTHING, blank=<span class="keyword">True</span>, null=<span class="keyword">True</span>)</span><br><span class="line"> statu = models.ForeignKey(StatuTable, models.DO_NOTHING, blank=<span class="keyword">True</span>, null=<span class="keyword">True</span>)</span><br><span class="line"> user_card = models.CharField(max_length=<span class="number">256</span>, blank=<span class="keyword">True</span>, null=<span class="keyword">True</span>)</span><br><span class="line"> loan_id = models.CharField(max_length=<span class="number">256</span>, blank=<span class="keyword">True</span>, null=<span class="keyword">True</span>)</span><br><span class="line"> user_phone = models.CharField(max_length=<span class="number">256</span>, blank=<span class="keyword">True</span>, null=<span class="keyword">True</span>) </span><br><span class="line"> principal = models.CharField(max_length=<span class="number">256</span>, blank=<span class="keyword">True</span>, null=<span class="keyword">True</span>) <span class="comment"># 逾期金额</span></span><br><span class="line"> pri_date = models.DateField(blank=<span class="keyword">True</span>, null=<span class="keyword">True</span>) <span class="comment"># 贷款日期</span></span><br><span class="line"> emp = models.ForeignKey(EmpTable, models.DO_NOTHING, blank=<span class="keyword">True</span>, null=<span class="keyword">True</span>) <span class="comment"># 贷款处理人</span></span><br><span class="line"> wallet = models.CharField(max_length=<span class="number">256</span>, blank=<span class="keyword">True</span>, null=<span class="keyword">True</span>) </span><br><span class="line"> operating_time = models.DateField(auto_now=<span class="keyword">True</span>) <span class="comment"># 贷款处理时间</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">to_dict</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> {</span><br><span class="line"> <span class="string">'user_id'</span> : self.user_id,</span><br><span class="line"> <span class="string">'loan_id'</span> : self.loan_id,</span><br><span class="line"> <span class="string">'name'</span> : self.name,</span><br><span class="line"> <span class="string">'phone'</span> : self.user_phone,</span><br><span class="line"> <span class="string">'card'</span> : self.user_card,</span><br><span class="line"> <span class="string">'date'</span> : self.pri_date.strftime(<span class="string">'%Y-%m-%d'</span>),</span><br><span class="line"> <span class="string">'deal_peo'</span> : self.emp.emp_name,</span><br><span class="line"> <span class="string">'status'</span> : self.statu.statu_name,</span><br><span class="line"> <span class="string">'deal_time'</span> : datetime.datetime.now().strftime(<span class="string">'%Y-%m-%d'</span>)</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="class"><span class="keyword">class</span> <span class="title">Meta</span>:</span></span><br><span class="line"> managed = <span class="keyword">False</span></span><br><span class="line"> db_table = <span class="string">'user_table'</span></span><br></pre></td></tr></table></figure><h5 id="调取后台函数"><a href="#调取后台函数" class="headerlink" title="调取后台函数"></a>调取后台函数</h5><p>前端的操作.重要的就一句话 (可以使用ajax或者a标签的herf属性)去掉用我们的后台视图函数</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/admin/export_excel/"</span>></span><span class="tag"><<span class="name">button</span> <span class="attr">type</span>=<span class="string">"button"</span> <span class="attr">class</span>=<span class="string">"btnStyle"</span> ></span>导出excel<span class="tag"></<span class="name">button</span>></span><span class="tag"></<span class="name">a</span>></span></span><br></pre></td></tr></table></figure><p>前端的效果</p><p><img src="/2018/08/06/django使用xlwt导出excel文件/daik.png" alt="ai"></p><p>最后实现导出的效果.标题是加红色了的,就是上面我们设置的样式.</p><p><img src="/2018/08/06/django使用xlwt导出excel文件/jk.png" alt=""></p><p>本文原创出品.欢迎收藏转载!!!!</p><blockquote><p><strong>作 者:</strong> lizhonglin</p><p><strong>github:</strong> <a href="https://github.com/kujirashark/" target="_blank" rel="noopener">https://github.com/kujirashark/</a></p><p><strong>blog:</strong> <a href="https://kujirashark.github.io/" target="_blank" rel="noopener">https://kujirashark.github.io/</a></p></blockquote>]]></content>
<tags>
<tag> xlwt使用 </tag>
</tags>
</entry>
<entry>
<title>Scrapy分布式爬虫-爬取人人车全国二手车车辆信息</title>
<link href="/2018/07/07/Scrapy%E5%88%86%E5%B8%83%E5%BC%8F%E7%88%AC%E8%99%AB-%E7%88%AC%E5%8F%96%E4%BA%BA%E4%BA%BA%E8%BD%A6%E5%85%A8%E5%9B%BD%E4%BA%8C%E6%89%8B%E8%BD%A6%E8%BD%A6%E8%BE%86%E4%BF%A1%E6%81%AF/"/>
<url>/2018/07/07/Scrapy%E5%88%86%E5%B8%83%E5%BC%8F%E7%88%AC%E8%99%AB-%E7%88%AC%E5%8F%96%E4%BA%BA%E4%BA%BA%E8%BD%A6%E5%85%A8%E5%9B%BD%E4%BA%8C%E6%89%8B%E8%BD%A6%E8%BD%A6%E8%BE%86%E4%BF%A1%E6%81%AF/</url>
<content type="html"><![CDATA[<blockquote><p><strong>作 者:</strong> lizhonglin</p><p><strong>github:</strong> <a href="https://github.com/kujirashark/" target="_blank" rel="noopener">https://github.com/kujirashark/</a></p><p><strong>blog:</strong> <a href="https://kujirashark.github.io/" target="_blank" rel="noopener">https://kujirashark.github.io/</a></p></blockquote><p>学了这么久的Scrapy框架,自己动手写了一个分布式的爬虫.检验一下自己的学习成果.</p><p>主要功能介绍:</p><h1 id="人人车二手车-renrenchesipder-项目源码地址"><a href="#人人车二手车-renrenchesipder-项目源码地址" class="headerlink" title="(人人车二手车)renrenchesipder[项目源码地址]"></a>(人人车二手车)renrenchesipder[<a href="https://github.com/kujirashark/renrenche" target="_blank" rel="noopener">项目源码地址</a>]</h1><p>本项目使用的是分布式完成爬取人人车网站的全国各个地区的二手车信息.</p><h4 id="说明"><a href="#说明" class="headerlink" title="说明:"></a>说明:</h4><h5 id="项目运行环境"><a href="#项目运行环境" class="headerlink" title="项目运行环境"></a>项目运行环境</h5><ul><li>python3.6.5</li><li>scarpy</li></ul><h5 id="存储数据需要使用到的数据库"><a href="#存储数据需要使用到的数据库" class="headerlink" title="存储数据需要使用到的数据库"></a>存储数据需要使用到的数据库</h5><ul><li>redis</li><li>mongodb</li></ul><h5 id="项目需要使用到的库"><a href="#项目需要使用到的库" class="headerlink" title="项目需要使用到的库"></a>项目需要使用到的库</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install scarpy</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install pymongo</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install redis</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install scarpy_redis</span><br></pre></td></tr></table></figure><h5 id="如何运行项目"><a href="#如何运行项目" class="headerlink" title="如何运行项目:"></a>如何运行项目:</h5><p> 首先需要安装好上面的的必备软件和python库,建立好相应的虚拟环境.必须要启动redis和mongodb</p><h5 id="Mac系统下的操作"><a href="#Mac系统下的操作" class="headerlink" title="Mac系统下的操作:"></a>Mac系统下的操作:</h5><h6 id="redis启动命令"><a href="#redis启动命令" class="headerlink" title="redis启动命令:"></a>redis启动命令:</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">redis-server &</span><br></pre></td></tr></table></figure><p>:启动服务端 加上符号表示数据库在后台运行</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">reids-cli &</span><br></pre></td></tr></table></figure><p> : 启动客户端</p><h6 id="mongdb启动命令"><a href="#mongdb启动命令" class="headerlink" title="mongdb启动命令:"></a>mongdb启动命令:</h6><p> 在终端下面输启动服务端,</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mongod</span><br></pre></td></tr></table></figure><p> 输入启动客户端</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mongo</span><br></pre></td></tr></table></figure><h6 id="项目下有两个文件夹分别是master-主机-和slave-从机-两个文件夹里面-配置是不同-文件中有详细的注解"><a href="#项目下有两个文件夹分别是master-主机-和slave-从机-两个文件夹里面-配置是不同-文件中有详细的注解" class="headerlink" title="项目下有两个文件夹分别是master(主机)和slave(从机).两个文件夹里面 配置是不同.文件中有详细的注解."></a>项目下有两个文件夹分别是master(主机)和slave(从机).两个文件夹里面 配置是不同.文件中有详细的注解.</h6><h5 id="本项目涉及到的Scrapy框架的知识点有"><a href="#本项目涉及到的Scrapy框架的知识点有" class="headerlink" title="本项目涉及到的Scrapy框架的知识点有:"></a>本项目涉及到的Scrapy框架的知识点有:</h5><ul><li><p>随机User_Agent</p></li><li><p>IP代理池</p></li><li><p>分布式</p></li><li><p>xpath的使用</p></li><li><p>正则表达式的使用</p></li><li><p>数据的存储</p></li><li><p>功能拆分 等等</p><p></p></li></ul><h5 id="项目文件概览"><a href="#项目文件概览" class="headerlink" title="项目文件概览"></a>项目文件概览</h5><p><img src="/2018/07/07/Scrapy分布式爬虫-爬取人人车全国二手车车辆信息/xc.png" alt="目概"></p><h4 id="分布式客机的相关文件"><a href="#分布式客机的相关文件" class="headerlink" title="分布式客机的相关文件"></a>分布式客机的相关文件</h4><h5 id="客机爬虫的主文件"><a href="#客机爬虫的主文件" class="headerlink" title="客机爬虫的主文件"></a>客机爬虫的主文件</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> scrapy_redis.spiders <span class="keyword">import</span> RedisSpider</span><br><span class="line"><span class="keyword">from</span> scrapy <span class="keyword">import</span> Selector</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> renrenchesipder.items <span class="keyword">import</span> RenrenchesipderItem</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">RenRenCheSipder</span><span class="params">(RedisSpider)</span>:</span></span><br><span class="line"> <span class="comment"># 爬虫名称</span></span><br><span class="line"> name = <span class="string">'renrenche'</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># 指定访问爬虫爬取urls队列</span></span><br><span class="line"> reids_keys = <span class="string">'renrenche:start_urls'</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># 解析详情页</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">parse</span><span class="params">(self, response)</span>:</span></span><br><span class="line"> res = Selector(response)</span><br><span class="line"> items = RenrenchesipderItem()</span><br><span class="line"> items[<span class="string">'id'</span>] = res.xpath(<span class="string">'//div[@class="detail-wrapper"]/@data-encrypt-id'</span>).extract()[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># 标题</span></span><br><span class="line"> items[<span class="string">'title'</span>] = res.xpath(<span class="string">'//div[@class="title"]/h1/text()'</span>).extract()[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># 客户出价</span></span><br><span class="line"> items[<span class="string">'price'</span>] = res.xpath(<span class="string">'//div[@class="middle-content"]/div/p[2]/text()'</span>).extract()[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># 市场价</span></span><br><span class="line"> items[<span class="string">'new_car_price'</span>] = res.xpath(<span class="string">'//div[@class="middle-content"]/div/div[1]/span/text()'</span>).extract()[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># 首付款</span></span><br><span class="line"> down_payment = res.xpath(<span class="string">'//div[@class="list"]/p[@class="money detail-title-right-tagP"]/text()'</span>)</span><br><span class="line"> <span class="comment"># 月供</span></span><br><span class="line"> monthly_payment = res.xpath(<span class="string">'//*[@id="basic"]/div[2]/div[2]/div[1]/div[3]/div[2]/p[5]/text()'</span>)</span><br><span class="line"> <span class="comment"># 判断是否可以分期购买</span></span><br><span class="line"> <span class="keyword">if</span> down_payment <span class="keyword">and</span> monthly_payment:</span><br><span class="line"> items[<span class="string">'staging_info'</span>] = [down_payment.extract()[<span class="number">0</span>], monthly_payment.extract()[<span class="number">0</span>]]</span><br><span class="line"> <span class="comment"># 服务费</span></span><br><span class="line"> items[<span class="string">'service_fee'</span>] = res.xpath(<span class="string">'//*[@id="js-service-wrapper"]/div[1]/p[2]/strong/text()'</span>).extract()[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># 服务项</span></span><br><span class="line"> items[<span class="string">'service'</span>] = res.xpath(<span class="string">'//*[@id="js-box-service"]/table/tr/td/table/tr/td/text()'</span>).extract()</span><br><span class="line"> <span class="comment"># 车辆上牌时间 里程 外迁信息</span></span><br><span class="line"> items[<span class="string">'info'</span>] = res.xpath(<span class="string">'//*[@id="basic"]/div[2]/div[2]/div[1]/div[4]/ul/li/div/p/strong/text()'</span>).extract()</span><br><span class="line"> <span class="comment"># 车辆排量</span></span><br><span class="line"> items[<span class="string">'displacement'</span>] = \</span><br><span class="line"> res.xpath(<span class="string">'//*[@id="basic"]/div[2]/div[2]/div[1]/div[4]/ul/li[4]/div/strong/text()'</span>).extract()[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># 车辆上牌城市</span></span><br><span class="line"> items[<span class="string">'registration_city'</span>] = res.xpath(<span class="string">'//*[@id="car-licensed"]/@licensed-city'</span>).extract()[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># 车源号</span></span><br><span class="line"> items[<span class="string">'options'</span>] = \</span><br><span class="line"> res.xpath(<span class="string">'//*[@id="basic"]/div[2]/div[2]/div[1]/div[5]/p/text()'</span>).extract()[<span class="number">0</span>].strip().split(<span class="string">":"</span>)[<span class="number">1</span>]</span><br><span class="line"> <span class="comment"># 判断是都有图片</span></span><br><span class="line"> <span class="keyword">if</span> res.xpath(<span class="string">'//div[@class="info-recommend"]/div/img/@src'</span>):</span><br><span class="line"> <span class="comment"># 车辆图片</span></span><br><span class="line"> items[<span class="string">'car_img'</span>] = res.xpath(<span class="string">'//div[@class="info-recommend"]/div/img/@src'</span>).extract()[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># 车辆所在城市</span></span><br><span class="line"> items[<span class="string">'city'</span>] = res.xpath(<span class="string">'//div[@rrc-event-scope="city"]/a[@class="choose-city"]/text()'</span>).extract()[<span class="number">0</span>].strip()</span><br><span class="line"> <span class="comment"># 车辆颜色</span></span><br><span class="line"> items[<span class="string">'color'</span>] = res.xpath(<span class="string">'//div[@class="card-table"]/table/tr/td[2]/text()'</span>).extract()[<span class="number">0</span>]</span><br><span class="line"></span><br><span class="line"> <span class="keyword">yield</span> items</span><br></pre></td></tr></table></figure><h5 id="客机的爬虫items"><a href="#客机的爬虫items" class="headerlink" title="客机的爬虫items"></a>客机的爬虫items</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> scrapy</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">RenrenchesipderItem</span><span class="params">(scrapy.Item)</span>:</span></span><br><span class="line"> <span class="string">'''定义车辆信息的item'''</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># 定义表名称</span></span><br><span class="line"> collection = <span class="string">'car_info'</span></span><br><span class="line"> <span class="comment"># 定义字段名称</span></span><br><span class="line"> id = scrapy.Field()</span><br><span class="line"> title = scrapy.Field()</span><br><span class="line"> price = scrapy.Field()</span><br><span class="line"> new_car_price = scrapy.Field()</span><br><span class="line"> staging_info = scrapy.Field()</span><br><span class="line"> service_fee = scrapy.Field()</span><br><span class="line"> service = scrapy.Field()</span><br><span class="line"> info = scrapy.Field()</span><br><span class="line"> displacement = scrapy.Field()</span><br><span class="line"> registration_city = scrapy.Field()</span><br><span class="line"> options = scrapy.Field()</span><br><span class="line"> car_img = scrapy.Field()</span><br><span class="line"> city = scrapy.Field()</span><br><span class="line"> color = scrapy.Field()</span><br></pre></td></tr></table></figure><h5 id="客机爬虫管道"><a href="#客机爬虫管道" class="headerlink" title="客机爬虫管道"></a>客机爬虫管道</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> scrapy.conf <span class="keyword">import</span> settings</span><br><span class="line"><span class="keyword">import</span> pymongo</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> renrenchesipder.items <span class="keyword">import</span> RenrenchesipderItem</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">RenrenchesipderPipeline</span><span class="params">(object)</span>:</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">process_item</span><span class="params">(self, item, spider)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> item</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">PymongoPiperline</span><span class="params">(object)</span>:</span></span><br><span class="line"> <span class="string">"""连接mongodb"""</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self)</span>:</span></span><br><span class="line"> self.MONGODB_HOST = settings[<span class="string">'MONGODB_HOST'</span>]</span><br><span class="line"> self.MONGODB_PORT = settings[<span class="string">'MONGODB_PORT'</span>]</span><br><span class="line"> self.MONGODB_DB = settings[<span class="string">'MONGODB_DB'</span>]</span><br><span class="line"> <span class="comment"># 创建连接</span></span><br><span class="line"> conn = pymongo.MongoClient(host=self.MONGODB_HOST, port=self.MONGODB_PORT)</span><br><span class="line"> <span class="comment"># 连接数据库</span></span><br><span class="line"> db = conn[self.MONGODB_DB]</span><br><span class="line"> <span class="comment"># 创建表</span></span><br><span class="line"> self.colltection = db[RenrenchesipderItem.collection]</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">process_item</span><span class="params">(self, item, spider)</span>:</span></span><br><span class="line"> <span class="comment"># 使用id去定位数据库中是否有此数据,如果没有就添加数据.如果已经存在就更新数据</span></span><br><span class="line"> self.colltection.update({<span class="string">'id'</span>: item[<span class="string">'id'</span>]}, {<span class="string">'$set'</span>: item}, <span class="keyword">True</span>)</span><br><span class="line"> <span class="keyword">return</span> item</span><br></pre></td></tr></table></figure><h5 id="客机爬虫中间件"><a href="#客机爬虫中间件" class="headerlink" title="客机爬虫中间件"></a>客机爬虫中间件</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> random</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> scrapy.contrib.downloadermiddleware.useragent <span class="keyword">import</span> UserAgentMiddleware</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> renrenchesipder.utils.useragentsource <span class="keyword">import</span> PROXY, USER_AGENT_LIST</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ProxyMiddleware</span><span class="params">(object)</span>:</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">process_request</span><span class="params">(self, request, spider)</span>:</span></span><br><span class="line"> <span class="comment"># 随机去获取一个代理的ip</span></span><br><span class="line"> proxy = random.choice(PROXY)</span><br><span class="line"> <span class="comment"># 设置代理的地址 如果协议是http下面就改成'http://%s' 加后面的内容</span></span><br><span class="line"> request.meta[<span class="string">'proxy'</span>] = <span class="string">'https://%s'</span> % proxy</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">RandomUserAgent</span><span class="params">(UserAgentMiddleware)</span>:</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">process_request</span><span class="params">(self, request, spider)</span>:</span></span><br><span class="line"> <span class="comment"># 获取随机的一个user_agent的参数</span></span><br><span class="line"> user_agent = random.choice(USER_AGENT_LIST)</span><br><span class="line"> <span class="comment"># 设置请求头中的User-Agent的参数</span></span><br><span class="line"> request.headers.setdefault(<span class="string">'User-Agent'</span>, user_agent)</span><br></pre></td></tr></table></figure><h5 id="客机爬虫的相关设置文件"><a href="#客机爬虫的相关设置文件" class="headerlink" title="客机爬虫的相关设置文件"></a>客机爬虫的相关设置文件</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line">BOT_NAME = <span class="string">'renrenchesipder'</span></span><br><span class="line"></span><br><span class="line">SPIDER_MODULES = [<span class="string">'renrenchesipder.spiders'</span>]</span><br><span class="line">NEWSPIDER_MODULE = <span class="string">'renrenchesipder.spiders'</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># Obey robots.txt rules</span></span><br><span class="line">ROBOTSTXT_OBEY = <span class="keyword">False</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Configure a delay for requests for the same website (default: 0)</span></span><br><span class="line"><span class="comment"># See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay</span></span><br><span class="line"><span class="comment"># See also autothrottle settings and docs</span></span><br><span class="line">DOWNLOAD_DELAY = <span class="number">0.3</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 配置代理 USER_AENGT 和IP代理池</span></span><br><span class="line">DOWNLOADER_MIDDLEWARES = {</span><br><span class="line"> <span class="string">'renrenchesipder.middlewares.ProxyMiddleware'</span>: <span class="number">543</span>,</span><br><span class="line"> <span class="string">'renrenchesipder.middlewares.RandomUserAgent'</span>: <span class="number">544</span>,</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment"># 项目管道设置</span></span><br><span class="line">ITEM_PIPELINES = {</span><br><span class="line"> <span class="string">'renrenchesipder.pipelines.RenrenchesipderPipeline'</span>: <span class="number">300</span>,</span><br><span class="line"> <span class="string">'renrenchesipder.pipelines.PymongoPiperline'</span>: <span class="number">301</span>,</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment"># 设置mongodb常量</span></span><br><span class="line">MONGODB_HOST = <span class="string">'127.0.0.1'</span></span><br><span class="line">MONGODB_PORT = <span class="number">27017</span></span><br><span class="line">MONGODB_DB = <span class="string">'renrenche'</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># redis配置</span></span><br><span class="line">REDIS_HOST = <span class="string">'127.0.0.1'</span></span><br><span class="line">REDIS_PORT = <span class="number">6379</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 启用Rides调度存储请求队列</span></span><br><span class="line">SCHEDULER = <span class="string">"scrapy_redis.scheduler.Scheduler"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 不清除Redis队列、这样可以暂停/恢复 爬取</span></span><br><span class="line">SCHEDULER_PERSIST = <span class="keyword">True</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 如果为True,则使用redis的'spop'进行操作。</span></span><br><span class="line"><span class="comment"># 如果需要避免起始网址列表出现重复,这个选项非常有用。开启此选项urls必须通过sadd添加,否则会出现类型错误。</span></span><br><span class="line">REDIS_START_URLS_AS_SET = <span class="keyword">False</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 去重队列</span></span><br><span class="line">DUPEFILTER_CLASS = <span class="string">"scrapy_redis.dupefilter.RFPDupeFilter"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用优先级调度请求队列 ["scrapy_redis.queue.SpiderQueue" 此项是先入先出队列]</span></span><br><span class="line">SCHEDULER_QUEUE_CLASS = <span class="string">"scrapy_redis.queue.SpiderQueue"</span></span><br></pre></td></tr></table></figure><h5 id="客机爬虫的utils工具文件User-Agent和IP代理"><a href="#客机爬虫的utils工具文件User-Agent和IP代理" class="headerlink" title="客机爬虫的utils工具文件User_Agent和IP代理"></a>客机爬虫的utils工具文件User_Agent和IP代理</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line">USER_AGENT_LIST = [</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.132 Safari/537.36"</span>,</span><br><span class="line"> <span class="string">"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0"</span>,</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line">PROXY = [</span><br><span class="line"> <span class="string">'173.82.219.113:3128'</span>,</span><br><span class="line"> <span class="string">'92.243.6.37:80'</span>,</span><br><span class="line"> <span class="string">'117.102.96.59:8080'</span>,</span><br><span class="line"> <span class="string">'213.234.28.94:8080'</span>,</span><br><span class="line"> <span class="string">'101.51.123.88:8080'</span>,</span><br><span class="line"> <span class="string">'158.58.131.214:41258'</span>,</span><br><span class="line"> <span class="string">'36.83.78.183:80'</span>,</span><br><span class="line"> <span class="string">'103.56.30.128:8080'</span>,</span><br><span class="line"> <span class="string">'185.231.209.251:41258'</span>,</span><br><span class="line"> <span class="string">'178.22.250.244:53281'</span>,</span><br><span class="line"> <span class="string">'89.216.76.253:53281'</span>,</span><br><span class="line"> <span class="string">'179.124.59.240:53281'</span>,</span><br><span class="line"> <span class="string">'36.74.207.47:8080'</span>,</span><br><span class="line"> <span class="string">'104.237.252.30:8181'</span>,</span><br><span class="line"> <span class="string">'183.89.1.16:8080'</span>,</span><br><span class="line"> <span class="string">'202.183.201.7:8081'</span>,</span><br><span class="line"> <span class="string">'140.227.73.83:3128'</span>,</span><br><span class="line"> <span class="string">'191.33.95.123:8080'</span>,</span><br><span class="line"> <span class="string">'103.208.181.10:53281'</span>,</span><br><span class="line"> <span class="string">'77.46.239.33:8080'</span>,</span><br><span class="line"> <span class="string">'94.74.191.82:80'</span>,</span><br><span class="line"> <span class="string">'82.202.70.14:8080'</span>,</span><br><span class="line"> <span class="string">'187.120.211.38:20183'</span>,</span><br><span class="line"> <span class="string">'124.205.155.150:9090'</span>,</span><br><span class="line"> <span class="string">'91.109.16.36:8080'</span>,</span><br><span class="line"> <span class="string">'182.88.89.53:8123'</span>,</span><br><span class="line"> <span class="string">'79.106.162.222:8080'</span>,</span><br><span class="line"> <span class="string">'91.142.239.124:8080'</span>,</span><br><span class="line"> <span class="string">'184.65.158.128:8080'</span>,</span><br><span class="line"> <span class="string">'188.191.28.115:53281'</span>,</span><br><span class="line">]</span><br></pre></td></tr></table></figure><h5 id="客机启动文件"><a href="#客机启动文件" class="headerlink" title="客机启动文件"></a>客机启动文件</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> scrapy.cmdline <span class="keyword">import</span> execute</span><br><span class="line"></span><br><span class="line"><span class="comment"># 最后一个参数要和项目设置的name一一对应</span></span><br><span class="line">execute([<span class="string">'scrapy'</span>,<span class="string">'crawl'</span>,<span class="string">'renrenche'</span>])</span><br></pre></td></tr></table></figure><h4 id="分布式主机的相关文件"><a href="#分布式主机的相关文件" class="headerlink" title="分布式主机的相关文件"></a>分布式主机的相关文件</h4><h5 id="主机的主文件"><a href="#主机的主文件" class="headerlink" title="主机的主文件"></a>主机的主文件</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> re</span><br><span class="line"><span class="keyword">from</span> scrapy_redis.spiders <span class="keyword">import</span> RedisSpider</span><br><span class="line"><span class="keyword">from</span> scrapy <span class="keyword">import</span> Selector, Request</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> renrenchesipder.items <span class="keyword">import</span> MasterItem</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">RenRenCheSipder</span><span class="params">(RedisSpider)</span>:</span></span><br><span class="line"> name = <span class="string">'renrenche'</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># 网站域名</span></span><br><span class="line"> domain_url = <span class="string">'https://www.renrenche.com'</span></span><br><span class="line"> <span class="comment"># 设置过滤爬取的域名</span></span><br><span class="line"> allowed_domains = [<span class="string">'www.renrenche.com'</span>]</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">start_requests</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">yield</span> Request(self.domain_url)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 解析所有城市</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">parse</span><span class="params">(self, response)</span>:</span></span><br><span class="line"> res = Selector(response)</span><br><span class="line"> city_url_list = res.xpath(<span class="string">'//div[@class="area-city-letter"]/div/a[@class="province-item "]/@href'</span>)</span><br><span class="line"> <span class="keyword">for</span> city_url <span class="keyword">in</span> city_url_list:</span><br><span class="line"> city = city_url.extract()</span><br><span class="line"> <span class="keyword">yield</span> Request(self.domain_url + city, callback=self.parse_brand)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 解析所有的品牌</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">parse_brand</span><span class="params">(self, response)</span>:</span></span><br><span class="line"> res = Selector(response)</span><br><span class="line"> brand_url_list = res.xpath(<span class="string">'//*[@id="brand_more_content"]/div/p/span/a'</span>)</span><br><span class="line"> <span class="keyword">for</span> a <span class="keyword">in</span> brand_url_list:</span><br><span class="line"> band_url = a.xpath(<span class="string">'./@href'</span>).extract()[<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">yield</span> Request(self.domain_url + band_url, callback=self.parse_page_url)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 解析某个品牌下面的具体某辆车的页面</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">parse_page_url</span><span class="params">(self, response)</span>:</span></span><br><span class="line"> <span class="comment"># 实例化管道</span></span><br><span class="line"> item = MasterItem()</span><br><span class="line"> res = Selector(response)</span><br><span class="line"> <span class="comment"># 获取到页面的所有li的信息 用于下面的页码的判断</span></span><br><span class="line"> li_list = res.xpath(<span class="string">'//ul[@class="row-fluid list-row js-car-list"]/li'</span>)</span><br><span class="line"> <span class="comment"># 判断页面</span></span><br><span class="line"> <span class="comment"># 判断页面是否有li标签</span></span><br><span class="line"> <span class="keyword">if</span> li_list:</span><br><span class="line"> <span class="keyword">for</span> c <span class="keyword">in</span> li_list:</span><br><span class="line"> <span class="comment"># 获取页面的每个车的url 并且过滤掉有广告的那个a标签</span></span><br><span class="line"> one_car_url = c.xpath(<span class="string">'./a[@class="thumbnail"]/@href'</span>).extract()</span><br><span class="line"> <span class="comment"># 判断是否有这个url</span></span><br><span class="line"> <span class="keyword">if</span> one_car_url:</span><br><span class="line"> item[<span class="string">'url'</span>] = self.domain_url + one_car_url[<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">yield</span> item</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 下一页信息</span></span><br><span class="line"> page = response.meta.get(<span class="string">'page'</span>, <span class="number">2</span>)</span><br><span class="line"> <span class="comment">#</span></span><br><span class="line"> url = response.url</span><br><span class="line"> <span class="comment"># 替换掉上面的结果出现../p1/p2/这样的结果我们只需要一个页面参数</span></span><br><span class="line"> url = re.sub(<span class="string">r'p\d+'</span>, <span class="string">''</span>, url)</span><br><span class="line"> <span class="comment"># 产生新的页面url</span></span><br><span class="line"> car_info_url = url + <span class="string">'p{page}/'</span></span><br><span class="line"> <span class="comment"># 回调 获取下一页</span></span><br><span class="line"> <span class="keyword">yield</span> Request(car_info_url.format(page=page), meta={<span class="string">'page'</span>: page + <span class="number">1</span>}, callback=self.parse_page_url)</span><br></pre></td></tr></table></figure><h5 id="主机爬虫items"><a href="#主机爬虫items" class="headerlink" title="主机爬虫items"></a>主机爬虫items</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> scrapy</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MasterItem</span><span class="params">(scrapy.Item)</span>:</span></span><br><span class="line"> url = scrapy.Field()</span><br></pre></td></tr></table></figure><h5 id="主机爬虫管道"><a href="#主机爬虫管道" class="headerlink" title="主机爬虫管道"></a>主机爬虫管道</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> scrapy.conf <span class="keyword">import</span> settings</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> redis</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">RenrenchesipderPipeline</span><span class="params">(object)</span>:</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">process_item</span><span class="params">(self, item, spider)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> item</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MasterPipeline</span><span class="params">(object)</span>:</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="comment"># 初始化连接数据的变量</span></span><br><span class="line"> self.REDIS_HOST = settings[<span class="string">'REDIS_HOST'</span>]</span><br><span class="line"> self.REDIS_PORT = settings[<span class="string">'REDIS_PORT'</span>]</span><br><span class="line"> <span class="comment"># 链接redis</span></span><br><span class="line"> self.r = redis.Redis(host=self.REDIS_HOST, port=self.REDIS_PORT)</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">process_item</span><span class="params">(self, item, spider)</span>:</span></span><br><span class="line"> <span class="comment"># 向redis中插入需要爬取的链接地址</span></span><br><span class="line"> self.r.lpush(<span class="string">'renrenche:start_urls'</span>, item[<span class="string">'url'</span>])</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> item</span><br></pre></td></tr></table></figure><h5 id="主机的设置settings"><a href="#主机的设置settings" class="headerlink" title="主机的设置settings"></a>主机的设置settings</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">BOT_NAME = <span class="string">'renrenchesipder'</span></span><br><span class="line"></span><br><span class="line">SPIDER_MODULES = [<span class="string">'renrenchesipder.spiders'</span>]</span><br><span class="line">NEWSPIDER_MODULE = <span class="string">'renrenchesipder.spiders'</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Crawl responsibly by identifying yourself (and your website) on the user-agent</span></span><br><span class="line">USER_AGENT = <span class="string">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Obey robots.txt rules</span></span><br><span class="line">ROBOTSTXT_OBEY = <span class="keyword">False</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># Configure a delay for requests for the same website (default: 0)</span></span><br><span class="line"><span class="comment"># See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay</span></span><br><span class="line"><span class="comment"># See also autothrottle settings and docs</span></span><br><span class="line">DOWNLOAD_DELAY = <span class="number">0.3</span></span><br><span class="line"></span><br><span class="line">ITEM_PIPELINES = {</span><br><span class="line"> <span class="string">'renrenchesipder.pipelines.RenrenchesipderPipeline'</span>: <span class="number">300</span>,</span><br><span class="line"> <span class="string">'renrenchesipder.pipelines.MasterPipeline'</span>: <span class="number">303</span>,</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># redis配置</span></span><br><span class="line">REDIS_HOST = <span class="string">'127.0.0.1'</span></span><br><span class="line">REDIS_PORT = <span class="number">6379</span></span><br></pre></td></tr></table></figure><h5 id="主机启动"><a href="#主机启动" class="headerlink" title="主机启动"></a>主机启动</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> scrapy.cmdline <span class="keyword">import</span> execute</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">execute([<span class="string">'scrapy'</span>,<span class="string">'crawl'</span>,<span class="string">'renrenche'</span>])</span><br></pre></td></tr></table></figure><p>到此这个项目就已经完成了.</p><p>最终的结果</p><p><img src="/2018/07/07/Scrapy分布式爬虫-爬取人人车全国二手车车辆信息/qqa.png" alt="q"></p>]]></content>
<tags>
<tag> 分布式爬虫 </tag>
</tags>
</entry>
<entry>
<title>Scrapy框架的使用</title>
<link href="/2018/07/02/Scrapy%E6%A1%86%E6%9E%B6%E7%9A%84%E4%BD%BF%E7%94%A8/"/>
<url>/2018/07/02/Scrapy%E6%A1%86%E6%9E%B6%E7%9A%84%E4%BD%BF%E7%94%A8/</url>
<content type="html"><![CDATA[<h4 id="Scrapy框架的使用"><a href="#Scrapy框架的使用" class="headerlink" title="Scrapy框架的使用"></a>Scrapy框架的使用</h4><p> Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。</p><p>其最初是为了 <a href="http://en.wikipedia.org/wiki/Screen_scraping" target="_blank" rel="noopener">页面抓取</a> (更确切来说, <a href="http://en.wikipedia.org/wiki/Web_scraping" target="_blank" rel="noopener">网络抓取</a> )所设计的, 也可以应用在获取API所返回的数据(例如 <a href="http://aws.amazon.com/associates/" target="_blank" rel="noopener">Amazon Associates Web Services</a> ) 或者通用的网络爬虫。</p><p>本文档将通过介绍Scrapy背后的概念使您对其工作原理有所了解, 并确定Scrapy是否是您所需要的。</p><p>当您准备好开始您的项目后,您可以参考 <a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/tutorial.html#intro-tutorial" target="_blank" rel="noopener">入门教程</a> 。</p><h5 id="1-如何安装scrapy"><a href="#1-如何安装scrapy" class="headerlink" title="1. 如何安装scrapy"></a>1. 如何安装scrapy</h5><p>macos:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install scrapy</span><br></pre></td></tr></table></figure><p>安装完成后进入虚拟环境后.可以使用<code>scarpy</code>命令就能检查是否成功</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">(venv) lizhonglindeMacBook-Pro:qidianspider lizhonglin$ scrapy</span><br><span class="line">Scrapy <span class="number">1.5</span><span class="number">.0</span> - project: qidianspider</span><br><span class="line"></span><br><span class="line">Usage:</span><br><span class="line"> scrapy <command> [options] [args]</span><br><span class="line"></span><br><span class="line">Available commands:</span><br><span class="line"> bench Run quick benchmark test</span><br><span class="line"> check Check spider contracts</span><br><span class="line"> crawl Run a spider</span><br><span class="line"> edit Edit spider</span><br><span class="line"> fetch Fetch a URL using the Scrapy downloader</span><br><span class="line"> genspider Generate new spider using pre-defined templates</span><br><span class="line"> list List available spiders</span><br><span class="line"> parse Parse URL (using its spider) <span class="keyword">and</span> <span class="keyword">print</span> the results</span><br><span class="line"> runspider Run a self-contained spider (without creating a project)</span><br><span class="line"> settings Get settings values</span><br><span class="line"> shell Interactive scraping console</span><br><span class="line"> startproject Create new project</span><br><span class="line"> version Print Scrapy version</span><br><span class="line"> view Open URL <span class="keyword">in</span> browser, <span class="keyword">as</span> seen by Scrapy</span><br><span class="line"></span><br><span class="line">Use <span class="string">"scrapy <command> -h"</span> to see more info about a command</span><br><span class="line">(venv) lizhonglindeMacBook-Pro:qidianspider lizhonglin$</span><br></pre></td></tr></table></figure><p>看到上面这样的结果就表示我们的<code>scrapy</code>已经成功安装了.接下来我们就可以来创建我们的项目了.</p><p>创建项目的命令是:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">scrapy startproject qidianspider</span><br></pre></td></tr></table></figure><p>项目创建成功后有如下的内容:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">qidianspider</span><br><span class="line">qidianspider</span><br><span class="line">scrapy.cfg</span><br><span class="line">__init__.py</span><br><span class="line">items.py</span><br><span class="line">middlewares.py</span><br><span class="line">pipelines.py</span><br><span class="line">settings.py</span><br><span class="line">spider</span><br><span class="line">__init__.py</span><br></pre></td></tr></table></figure><p>这些文件的含义分别是:</p><ul><li><code>scrapy.py</code>: 项目的配置文件</li><li><code>qidianspider</code>: 该项目的python模块</li><li><code>qidianspider/items.py</code>: 项目中的item文件</li><li><code>qidianspider/middlewares.py</code>:</li><li><code>qidianspider/piplines.py</code>:项目中处理数据行为.如:一般结构化的数据持久化</li><li><code>qidianspider/settings.py</code>:项目的设置文件</li><li><code>qidianspider/spiders/</code>: 放置spider代码的目录</li></ul><h5 id="2-创建第一个爬虫项目"><a href="#2-创建第一个爬虫项目" class="headerlink" title="2.创建第一个爬虫项目"></a>2.创建第一个爬虫项目</h5><p>有了这些我们就可以开始写我们的第一个爬虫了.</p><p>在spiders目录下面创建一个<code>qidian.py</code>的文件</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> scrapy</span><br><span class="line"><span class="keyword">from</span> scrapy.selector <span class="keyword">import</span> Selector</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">qiDianSpider</span><span class="params">(scrapy.spiders.Spider)</span>:</span></span><br><span class="line"> <span class="comment"># 启动项目指定的name参数</span></span><br><span class="line"> name = <span class="string">'qidian'</span></span><br><span class="line"> <span class="comment"># 指定爬取的页面</span></span><br><span class="line"> start_urls = {</span><br><span class="line"> <span class="string">'https://www.qidian.com/'</span>,</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">parse</span><span class="params">(self,response)</span>:</span></span><br><span class="line"> <span class="comment">#print(response)</span></span><br><span class="line"> <span class="comment"># 页面源码</span></span><br><span class="line"> <span class="comment"># print(response.body)</span></span><br><span class="line"> res = Selector(response)</span><br><span class="line"> <span class="comment"># 获取对应的菜单名称</span></span><br><span class="line"> menu_type = res.xpath(<span class="string">'//*[@id="classify-list"]/dl/dd/a/cite/span/i/text()'</span>).extract()</span><br><span class="line"> <span class="comment"># 获取对应的菜单连接</span></span><br><span class="line"> menu_type_href = res.xpath(<span class="string">'//*[@id="classify-list"]/dl/dd/a/@href'</span>).extract()</span><br><span class="line"> <span class="comment"># print(menu_type,menu_type_href)</span></span><br><span class="line"> <span class="keyword">return</span> items</span><br></pre></td></tr></table></figure><p>其包含了一个用于下载的初始URL,如何跟进网页中的链接以及如何分析页面中的内容, 提取生成 <a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/items.html#topics-items" target="_blank" rel="noopener">item</a> 的方法。</p><p>为了创建一个Spider,您必须继承 <a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/spiders.html#scrapy.spider.Spider" target="_blank" rel="noopener"><code>scrapy.Spider</code></a> 类, 且定义以下三个属性:</p><ul><li><a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/spiders.html#scrapy.spider.Spider.name" target="_blank" rel="noopener"><code>name</code></a>: 用于区别Spider。 该名字必须是唯一的,您不可以为不同的Spider设定相同的名字。</li><li><a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/spiders.html#scrapy.spider.Spider.start_urls" target="_blank" rel="noopener"><code>start_urls</code></a>: 包含了Spider在启动时进行爬取的url列表。 因此,第一个被获取到的页面将是其中之一。 后续的URL则从初始的URL获取到的数据中提取。</li><li><a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/spiders.html#scrapy.spider.Spider.parse" target="_blank" rel="noopener"><code>parse()</code></a> 是spider的一个方法。 被调用时,每个初始URL完成下载后生成的 <a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/request-response.html#scrapy.http.Response" target="_blank" rel="noopener"><code>Response</code></a> 对象将会作为唯一的参数传递给该函数。 该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的 <a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/request-response.html#scrapy.http.Request" target="_blank" rel="noopener"><code>Request</code></a> 对象。</li></ul><p>这样我们就成功的用<code>scrapy</code>写了第一个爬虫.</p><p>启动我们创建好的爬虫:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">scrapy crawl qidian</span><br></pre></td></tr></table></figure><p>我们能看见如下的输出:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">省略很多行</span><br><span class="line">....</span><br><span class="line"><span class="number">2018</span><span class="number">-07</span><span class="number">-02</span> <span class="number">19</span>:<span class="number">16</span>:<span class="number">06</span> [scrapy.core.engine] INFO: Spider opened</span><br><span class="line"><span class="number">2018</span><span class="number">-07</span><span class="number">-02</span> <span class="number">19</span>:<span class="number">16</span>:<span class="number">06</span> [scrapy.extensions.logstats] INFO: Crawled <span class="number">0</span> pages (at <span class="number">0</span> pages/min), scraped <span class="number">0</span> items (at <span class="number">0</span> items/min)</span><br><span class="line"><span class="number">2018</span><span class="number">-07</span><span class="number">-02</span> <span class="number">19</span>:<span class="number">16</span>:<span class="number">06</span> [scrapy.extensions.telnet] DEBUG: Telnet console listening on <span class="number">127.0</span><span class="number">.0</span><span class="number">.1</span>:<span class="number">6023</span></span><br><span class="line"><span class="number">2018</span><span class="number">-07</span><span class="number">-02</span> <span class="number">19</span>:<span class="number">16</span>:<span class="number">06</span> [scrapy.core.engine] DEBUG: Crawled (<span class="number">200</span>) <GET https://www.qidian.com/robots.txt> (referer: <span class="keyword">None</span>)</span><br><span class="line"><span class="number">2018</span><span class="number">-07</span><span class="number">-02</span> <span class="number">19</span>:<span class="number">16</span>:<span class="number">06</span> [scrapy.core.engine] DEBUG: Crawled (<span class="number">200</span>) <GET https://www.qidian.com/> (referer: <span class="keyword">None</span>)</span><br><span class="line">[<span class="string">'玄幻'</span>, <span class="string">'奇幻'</span>, <span class="string">'武侠'</span>, <span class="string">'仙侠'</span>, <span class="string">'都市'</span>, <span class="string">'现实'</span>, <span class="string">'军事'</span>, <span class="string">'历史'</span>, <span class="string">'游戏'</span>, <span class="string">'体育'</span>, <span class="string">'科幻'</span>, <span class="string">'灵异'</span>, <span class="string">'女生网'</span>, <span class="string">'二次元'</span>] [<span class="string">'/xuanhuan'</span>, <span class="string">'/qihuan'</span>, <span class="string">'/wuxia'</span>, <span class="string">'/xianxia'</span>, <span class="string">'/dushi'</span>, <span class="string">'/xianshi'</span>, <span class="string">'/junshi'</span>, <span class="string">'/lishi'</span>, <span class="string">'/youxi'</span>, <span class="string">'/tiyu'</span>, <span class="string">'/kehuan'</span>, <span class="string">'/lingyi'</span>, <span class="string">'//www.qdmm.com/'</span>, <span class="string">'/2cy'</span>]</span><br><span class="line"><span class="number">2018</span><span class="number">-07</span><span class="number">-02</span> <span class="number">19</span>:<span class="number">16</span>:<span class="number">07</span> [scrapy.core.scraper] ERROR: Spider must <span class="keyword">return</span> Request, BaseItem, dict <span class="keyword">or</span> <span class="keyword">None</span>, got <span class="string">'list'</span> <span class="keyword">in</span> <GET https://www.qidian.com/></span><br><span class="line"><span class="number">2018</span><span class="number">-07</span><span class="number">-02</span> <span class="number">19</span>:<span class="number">16</span>:<span class="number">07</span> [scrapy.core.scraper] ERROR: Spider must <span class="keyword">return</span> Request, BaseItem, dict <span class="keyword">or</span> <span class="keyword">None</span>, got <span class="string">'list'</span> <span class="keyword">in</span> <GET https://www.qidian.com/></span><br><span class="line"><span class="number">2018</span><span class="number">-07</span><span class="number">-02</span> <span class="number">19</span>:<span class="number">16</span>:<span class="number">07</span> [scrapy.core.engine] INFO: Closing spider (finished)</span><br><span class="line"><span class="number">2018</span><span class="number">-07</span><span class="number">-02</span> <span class="number">19</span>:<span class="number">16</span>:<span class="number">07</span> [scrapy.statscollectors] INFO: Dumping Scrapy stats:</span><br><span class="line">....</span><br><span class="line">省略很多行</span><br></pre></td></tr></table></figure><p>可以看到输出的log中包含定义在 <code>start_urls</code> 的初始URL,并且与spider中是一一对应的。在log中可以看到其没有指向其他页面( <code>(referer:None)</code> )。</p><p>Scrapy为Spider的 <code>start_urls</code> 属性中的每个URL创建了 <a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/request-response.html#scrapy.http.Request" target="_blank" rel="noopener"><code>scrapy.Request</code></a> 对象,并将 <code>parse</code> 方法作为回调函数(callback)赋值给了Request。</p><p>Request对象经过调度,执行生成 <a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/request-response.html#scrapy.http.Response" target="_blank" rel="noopener"><code>scrapy.http.Response</code></a> 对象并送回给spider <a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/spiders.html#scrapy.spider.Spider.parse" target="_blank" rel="noopener"><code>parse()</code></a> 方法。</p><h5 id="3-提取Item"><a href="#3-提取Item" class="headerlink" title="3. 提取Item"></a>3. 提取Item</h5><h6 id="Selectors选择器简介"><a href="#Selectors选择器简介" class="headerlink" title="Selectors选择器简介"></a>Selectors选择器简介</h6><p>从网页中提取数据有很多方法。Scrapy使用了一种基于 <a href="http://www.w3.org/TR/xpath" target="_blank" rel="noopener">XPath</a> 和 <a href="http://www.w3.org/TR/selectors" target="_blank" rel="noopener">CSS</a> 表达式机制: <a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/selectors.html#topics-selectors" target="_blank" rel="noopener">Scrapy Selectors</a>。 关于selector和其他提取机制的信息请参考 <a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/selectors.html#topics-selectors" target="_blank" rel="noopener">Selector文档</a> 。</p><p>这里给出XPath表达式的例子及对应的含义:</p><ul><li><code>/html/head/title</code>: 选择HTML文档中 <code><head></code> 标签内的 <code><title></code> 元素</li><li><code>/html/head/title/text()</code>: 选择上面提到的 <code><title></code> 元素的文字</li><li><code>//td</code>: 选择所有的 <code><td></code> 元素</li><li><code>//div[@class="mine"]</code>: 选择所有具有 <code>class="mine"</code> 属性的 <code>div</code> 元素</li></ul><p>上边仅仅是几个简单的XPath例子,XPath实际上要比这远远强大的多。 如果您想了解的更多,我们推荐 <a href="http://www.w3schools.com/XPath/default.asp" target="_blank" rel="noopener">这篇XPath教程</a> 。</p><p>为了配合XPath,Scrapy除了提供了 <a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/selectors.html#scrapy.selector.Selector" target="_blank" rel="noopener"><code>Selector</code></a> 之外,还提供了方法来避免每次从response中提取数据时生成selector的麻烦。</p><p>Selector有四个基本的方法(点击相应的方法可以看到详细的API文档):</p><ul><li><a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/selectors.html#scrapy.selector.Selector.xpath" target="_blank" rel="noopener"><code>xpath()</code></a>: 传入xpath表达式,返回该表达式所对应的所有节点的selector list列表 。</li><li><a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/selectors.html#scrapy.selector.Selector.css" target="_blank" rel="noopener"><code>css()</code></a>: 传入CSS表达式,返回该表达式所对应的所有节点的selector list列表.</li><li><a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/selectors.html#scrapy.selector.Selector.extract" target="_blank" rel="noopener"><code>extract()</code></a>: 序列化该节点为unicode字符串并返回list。</li><li><a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/selectors.html#scrapy.selector.Selector.re" target="_blank" rel="noopener"><code>re()</code></a>: 根据传入的正则表达式对数据进行提取,返回unicode字符串list列表。</li></ul><h5 id="4-保存爬虫数据"><a href="#4-保存爬虫数据" class="headerlink" title="4 . 保存爬虫数据"></a>4 . 保存爬虫数据</h5><p>最简单的方式的就使用如下方式:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">scrapy crawl douban -o items.json</span><br></pre></td></tr></table></figure><p>该命令将采用 <a href="http://en.wikipedia.org/wiki/JSON" target="_blank" rel="noopener">JSON</a> 格式对爬取的数据进行序列化,生成 <code>items.json</code> 文件。</p><p>在类似本篇教程里这样小规模的项目中,这种存储方式已经足够。 如果需要对爬取到的item做更多更为复杂的操作,您可以编写 <a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/item-pipeline.html#topics-item-pipeline" target="_blank" rel="noopener">Item Pipeline</a> 。 类似于我们在创建项目时对Item做的,用于您编写自己的 <code>tutorial/pipelines.py</code> 也被创建。 不过如果您仅仅想要保存item,您不需要实现任何的pipeline。</p><h5 id="2-爬虫案例"><a href="#2-爬虫案例" class="headerlink" title="2, 爬虫案例"></a>2, 爬虫案例</h5><p>爬去豆瓣电影top250的电影资源.并存入到Mongodb数据库</p><h6 id="2-1建立爬虫目录"><a href="#2-1建立爬虫目录" class="headerlink" title="2.1建立爬虫目录"></a>2.1建立爬虫目录</h6><ol><li>添加爬取规则属性rules,这个属性是一个列表,它可以包含多个Rule,每个Rule描述了那些链接需要抓取,那些不需要。这些rule可以有callback,也可以没有。</li><li>爬虫的通常需要在一个网页里面爬去其他的链接,然后一层一层往下爬,scrapy提供了LinkExtractor类用于对网页链接的提取</li></ol><p>LinkExtractor常用的参数有:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">allow:提取满足正则表达式的链接</span><br><span class="line">deny:排除正则表达式匹配的链接(优先级高于allow)</span><br><span class="line">allow_domains:允许的域名(可以是str或list)deny_domains:排除的域名(可以是str或list)</span><br><span class="line">restrict_xpaths:提取满足XPath选择条件的链接(可以是str或list)</span><br><span class="line">restrict_css:提取满足css选择条件的链接(可以是str或list)</span><br><span class="line">tags:提取指定标签下的链接,默认从a和area中提取(可以是str或list)</span><br><span class="line">attrs:提取满足拥有属性的链接,默认为href(类型为list)</span><br><span class="line">unique:链接是否去重(类型为boolean)</span><br><span class="line">process_value:值处理函数(优先级大于allow)</span><br></pre></td></tr></table></figure><p>代码如下:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> scrapy</span><br><span class="line"><span class="keyword">from</span> scrapy.selector <span class="keyword">import</span> Selector</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> qidianspider.items <span class="keyword">import</span> DouBanspiderItem</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">DouBanSpider</span><span class="params">(scrapy.spiders.Spider)</span>:</span></span><br><span class="line"> <span class="comment"># 创建爬虫名称</span></span><br><span class="line"> name = <span class="string">'douban'</span></span><br><span class="line"> search = []</span><br><span class="line"> <span class="comment"># 创建生成爬取链接</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>, <span class="number">250</span>, <span class="number">25</span>):</span><br><span class="line"> a = <span class="string">'https://movie.douban.com/top250?start=%d&filter='</span> % i</span><br><span class="line"> search.append(a)</span><br><span class="line"><span class="comment"># 指定爬取的页面</span></span><br><span class="line"> start_urls = set(search)</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">parse</span><span class="params">(self, response)</span>:</span></span><br><span class="line"> res = Selector(response)</span><br><span class="line"> items = DouBanspiderItem()</span><br><span class="line"> <span class="comment"># 获取电影名称</span></span><br><span class="line"> items[<span class="string">'name'</span>] = res.xpath(<span class="string">'//*[@id="content"]/div/div[1]/ol/li/div/div[2]/div[1]/a/span[1]/text()'</span>).extract()</span><br><span class="line"> <span class="comment"># 获取电影图片</span></span><br><span class="line"> items[<span class="string">'avator'</span>] = res.xpath(<span class="string">'//*[@id="content"]/div/div[1]/ol/li/div/div[1]/a/img/@src'</span>).extract()</span><br><span class="line"> <span class="comment"># 获取电影导演</span></span><br><span class="line"> director_info = res.xpath(<span class="string">'//*[@id="content"]/div/div[1]/ol/li/div/div[2]/div[2]/p[1]/text()[1]'</span>).extract()</span><br><span class="line"> <span class="comment"># 处理导演主演信息</span></span><br><span class="line"> items[<span class="string">'director'</span>] = [info.strip().replace(<span class="string">'\xa0'</span>, <span class="string">''</span>) <span class="keyword">for</span> info <span class="keyword">in</span> director_info]</span><br><span class="line"> <span class="comment"># 处理电影信息</span></span><br><span class="line"> movie_info = res.xpath(<span class="string">'//*[@id="content"]/div/div[1]/ol/li/div/div[2]/div[2]/p[1]/text()[2]'</span>).extract()</span><br><span class="line"> movie_info = [info.strip().replace(<span class="string">'\xa0'</span>, <span class="string">''</span>) <span class="keyword">for</span> info <span class="keyword">in</span> movie_info]</span><br><span class="line"> <span class="comment"># 处理年 国家 分类信息</span></span><br><span class="line"> items[<span class="string">'year'</span>], items[<span class="string">'country'</span>], items[<span class="string">'classification'</span>] = [], [], []</span><br><span class="line"> <span class="keyword">for</span> info <span class="keyword">in</span> movie_info:</span><br><span class="line"> items[<span class="string">'year'</span>].append(info.split(<span class="string">'/'</span>)[<span class="number">0</span>])</span><br><span class="line"> items[<span class="string">'country'</span>].append(info.split(<span class="string">'/'</span>)[<span class="number">1</span>])</span><br><span class="line"> items[<span class="string">'classification'</span>].append(info.split(<span class="string">'/'</span>)[<span class="number">2</span>])</span><br><span class="line"> <span class="comment"># 评分</span></span><br><span class="line"> items[<span class="string">'rate'</span>] = res.xpath(<span class="string">'//*[@id="content"]/div/div[1]/ol/li/div/div[2]/div[2]/div/span[2]/text()'</span>).extract()</span><br><span class="line"> <span class="keyword">return</span> items</span><br></pre></td></tr></table></figure><h6 id="2-2-Items"><a href="#2-2-Items" class="headerlink" title="2.2 Items"></a>2.2 Items</h6><p>爬取的主要目标就是从非结构性的数据源提取结构性数据,例如网页。 Scrapy提供 <a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/items.html#scrapy.item.Item" target="_blank" rel="noopener"><code>Item</code></a> 类来满足这样的需求。</p><p><a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/items.html#scrapy.item.Item" target="_blank" rel="noopener"><code>Item</code></a> 对象是种简单的容器,保存了爬取到得数据。 其提供了 <a href="http://docs.python.org/library/stdtypes.html#dict" target="_blank" rel="noopener">类似于词典(dictionary-like)</a> 的API以及用于声明可用字段的简单语法。</p><p>在<code>itmes.py</code>文件中声明item,Item使用简单的class定义语法以及 <a href="http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/items.html#scrapy.item.Field" target="_blank" rel="noopener"><code>Field</code></a> 对象来声明。例如:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> scrapy</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">DouBanspiderItem</span><span class="params">(scrapy.Item)</span>:</span></span><br><span class="line"> name = scrapy.Field()</span><br><span class="line"> avator = scrapy.Field()</span><br><span class="line"> director = scrapy.Field()</span><br><span class="line"> year = scrapy.Field()</span><br><span class="line"> country = scrapy.Field()</span><br><span class="line"> classification = scrapy.Field()</span><br><span class="line"> rate = scrapy.Field()</span><br></pre></td></tr></table></figure><h6 id="2-3-Item-Pipeline"><a href="#2-3-Item-Pipeline" class="headerlink" title="2.3 Item Pipeline"></a>2.3 Item Pipeline</h6><p>当Item在Spider中被收集之后,它将会被传递到Item Pipeline,一些组件会按照一定的顺序执行对Item的处理。</p><p>每个item pipeline组件(有时称之为“Item Pipeline”)是实现了简单方法的Python类。他们接收到Item并通过它执行一些行为,同时也决定此Item是否继续通过pipeline,或是被丢弃而不再进行处理。</p><p>以下是item pipeline的一些典型应用:</p><ul><li>清理HTML数据</li><li>验证爬取的数据(检查item包含某些字段)</li><li>查重(并丢弃)</li><li>将爬取结果保存到数据库中</li></ul><p>写下面的代码前先去<code>setting.py</code>文件下写入如下配置:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">MONGODB_HOST = <span class="string">'127.0.0.1'</span></span><br><span class="line">MONGODB_PORT = <span class="number">27017</span></span><br><span class="line">MONGODB_DB = <span class="string">'douban'</span></span><br><span class="line">MONGODB_COLLECTION = <span class="string">'movie'</span></span><br></pre></td></tr></table></figure><p>写完上面的代码后我们在写如下的代码. 这样我们可以把重要的配置都放入一个固定的位置方便我们管理.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> pymongo</span><br><span class="line"><span class="keyword">from</span> scrapy.conf <span class="keyword">import</span> settings</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">DouBanspiderPipeline</span><span class="params">(object)</span>:</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self)</span>:</span></span><br><span class="line"> conn = pymongo.MongoClient(host=settings[<span class="string">'MONGODB_HOST'</span>], port=settings[<span class="string">'MONGODB_PORT'</span>])</span><br><span class="line"> db = conn[settings[<span class="string">'MONGODB_DB'</span>]]</span><br><span class="line"> self.collection = db[settings[<span class="string">'MONGODB_COLLECTION'</span>]]</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">process_item</span><span class="params">(self, item, spider)</span>:</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(len(item[<span class="string">'name'</span>])):</span><br><span class="line"> data = {}</span><br><span class="line"> data[<span class="string">'name'</span>] = item[<span class="string">'name'</span>][i]</span><br><span class="line"> data[<span class="string">'avator'</span>] = item[<span class="string">'avator'</span>][i]</span><br><span class="line"> data[<span class="string">'director'</span>] = item[<span class="string">'director'</span>][i]</span><br><span class="line"> data[<span class="string">'year'</span>] = item[<span class="string">'year'</span>][i]</span><br><span class="line"> data[<span class="string">'country'</span>] = item[<span class="string">'country'</span>][i]</span><br><span class="line"> data[<span class="string">'classification'</span>] = item[<span class="string">'classification'</span>][i]</span><br><span class="line"> data[<span class="string">'rate'</span>] = item[<span class="string">'rate'</span>][i]</span><br><span class="line"> <span class="comment"># print(data)</span></span><br><span class="line"> self.collection.insert(data)</span><br><span class="line"> <span class="keyword">return</span> item</span><br></pre></td></tr></table></figure><p>写完这些后我们的代码就告一段落了.接下来我们需要检查我们的mongodb数据库中是否有我们要存的数据库和<code>collection</code>.</p><h6 id="2-4-检查数据库"><a href="#2-4-检查数据库" class="headerlink" title="2.4 检查数据库"></a>2.4 检查数据库</h6><p>在我们本地的终端中输入<code>mongo</code></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">lizhonglindeMacBook-Pro:~ lizhonglin$ mongo</span><br><span class="line">MongoDB shell version v3<span class="number">.6</span><span class="number">.5</span></span><br><span class="line">connecting to: mongodb://<span class="number">127.0</span><span class="number">.0</span><span class="number">.1</span>:<span class="number">27017</span></span><br><span class="line">MongoDB server version: <span class="number">3.6</span><span class="number">.5</span></span><br><span class="line">Server has startup warnings: </span><br><span class="line"><span class="number">2018</span><span class="number">-07</span><span class="number">-01</span>T09:<span class="number">41</span>:<span class="number">06.676</span>+<span class="number">0800</span> I CONTROL [initandlisten] </span><br><span class="line"><span class="number">2018</span><span class="number">-07</span><span class="number">-01</span>T09:<span class="number">41</span>:<span class="number">06.676</span>+<span class="number">0800</span> I CONTROL [initandlisten] ** WARNING: Access control <span class="keyword">is</span> <span class="keyword">not</span> enabled <span class="keyword">for</span> the database.</span><br><span class="line"><span class="number">2018</span><span class="number">-07</span><span class="number">-01</span>T09:<span class="number">41</span>:<span class="number">06.676</span>+<span class="number">0800</span> I CONTROL [initandlisten] ** Read <span class="keyword">and</span> write access to data <span class="keyword">and</span> configuration <span class="keyword">is</span> unrestricted.</span><br><span class="line"><span class="number">2018</span><span class="number">-07</span><span class="number">-01</span>T09:<span class="number">41</span>:<span class="number">06.676</span>+<span class="number">0800</span> I CONTROL [initandlisten] </span><br><span class="line">></span><br></pre></td></tr></table></figure><p>然后在输入</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">show dbs</span><br></pre></td></tr></table></figure><p>就能看见目前我们的数据库</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">show dbs</span><br><span class="line">admin <span class="number">0.000</span>GB</span><br><span class="line">config <span class="number">0.000</span>GB</span><br><span class="line">local <span class="number">0.000</span>GB</span><br></pre></td></tr></table></figure><p>没有我们就用我们的创建数据库的命令进行创建参考这篇文章:<a href="https://kujirashark.github.io/2018/06/30/mongodb%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/#more" target="_blank" rel="noopener"><<MongoDB数据的创建和用法>></a></p><p>这些工作都做完了.就来到我们的最后一步.启动我们的爬虫进行爬取.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">scrapy crawl douban</span><br></pre></td></tr></table></figure><p>最后完成的效果图:</p><p><img src="/2018/07/02/Scrapy框架的使用/shuju.png" alt="huj"></p><p>至此250条数据就完美搞定.</p>]]></content>
<tags>
<tag> Scrapy使用 </tag>
</tags>
</entry>
<entry>
<title>使用selenium|bs4爬取淘宝商品信息</title>
<link href="/2018/06/30/%E4%BD%BF%E7%94%A8selenium-bs4%E7%88%AC%E5%8F%96%E6%B7%98%E5%AE%9D%E5%95%86%E5%93%81%E4%BF%A1%E6%81%AF/"/>
<url>/2018/06/30/%E4%BD%BF%E7%94%A8selenium-bs4%E7%88%AC%E5%8F%96%E6%B7%98%E5%AE%9D%E5%95%86%E5%93%81%E4%BF%A1%E6%81%AF/</url>
<content type="html"><![CDATA[<blockquote><p>作者:李忠林</p><p>Github: <a href="https://github.com/kujirashark" target="_blank" rel="noopener">https://github.com/kujirashark</a></p><p>Gitblog: <a href="https://kujirashark.github.io/" target="_blank" rel="noopener">https://kujirashark.github.io/</a></p></blockquote><p> 使用自动化测试库,来模拟浏览器获取淘宝搜索页面的相关信息.首先我们需要安装selenium | BeautifulSoup4 | pymongo 库.安装方法.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">pip install selenium</span><br><span class="line"></span><br><span class="line">pip install beautifulsoup4</span><br><span class="line"></span><br><span class="line">pip install pymongo</span><br></pre></td></tr></table></figure><p>安装好之后我们需要检查一下是否的都安装成功.检查方法在虚拟环境中输入</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">(venv) deMacBook-Pro:spider00 lizhonglin$ pip freeze </span><br><span class="line"></span><br><span class="line">selenium==<span class="number">3.13</span><span class="number">.0</span></span><br><span class="line">beautifulsoup4==<span class="number">4.6</span><span class="number">.0</span></span><br><span class="line">pymongo==<span class="number">3.7</span><span class="number">.0</span></span><br></pre></td></tr></table></figure><p>能看见这几个东西就表明我们的库已经成功安装了.</p><p>接下来我们就可以开始我们的代码了.首先我们要理清楚解决问题的思路.有了思路了才能开始写我们的代码. 分析问题— — >获取解决问题的方法— — > 解决问题.就有了我们下面的代码.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">from</span> selenium <span class="keyword">import</span> webdriver</span><br><span class="line"><span class="keyword">from</span> bs4 <span class="keyword">import</span> BeautifulSoup</span><br><span class="line"><span class="keyword">from</span> pymongo <span class="keyword">import</span> MongoClient</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">save_data_mongodb</span><span class="params">(data)</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 保存数据到mongodb</span></span><br><span class="line"><span class="string"> :param data: 传入需要保存的数据</span></span><br><span class="line"><span class="string"> :return: 无</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> <span class="comment"># 链接数据库</span></span><br><span class="line"> conn = MongoClient(<span class="string">'mongodb://127.0.0.1:27017'</span>)</span><br><span class="line"> <span class="comment"># 切换到taobao的数据库</span></span><br><span class="line"> db = conn.taobao</span><br><span class="line"> <span class="comment"># 插入数据</span></span><br><span class="line"> db.goods_info.insert(data)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">parse_taobao_goods_info_html</span><span class="params">(html)</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 解析页面信息</span></span><br><span class="line"><span class="string"> :param html: 需要解析的页面</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> soup = BeautifulSoup(html, <span class="string">'lxml'</span>)</span><br><span class="line"> div_list = soup.find_all(<span class="string">'div'</span>, <span class="string">'J_MouserOnverReq'</span>)</span><br><span class="line"> <span class="keyword">for</span> div <span class="keyword">in</span> div_list:</span><br><span class="line"> <span class="comment"># 获取图片和名称</span></span><br><span class="line"> imgs = div.find(<span class="string">'img'</span>, <span class="string">'J_ItemPic'</span>)</span><br><span class="line"> image_link = <span class="string">'https:'</span> + imgs.attrs.get(<span class="string">'data-src'</span>)</span><br><span class="line"> name = imgs.attrs.get(<span class="string">'alt'</span>)</span><br><span class="line"> <span class="comment"># print('商品图片链接:'+image_link)</span></span><br><span class="line"> <span class="comment"># print('商品名称:'+ name)</span></span><br><span class="line"> <span class="comment"># 获取商品的价格</span></span><br><span class="line"> price = div.find(<span class="string">'div'</span>, <span class="string">'g_price-highlight'</span>).find(<span class="string">'strong'</span>).text</span><br><span class="line"> <span class="comment"># print('价格:'+price)</span></span><br><span class="line"> <span class="comment"># 获取商品的销量</span></span><br><span class="line"> sales = div.find(<span class="string">'div'</span>, <span class="string">'deal-cnt'</span>).text.split(<span class="string">'人'</span>)[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># print('销量:'+ sales)</span></span><br><span class="line"> <span class="comment"># 获取商品地区信息</span></span><br><span class="line"> location = div.find(<span class="string">'div'</span>, <span class="string">'location'</span>).text</span><br><span class="line"> <span class="comment"># print('地区:'+ location)</span></span><br><span class="line"> <span class="comment"># 获取商家信息</span></span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> business_info = div.find(<span class="string">'a'</span>, <span class="string">'shopname'</span>).find_all(<span class="string">'span'</span>)[<span class="number">-1</span>].text</span><br><span class="line"> <span class="keyword">except</span>:</span><br><span class="line"> business_info = div.find(<span class="string">'a'</span>, <span class="string">'shopname'</span>).text</span><br><span class="line"></span><br><span class="line"> <span class="comment"># print('商家信息:' + business_info)</span></span><br><span class="line"> result = {</span><br><span class="line"> <span class="string">'name'</span>: name,</span><br><span class="line"> <span class="string">'image_link'</span>: image_link,</span><br><span class="line"> <span class="string">'price'</span>: price,</span><br><span class="line"> <span class="string">'sales'</span>: sales,</span><br><span class="line"> <span class="string">'location'</span>: location,</span><br><span class="line"> <span class="string">'business_info'</span>: business_info</span><br><span class="line"> }</span><br><span class="line"> <span class="comment"># 插入数据</span></span><br><span class="line"> save_data_mongodb(result)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_taobao_html</span><span class="params">(url, keyword)</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 爬取原始页面</span></span><br><span class="line"><span class="string"> :param url: 爬取页面的url</span></span><br><span class="line"><span class="string"> :param keyword: 需要爬取的关键字</span></span><br><span class="line"><span class="string"> :return: 爬取完的所有数据</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> browser = webdriver.Chrome()</span><br><span class="line"> browser.get(url)</span><br><span class="line"> time.sleep(<span class="number">3</span>)</span><br><span class="line"> <span class="comment"># 模拟在输入框内输入数据</span></span><br><span class="line"> browser.find_element_by_id(<span class="string">'q'</span>).send_keys(keyword)</span><br><span class="line"> time.sleep(<span class="number">4</span>)</span><br><span class="line"> <span class="comment"># 模拟点击搜索</span></span><br><span class="line"> browser.find_element_by_class_name(<span class="string">'btn-search'</span>).click()</span><br><span class="line"> time.sleep(<span class="number">2</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 获取到有多少页的搜索结果</span></span><br><span class="line"> total_page = browser.find_element_by_xpath(<span class="string">'//*[@id="mainsrp-pager"]/div/div/div/div[1]'</span>).text.split()[<span class="number">1</span>]</span><br><span class="line"> <span class="comment"># 获取页面资源</span></span><br><span class="line"> print(<span class="string">'正在获取第一页数据'</span>)</span><br><span class="line"> html_source_one = browser.page_source</span><br><span class="line"> time.sleep(<span class="number">8</span>)</span><br><span class="line"> <span class="comment"># print(html_source_one)</span></span><br><span class="line"> print(<span class="string">'正在解析第一页数据'</span>)</span><br><span class="line"> parse_taobao_goods_info_html(html_source_one)</span><br><span class="line"> time.sleep(<span class="number">8</span>)</span><br><span class="line"> print(<span class="string">'第一页数据插入完成'</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># for page in range(int(total_page)):</span></span><br><span class="line"> <span class="keyword">for</span> page <span class="keyword">in</span> range(<span class="number">4</span>):</span><br><span class="line"> <span class="comment"># 判断右下角页面输入框的值,来确定当前页</span></span><br><span class="line"> current_page = int(</span><br><span class="line"> browser.find_element_by_xpath(<span class="string">'//*[@id="mainsrp-pager"]/div/div/div/div[2]/input'</span>).get_attribute(<span class="string">'value'</span>))</span><br><span class="line"> <span class="keyword">if</span> current_page != page:</span><br><span class="line"> bottom = <span class="string">"window.scrollTo(0, document.body.scrollHeight)"</span></span><br><span class="line"> browser.execute_script(bottom)</span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line"> <span class="comment"># 修改要爬取的页面值</span></span><br><span class="line"> browser.find_element_by_xpath(<span class="string">'//*[@id="mainsrp-pager"]/div/div/div/div[2]/input'</span>).clear()</span><br><span class="line"> browser.find_element_by_xpath(<span class="string">'//*[@id="mainsrp-pager"]/div/div/div/div[2]/input'</span>).send_keys(current_page)</span><br><span class="line"> <span class="comment"># 提交要爬取的页面</span></span><br><span class="line"> browser.find_element_by_xpath(<span class="string">'//*[@id="mainsrp-pager"]/div/div/div/div[2]/span[3]'</span>).click()</span><br><span class="line"> time.sleep(<span class="number">3</span>)</span><br><span class="line"> print(<span class="string">'++++++'</span> * <span class="number">10</span>)</span><br><span class="line"> print(<span class="string">'正在获取第%d页数...'</span> % current_page)</span><br><span class="line"> <span class="comment"># 获取当前页面的源码</span></span><br><span class="line"> html_source = browser.page_source</span><br><span class="line"> time.sleep(<span class="number">8</span>)</span><br><span class="line"> <span class="comment"># 解析获取的页面</span></span><br><span class="line"> print(<span class="string">'正在解析第%d页数...'</span> % current_page)</span><br><span class="line"> parse_taobao_goods_info_html(html_source)</span><br><span class="line"> time.sleep(<span class="number">8</span>)</span><br><span class="line"> print(<span class="string">'第%d页数据插入完成......'</span> % current_page)</span><br><span class="line"> browser.close()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> keyword = input(<span class="string">'请输入要搜索的关键字:'</span>)</span><br><span class="line"> url = <span class="string">'https://www.taobao.com/'</span></span><br><span class="line"> get_taobao_html(url, keyword)</span><br></pre></td></tr></table></figure>]]></content>
<tags>
<tag> spider_taobao </tag>
</tags>
</entry>
<entry>
<title>mongodb常用命令</title>
<link href="/2018/06/30/mongodb%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/"/>
<url>/2018/06/30/mongodb%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/</url>
<content type="html"><![CDATA[<p>Mongodb介绍:</p><p> 来自<a href="https://www.mongodb.com/cn" target="_blank" rel="noopener">官网</a>.</p><p> MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是可以应用于各种规模的企业、各个行业以及各类应用程序的开源数据库。作为一个适用于敏捷开发的数据库,MongoDB的数据模式可以随着应用程序的发展而灵活地更新。与此同时,它也为开发人员 提供了传统数据库的功能:二级索引,完整的查询系统以及严格一致性等等。 MongoDB能够使企业更加具有敏捷性和可扩展性,各种规模的企业都可以通过使用MongoDB来创建新的应用,提高与客户之间的工作效率,加快产品上市时间,以及降低企业成本。</p><p>MongoDB是专为可扩展性,高性能和高可用性而设计的数据库。它可以从单服务器部署扩展到大型、复杂的多数据中心架构。利用内存计算的优势,MongoDB能够提供高性能的数据读写操作。 MongoDB的本地复制和自动故障转移功能使您的应用程序具有企业级的可靠性和操作灵活性。</p><h5 id="Mongodb使用教程"><a href="#Mongodb使用教程" class="headerlink" title="Mongodb使用教程"></a>Mongodb使用教程</h5><p>如何安装:</p><p>列举MacOs的安装教程.macos非常方便可以使用<a href="https://brew.sh/index_zh-cn" target="_blank" rel="noopener">Homebrew</a>包管理工具安装.有了这个工具之后只需要一条命令就能安装好mongodb.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew install mongodb</span><br></pre></td></tr></table></figure><h6 id="启动-重启-停止MongoDB服务的命令"><a href="#启动-重启-停止MongoDB服务的命令" class="headerlink" title="启动 | 重启 | 停止MongoDB服务的命令"></a>启动 | 重启 | 停止MongoDB服务的命令</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"># 启动</span><br><span class="line">brew services start mongodb</span><br><span class="line"># 服务端</span><br><span class="line">mongod</span><br><span class="line"># 客户端</span><br><span class="line">mongo</span><br><span class="line"></span><br><span class="line"># 停止</span><br><span class="line">brew services stop mongodb</span><br><span class="line"># 重启</span><br><span class="line">brew services restart mongodb</span><br></pre></td></tr></table></figure><h5 id="Mongodb常用命令:"><a href="#Mongodb常用命令:" class="headerlink" title="Mongodb常用命令:"></a>Mongodb常用命令:</h5><h6 id="1、查询库、查询表"><a href="#1、查询库、查询表" class="headerlink" title="1、查询库、查询表"></a>1、查询库、查询表</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">show dbs //查询所有的数据库</span><br><span class="line"></span><br><span class="line">show collections //查询当前数据库下的所有数据表123</span><br><span class="line"></span><br><span class="line">> // 显示所有数据库</span><br><span class="line">> show dbs</span><br><span class="line">admin 0.000GB</span><br><span class="line">config 0.000GB</span><br><span class="line">local 0.000GB</span><br><span class="line"></span><br><span class="line">> // 创建并切换到spider数据库</span><br><span class="line">> use spider</span><br><span class="line">switched to db spider</span><br><span class="line"></span><br><span class="line">> // 删除当前数据库</span><br><span class="line">> db.dropDatabase()</span><br><span class="line">{ "ok" : 1 }</span><br></pre></td></tr></table></figure><p>注意:如果第一次use spider会创建spider数据库的,但是立马show dbs的时候,并不会展示出当前刚创建的spider的数据库,需要在该数据库下创建了文档才能show dbs看到spider数据库的。这点需要注意一下。</p><h6 id="2、建库和删库"><a href="#2、建库和删库" class="headerlink" title="2、建库和删库"></a>2、建库和删库</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">> // 创建并切换到school数据库</span><br><span class="line">> use school</span><br><span class="line">switched to db school</span><br><span class="line"></span><br><span class="line">> // 创建colleges集合</span><br><span class="line">> db.createCollection('colleges')</span><br><span class="line">{ "ok" : 1 }</span><br><span class="line"></span><br><span class="line">> // 创建students集合</span><br><span class="line">> db.createCollection('students')</span><br><span class="line">{ "ok" : 1 }</span><br><span class="line"></span><br><span class="line">> // 查看所有集合</span><br><span class="line">> show collections</span><br><span class="line">colleges</span><br><span class="line">students</span><br><span class="line"></span><br><span class="line">> // 删除colleges集合</span><br><span class="line">> db.colleges.drop()</span><br><span class="line">true</span><br><span class="line">></span><br></pre></td></tr></table></figure><h6 id="3、单表的增删改"><a href="#3、单表的增删改" class="headerlink" title="3、单表的增删改"></a>3、单表的增删改</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br></pre></td><td class="code"><pre><span class="line">db.myTable.insert({name:’hahaha’,age:12}); //新增</span><br><span class="line"></span><br><span class="line">db.myTable.update({name:’hf’},{$set:{age:25}}) //修改</span><br><span class="line"></span><br><span class="line">db.myTable.remove({name:’hf'}); //删除12345</span><br><span class="line"></span><br><span class="line">> // 向students集合插入文档</span><br><span class="line">> db.students.insert({s_id: 1, name: 'Lee', age: 18})</span><br><span class="line">WriteResult({ "nInserted" : 1 })</span><br><span class="line"></span><br><span class="line">> // 向students集合插入文档</span><br><span class="line">> db.students.save({s_id: 2, name: 'Lee', tel: '12334566789', gender: '男'})</span><br><span class="line">WriteResult({ "nInserted" : 1 })</span><br><span class="line"></span><br><span class="line">> // 查看所有文档</span><br><span class="line">> db.students.find()</span><br><span class="line">{ "_id" : ObjectId("5b24b01f165a0f78dbf82a12"), "s_id" : 2, "name" : "Lee", "tel" : "12334566789", "gender" : "男" }</span><br><span class="line">{ "_id" : ObjectId("5b24b0dc165a0f78dbf82a15"), "s_id" : 1, "name" : "Lee", "age" : 18 }</span><br><span class="line"></span><br><span class="line">> // 更新s_id为1的文档</span><br><span class="line">> db.students.update({'s_id':1}, {'$set':{'age':16}})</span><br><span class="line">WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">> // 插入或更新s_id为3的文档</span><br><span class="line">> db.students.update({s_id: 3}, {'$set': {name: 'jerry', tel: '13022221333', gender: '女'}}, upsert=true)</span><br><span class="line">WriteResult({</span><br><span class="line"> "nMatched" : 0,</span><br><span class="line"> "nUpserted" : 1,</span><br><span class="line"> "nModified" : 0,</span><br><span class="line"> "_id" : ObjectId("5b24b30d4717832ad090f2f5")</span><br><span class="line">})</span><br><span class="line"></span><br><span class="line">> // 查询所有文档</span><br><span class="line">> db.students.find().pretty()</span><br><span class="line">{</span><br><span class="line">"_id" : ObjectId("5b24b01f165a0f78dbf82a12"),</span><br><span class="line">"s_id" : 2,</span><br><span class="line">"name" : "Lee",</span><br><span class="line">"tel" : "12334566789",</span><br><span class="line">"gender" : "男"</span><br><span class="line">}</span><br><span class="line">{</span><br><span class="line">"_id" : ObjectId("5b24b0ba165a0f78dbf82a14"),</span><br><span class="line">"s_id" : 2,</span><br><span class="line">"name" : "Lee",</span><br><span class="line">"tel" : "12334566789",</span><br><span class="line">"gender" : "男"</span><br><span class="line">}</span><br><span class="line">{</span><br><span class="line">"_id" : ObjectId("5b24b0dc165a0f78dbf82a15"),</span><br><span class="line">"s_id" : 1,</span><br><span class="line">"name" : "Lee",</span><br><span class="line">"tel" : "12334566786",</span><br><span class="line">"age" : 16</span><br><span class="line">}</span><br><span class="line">{</span><br><span class="line">"_id" : ObjectId("5b24b30d4717832ad090f2f5"),</span><br><span class="line">"s_id" : 3,</span><br><span class="line">"gender" : "女",</span><br><span class="line">"name" : "jerry",</span><br><span class="line">"tel" : "13022221333"</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>讲解:我们可以使用 find() 方法来查询指定字段的数据,将要返回的字段对应值设置为 1。但是除了 _id 你不能在一个对象中同时指定 0 和 1。否则同时制定0和1的话,会报错误的。</p><h6 id="4、查询"><a href="#4、查询" class="headerlink" title="4、查询"></a>4、查询</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">>> // 查询s_id大于2的文档只显示name和tel字段</span><br><span class="line">> db.students.find({s_id: {'$gt': 2}}, {_id: 0, name: 1, tel: 1}).pretty()</span><br><span class="line"></span><br><span class="line">>> // 查询s_id大于2的文档除了不显示name和tel字段的其他字段</span><br><span class="line">> db.students.find({s_id:{'$gt':2}}, {s_id:0, name:0, _id:0})</span><br><span class="line">{ "gender" : "女", "tel" : "13022221333" }</span><br><span class="line"></span><br><span class="line">>> // 查询s_id大于2的文档只显示_id和name和tel字段</span><br><span class="line">> db.students.find({s_id:{'$gt':2}}, {s_id:1, name:1, _id:1})</span><br><span class="line">{ "_id" : ObjectId("5b24b30d4717832ad090f2f5"), "s_id" : 3, "name" : "jerry" }</span><br></pre></td></tr></table></figure><p> 筛选查询:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">>>// 查询学生文档跳过第1条文档只查1条文档</span><br><span class="line">> db.students.find().skip(1).limit(1).pretty()</span><br><span class="line">{</span><br><span class="line">"_id" : ObjectId("5b24b0ba165a0f78dbf82a14"),</span><br><span class="line">"s_id" : 2,</span><br><span class="line">"name" : "Lee",</span><br><span class="line">"tel" : "12334566789",</span><br><span class="line">"gender" : "男"</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">> // 对查询结果进行排序(1表示升序,-1表示降序)</span><br><span class="line">> db.students.find().sort({s_id: -1})</span><br><span class="line">{ "_id" : ObjectId("5b24b30d4717832ad090f2f5"), "s_id" : 3, "gender" : "女", "name" : "jerry", "tel" : "13022221333" }</span><br><span class="line">{ "_id" : ObjectId("5b24b01f165a0f78dbf82a12"), "s_id" : 2, "name" : "Lee", "tel" : "12334566789", "gender" : "男" }</span><br><span class="line">{ "_id" : ObjectId("5b24b0ba165a0f78dbf82a14"), "s_id" : 2, "name" : "Lee", "tel" : "12334566789", "gender" : "男" }</span><br><span class="line">{ "_id" : ObjectId("5b24b0dc165a0f78dbf82a15"), "s_id" : 1, "name" : "Lee", "tel" : "12334566786", "age" : 16 }</span><br></pre></td></tr></table></figure>]]></content>
<tags>
<tag> Mongodb常用命令 </tag>
</tags>
</entry>
<entry>
<title>Spider(蜘蛛)笔记</title>
<link href="/2018/06/30/Spider-%E8%9C%98%E8%9B%9B-%E7%AC%94%E8%AE%B0/"/>
<url>/2018/06/30/Spider-%E8%9C%98%E8%9B%9B-%E7%AC%94%E8%AE%B0/</url>
<content type="html"><![CDATA[<h4 id="Spider学习笔记"><a href="#Spider学习笔记" class="headerlink" title="Spider学习笔记"></a>Spider学习笔记</h4><h5 id="前言"><a href="#前言" class="headerlink" title="前言:"></a>前言:</h5><p> 网络爬虫(Web Spider。又被称为网页蜘蛛。网络机器人,又称为网页追逐者),是一种依照一定的规则,自己主动的抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁,自己主动索引。模拟程序或者蠕虫。假设把互联网比喻成一个蜘蛛网,那么Spider就是在网上爬来爬去的蜘蛛。</p><p> 网络蜘蛛是通过网页的链接地址来寻找网页的。从站点某一个页面(一般是首页)開始,读取网页的内容。找到在网页中的其他链接地址。然后通过这些链接地址寻找下一个网页。这样一直循环下去,直到把这个站点全部的网页都抓取完为止。假设把整个互联网当成一个站点。那么网络蜘蛛就能够用这个原理把互联网上全部的网页都抓取下来。这样看来,网络爬虫就是一个爬行程序,一个抓取网页的程序。</p><p><strong>简单地说,网络爬虫的基本任务就是抓取网页内容。</strong></p><h5 id="1-数据分析和采集"><a href="#1-数据分析和采集" class="headerlink" title="1. 数据分析和采集"></a>1. 数据分析和采集</h5><p>本爬虫教程中使用的python版本统一为python3.X的版本</p><h6 id="1-1-数据分析"><a href="#1-1-数据分析" class="headerlink" title="1.1 数据分析"></a>1.1 数据分析</h6><p>爬取网页信息可以使用很多的技术:</p><ol><li><p>获取网页信息:urllib、urllib3、requests</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">requests为第三方的库,需要安装才能使用</span><br><span class="line"></span><br><span class="line">pip install requests</span><br></pre></td></tr></table></figure></li><li><p>解析网页信息:beautifulsoup4(bs4)、re、xpath、lxml</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">bs4为第三方的库,需要安装才能使用</span><br><span class="line"></span><br><span class="line">pip install beautifulsoup4</span><br><span class="line"></span><br><span class="line">使用的时候 from bs4 import BeautifulSoup 这样导入</span><br></pre></td></tr></table></figure></li></ol><p>Python 标准库中自带了 xml 模块,但是性能不够好,而且缺乏一些人性化的 API,相比之下,第三方库 lxml 是用 Cython 实现的,而且增加了很多实用的功能。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">安装lxml,在新版本中无法使用from lxml import etree</span><br><span class="line"> </span><br><span class="line"> pip install lxml 并不推荐这样去安装lxml</span><br><span class="line"></span><br><span class="line"> 推荐安装的方法:访问网站(https://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml)下载lxml的安装whl文件,然后进行安装。</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install lxml-4.2.1-cp36-cp36m-win_amd64.whl</span><br></pre></td></tr></table></figure><ol><li><p>动态数据解析</p><p>通用:selenium(自动化测试框架)</p></li></ol><h6 id="1-2-数据采集"><a href="#1-2-数据采集" class="headerlink" title="1.2 数据采集"></a>1.2 数据采集</h6><ol><li><p>存储:mysql、redis、mongodb、sqlalchemy</p></li><li><p>序列化:json</p></li><li><p>调度器:进程、线程、协程</p><p></p></li></ol><h5 id="2-请求头分析"><a href="#2-请求头分析" class="headerlink" title="2. 请求头分析"></a>2. 请求头分析</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"># 浏览器告诉服务器可以接收的文本类型, */*表示任何类型都可以接收</span><br><span class="line">Accept: text/html, */*;q=0.8</span><br><span class="line"></span><br><span class="line"># 浏览器告诉服务器,数据可以压缩,页面可以解压数据然后进行渲染。做爬虫的时候,最好不要写该参数</span><br><span class="line">Accept-Encoding: gzip, deflate </span><br><span class="line"></span><br><span class="line"># 语言类型</span><br><span class="line">Accept-Language: zh-CN,zh;q=0.9 </span><br><span class="line"></span><br><span class="line">Cache-Control: max-age=0</span><br><span class="line"></span><br><span class="line"># 保持连接</span><br><span class="line">Connection: keep-alive </span><br><span class="line"></span><br><span class="line"># 会话 </span><br><span class="line">Cookie: Hm_lvt_3bfcc098e0da26d58c321ba579b04b2f=1527581188,1528137133</span><br><span class="line"></span><br><span class="line"># 域名</span><br><span class="line">Host: www.cdtopspeed.com </span><br><span class="line"></span><br><span class="line">Upgrade-Insecure-Requests: 1</span><br><span class="line"></span><br><span class="line"># 用户代理, 使得服务器能够识别请求是通过浏览器请求过来的,其中包含浏览器的名称/版本等信息</span><br><span class="line">User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36</span><br></pre></td></tr></table></figure><p>其中在爬虫中最重要的就是User-Agent:在下面urllib的使用中就会详细的解释User-Agent的使用</p><h5 id="3-urllib库的使用"><a href="#3-urllib库的使用" class="headerlink" title="3.urllib库的使用"></a>3.urllib库的使用</h5><p><code>urllib</code>是Python自带的标准库,无需安装,直接可以用。</p><p>提供了如下功能:</p><ul><li>网页请求 </li><li>响应获取</li><li>代理和cookie设置</li><li>异常处理</li><li>URL解析</li></ul><blockquote><p>爬虫所需要的功能,基本上在<code>urllib</code>中都能找到,学习这个标准库,可以更加深入的理解后面更加便利的<code>requests</code>库。</p></blockquote><h6 id="3-1-发起请求"><a href="#3-1-发起请求" class="headerlink" title="3.1 发起请求"></a>3.1 发起请求</h6><p>模拟浏览器发起一个 HTTP 请求,我们需要用到 urllib.request 模块。urllib.request 的作用不仅仅是发起请求, 还能获取请求返回结果。发起请求,单靠 <code>urlopen()</code> 方法就可以叱咤风云。我们先看下 urlopen() 的 API</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">urllib.request.urlopen(url, data=<span class="keyword">None</span>, [timeout, ]*, cafile=<span class="keyword">None</span>, capath=<span class="keyword">None</span>, cadefault=<span class="keyword">False</span>, context=<span class="keyword">None</span>)</span><br></pre></td></tr></table></figure><blockquote><ol><li>第一个参数String 类型的地址</li><li><code>data</code>是bytes类型的的内容,可以通过bytes()函数转化字节流,它也是可选参数.使用data参数.请求方式变成以POST方式提交表单.使用标准格式是<code>application/x-www-form-urlencoded</code></li><li><code>timeout</code> 参数是用于设置请求超时时间,单位是秒.</li><li><code>cafile</code>和<code>capath</code>代表CA证书和CA证书的路径.如果使用HTTPS则需要用到.</li><li><code>context</code>参数是<code>ssl.SSLContext</code>类型,用来指定SSL设置</li><li><code>cadefault</code>参数已经被弃用.</li><li>该方法也可以单独传入<code>urllib.request.Resquest</code>对象</li><li>该函数返回结果是一个<code>http.client.HTTPResponse</code>对象</li></ol></blockquote><h6 id="3-2-简单抓取网页"><a href="#3-2-简单抓取网页" class="headerlink" title="3.2 简单抓取网页"></a>3.2 简单抓取网页</h6><p>我们去获取百度首页的源代码</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> urllib.request</span><br><span class="line"></span><br><span class="line">url = <span class="string">"http://www.baidu.com"</span></span><br><span class="line">response = urllib.request.urlopen(url)</span><br><span class="line">html = response.read() <span class="comment"># 获取到页面的源代码</span></span><br><span class="line">print(html.decode(<span class="string">'utf-8'</span>)) <span class="comment"># 转化为 utf-8 编码</span></span><br></pre></td></tr></table></figure><h6 id="3-2-设置请求超时"><a href="#3-2-设置请求超时" class="headerlink" title="3.2 设置请求超时"></a>3.2 设置请求超时</h6><p>有些请求可能因为网络原因无法得到响应。因此,我们可以手动设置超时时间。当请求超时,我们可以采取进一步措施,例如选择直接丢弃该请求或者再请求一次。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> urllib.request</span><br><span class="line"></span><br><span class="line">url = <span class="string">"http://www.baidu.com"</span></span><br><span class="line">response = urllib.request.urlopen(url, timeout=<span class="number">1</span>)</span><br><span class="line">print(response.read().decode(<span class="string">'utf-8'</span>))</span><br></pre></td></tr></table></figure><h6 id="3-3-ssl认证"><a href="#3-3-ssl认证" class="headerlink" title="3.3 ssl认证"></a>3.3 ssl认证</h6><p>什么是 SSL 证书?</p><p>SSL 证书就是遵守 SSL 安全套接层协议的服务器数字证书。</p><p>而 SSL 安全协议最初是由美国网景 Netscape Communication 公司设计开发的,全称为:安全套接层协议 (Secure Sockets Layer) , 它指定了在应用程序协议 ( 如 HTTP 、 Telnet 、 FTP) 和 TCP/IP 之间提供数据安全性分层的机制,它是在传输通信协议 (TCP/IP) 上实现的一种安全协议,采用公开密钥技术,它为 TCP/IP 连接提供数据加密、服务器认证、消息完整性以及可选的客户机认证。由于此协议很好地解决了互联网明文传输的不安全问题,很快得到了业界的支持,并已经成为国际标准。</p><p>SSL 证书由浏览器中“受信任的根证书颁发机构”在验证服务器身份后颁发,具有网站身份验证和加密传输双重功能。</p><p>如果能使用 https:// 来访问某个网站,就表示此网站是部署了SSL证书。一般来讲,如果此网站部署了SSL证书,则在需要加密的页面会自动从 http:// 变为 https:// ,如果没有变,你认为此页面应该加密,您也可以尝试直接手动在浏览器地址栏的http后面加上一个英文字母“ s ”后回车,如果能正常访问并出现安全锁,则表明此网站实际上是部署了SSL证书,只是此页面没有做 https:// 链接;如果不能访问,则表明此网站没有部署 SSL证书。</p><p>有些时候我们在请求的时候回出现如下这样的错误信息.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)></span><br></pre></td></tr></table></figure><p>如果不忽略ssl的安全认证的话,网页的源码会提示ssl认证问题,需要提供ssl认证。我们在做爬虫的时候,自动设置忽略掉ssl认证即可。 如下案例.在京东首页搜索某个商品能出现多少结果.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> re</span><br><span class="line"><span class="keyword">import</span> urllib.request</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用urllib进行中文的编码和解码</span></span><br><span class="line"><span class="keyword">from</span> urllib <span class="keyword">import</span> parse</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> ssl</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">main</span><span class="params">(url)</span>:</span></span><br><span class="line"> <span class="comment"># 请求头</span></span><br><span class="line"> header = {</span><br><span class="line"> <span class="string">'User-Agent'</span>: <span class="string">'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'</span></span><br><span class="line"> }</span><br><span class="line"> <span class="comment"># 设置忽略ssl认证</span></span><br><span class="line"> context = ssl._create_unverified_context()</span><br><span class="line"> <span class="comment"># 发起请求</span></span><br><span class="line"> req = urllib.request.Request(url, headers=header)</span><br><span class="line"> <span class="comment"># 得到响应数据</span></span><br><span class="line"> res = urllib.request.urlopen(req, context=context)</span><br><span class="line"><span class="comment"># 使用正则匹配需要的数据</span></span><br><span class="line"> conent_re = re.findall(<span class="string">'page_count:"(\d+)"'</span>, res.read().decode(<span class="string">'utf-8'</span>))</span><br><span class="line"> </span><br><span class="line"> print(<span class="string">'共有'</span> + conent_re[<span class="number">0</span>] + <span class="string">'页数据'</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">"__main__"</span>:</span><br><span class="line"> </span><br><span class="line"> msg = input(<span class="string">'请输入搜索信息:'</span>)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 使用urllib进行中文的编码和解码</span></span><br><span class="line"> search = parse.urlencode({<span class="string">'keyword'</span>: msg})</span><br><span class="line"> </span><br><span class="line"> url = <span class="string">'https://search.jd.com/Search?%s'</span> % search</span><br><span class="line"> main(url)</span><br></pre></td></tr></table></figure><h5 id="4-使用urllib进行中文的编码和解码"><a href="#4-使用urllib进行中文的编码和解码" class="headerlink" title="4. 使用urllib进行中文的编码和解码"></a>4. 使用urllib进行中文的编码和解码</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">from urllib import parse</span><br><span class="line"></span><br><span class="line"># 编码</span><br><span class="line">enstr = parse.urlencode({'kd': '忠林'})</span><br><span class="line"># 打印的结果为 kd=%E5%BF%A0%E6%9E%97</span><br><span class="line">print(enstr)</span><br><span class="line"></span><br><span class="line"># 解码</span><br><span class="line">destr = parse.unquote(enstr)</span><br><span class="line"># 解码的结果为 kd=忠林</span><br><span class="line">print(destr)</span><br></pre></td></tr></table></figure><p>案例1,爬取格言网中的<code>100句关于梦想的名言警句</code></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> re</span><br><span class="line"><span class="keyword">import</span> urllib.request</span><br><span class="line"><span class="keyword">import</span> ssl</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_motto</span><span class="params">()</span>:</span></span><br><span class="line"> header = {</span><br><span class="line"> <span class="string">'User-Agent'</span>: <span class="string">'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'</span></span><br><span class="line"> }</span><br><span class="line"> <span class="comment"># 请求的url</span></span><br><span class="line"> url = <span class="string">'https://www.geyanw.com/mingyanjingju/1857.html'</span></span><br><span class="line"> </span><br><span class="line"> context = ssl._create_unverified_context()</span><br><span class="line"> </span><br><span class="line"> req = urllib.request.Request(url, headers=header)</span><br><span class="line"> </span><br><span class="line"> res = urllib.request.urlopen(req, context=context)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 正则匹配</span></span><br><span class="line"> pattern = re.compile(<span class="string">'<p>(.*?)</p>'</span>)</span><br><span class="line"></span><br><span class="line"> content_result = re.findall(pattern, res.read().decode(<span class="string">'gbk'</span>))</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 写入文件中去</span></span><br><span class="line"> <span class="keyword">with</span> open(<span class="string">'12.txt'</span>, <span class="string">'w+'</span>, encoding=<span class="string">'utf-8'</span>) <span class="keyword">as</span> f:</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> content_result:</span><br><span class="line"> <span class="keyword">if</span> i != <span class="string">'&nbsp;'</span>:</span><br><span class="line"> f.writelines(i + <span class="string">'\n'</span>)</span><br><span class="line"> <span class="comment"># 关闭文件对象 </span></span><br><span class="line"> f.close()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">"__main__"</span>:</span><br><span class="line"> get_motto()</span><br></pre></td></tr></table></figure><h5 id="5-数据采集"><a href="#5-数据采集" class="headerlink" title="5. 数据采集"></a>5. 数据采集</h5><p>数据采集,针对网页获取源码,按照一定的正则匹配,或者xpath的规则去匹配出我们需要的结果,进行分类筛选入库等操作。在本章中会讲到requests,beautifulsoup等工具去爬取网页,获取相关需要的信息。</p><h6 id="5-1-BeautifSoup库的使用"><a href="#5-1-BeautifSoup库的使用" class="headerlink" title="5.1 BeautifSoup库的使用"></a>5.1 BeautifSoup库的使用</h6><p>Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间.—–引入<a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html" target="_blank" rel="noopener">官网地址</a>的一句话</p><p>Beautiful Soup 4 通过PyPi发布,所以如果你无法使用系统包管理安装,那么也可以通过 easy_install 或 pip 来安装.包的名字是 beautifulsoup4 ,这个包兼容Python2和Python3.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install beautifulsoup4</span><br></pre></td></tr></table></figure><h6 id="5-2-解析语法、find、find-all"><a href="#5-2-解析语法、find、find-all" class="headerlink" title="5.2 解析语法、find、find_all"></a>5.2 解析语法、find、find_all</h6><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">find_all( name , attrs , recursive , text , **kwargs )</span><br></pre></td></tr></table></figure><p>find_all() 方法搜索当前tag的所有tag子节点,并判断是否符合过滤器的条件</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">1. 查询所有a标签的内容</span><br><span class="line"></span><br><span class="line">soup.find_all('a')</span><br><span class="line"></span><br><span class="line">2. 查询所有a标签下class样式为bb的内容</span><br><span class="line"></span><br><span class="line">soup.find_all('a', 'bb')</span><br><span class="line"></span><br><span class="line">3. 查询所有id样式为cc的内容</span><br><span class="line"></span><br><span class="line">soup.find_all(id='cc')</span><br></pre></td></tr></table></figure><p>案例: 爬去知乎发现里面的问答</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">from</span> bs4 <span class="keyword">import</span> BeautifulSoup</span><br><span class="line"><span class="keyword">import</span> pymysql</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_mysql</span><span class="params">(sql, params_list)</span>:</span></span><br><span class="line"> <span class="comment"># 建立连接</span></span><br><span class="line"> conn = pymysql.connect(port=<span class="number">3306</span>, host=<span class="string">'localhost'</span>, password=<span class="string">'123456'</span>, </span><br><span class="line"> charset=<span class="string">'utf8'</span>, user=<span class="string">'root'</span>,database=<span class="string">'spider'</span>)</span><br><span class="line"> <span class="comment"># 创建游标对象</span></span><br><span class="line"> cursor = conn.cursor()</span><br><span class="line"> <span class="comment"># 添加数据</span></span><br><span class="line"> cursor.executemany(sql, params_list)</span><br><span class="line"> <span class="comment"># 提交</span></span><br><span class="line"> conn.commit()</span><br><span class="line"> <span class="comment"># 关闭游标连接</span></span><br><span class="line"> conn.close()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">start_crawl</span><span class="params">(url)</span>:</span></span><br><span class="line"> headers = {</span><br><span class="line"> <span class="string">'User-Agent'</span>: <span class="string">'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'</span></span><br><span class="line"> }</span><br><span class="line"> res = requests.get(url, headers=headers)</span><br><span class="line"> </span><br><span class="line"> soup = BeautifulSoup(res.text, <span class="string">'lxml'</span>)</span><br><span class="line"> <span class="comment"># 筛选类为question_link 的a标签</span></span><br><span class="line"> a_links = soup.find_all(<span class="string">'a'</span>, <span class="string">'question_link'</span>)</span><br><span class="line"></span><br><span class="line"> result_list = []</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> link <span class="keyword">in</span> a_links:</span><br><span class="line"> <span class="comment"># 获取问题的连接</span></span><br><span class="line"> answer_link = <span class="string">'https://www.zhihu.com'</span> + link.get(<span class="string">'href'</span>)</span><br><span class="line"> <span class="comment"># 获取问题的标题</span></span><br><span class="line"> title = link.get_text().replace(<span class="string">'\n'</span>, <span class="string">''</span>)</span><br><span class="line"> <span class="comment"># 追加结果到列表</span></span><br><span class="line"> result_list.append([title, answer_link])</span><br><span class="line"> <span class="comment"># 创建sql语句</span></span><br><span class="line"> sql = <span class="string">'insert into result_news values (%s, %s)'</span></span><br><span class="line"> <span class="comment"># 写入数据库</span></span><br><span class="line"> get_mysql(sql, result_list)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> url = <span class="string">'https://www.zhihu.com/explore'</span></span><br><span class="line"> start_crawl(url)</span><br></pre></td></tr></table></figure><h5 id="6-requests库的使用"><a href="#6-requests库的使用" class="headerlink" title="6. requests库的使用"></a>6. requests库的使用</h5><p><a href="http://docs.python-requests.org/zh_CN/latest/user/quickstart.html" target="_blank" rel="noopener">中文官网地址</a></p><h6 id="6-1安装"><a href="#6-1安装" class="headerlink" title="6.1安装"></a>6.1安装</h6><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install requests</span><br></pre></td></tr></table></figure><h6 id="6-2-发送请求,GET、POST、PUT、PATCH、DELETE"><a href="#6-2-发送请求,GET、POST、PUT、PATCH、DELETE" class="headerlink" title="6.2 发送请求,GET、POST、PUT、PATCH、DELETE"></a>6.2 发送请求,GET、POST、PUT、PATCH、DELETE</h6><p>使用 Requests 发送网络请求非常简单。</p><p>一开始要导入 Requests 模块:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br></pre></td></tr></table></figure><p>然后,尝试获取某个网页。本例子中,我们来获取 Github 的公共时间线:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">r = requests.get(<span class="string">'https://api.github.com/events'</span>)</span><br></pre></td></tr></table></figure><p>现在,我们有一个名为 r 的 Response 对象。我们可以从这个对象中获取所有我们想要的信息。</p><p>Requests 简便的 API 意味着所有 HTTP 请求类型都是显而易见的。例如,你可以这样发送一个 HTTP POST 请求:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">r = requests.post(<span class="string">'http://httpbin.org/post'</span>, data = {<span class="string">'key'</span>:<span class="string">'value'</span>})</span><br></pre></td></tr></table></figure><p>漂亮,对吧?那么其他 HTTP 请求类型:PUT,DELETE,HEAD 以及 OPTIONS 又是如何的呢?都是一样的简单:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">r = requests.put(<span class="string">'http://httpbin.org/put'</span>, data = {<span class="string">'key'</span>:<span class="string">'value'</span>})</span><br><span class="line"></span><br><span class="line">r = requests.delete(<span class="string">'http://httpbin.org/delete'</span>)</span><br><span class="line"></span><br><span class="line">r = requests.head(<span class="string">'http://httpbin.org/get'</span>)</span><br><span class="line"></span><br><span class="line">r = requests.options(<span class="string">'http://httpbin.org/get'</span>)</span><br></pre></td></tr></table></figure><p>都很不错吧,但这也仅是 Requests 的冰山一角呢。</p><h6 id="6-3-传递-URL-参数"><a href="#6-3-传递-URL-参数" class="headerlink" title="6.3 传递 URL 参数"></a>6.3 传递 URL 参数</h6><p>你也许经常想为 URL 的查询字符串(query string)传递某种数据。如果你是手工构建 URL,那么数据会以键/值对的形式置于 URL 中,跟在一个问号的后面。例如, httpbin.org/get?key=val。</p><p>Requests 允许你使用 params 关键字参数,以一个字符串字典来提供这些参数。</p><p>举例来说,如果你想传递 key1=value1 和 key2=value2 到 httpbin.org/get ,那么你可以使用如下代码:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">payload = {<span class="string">'key1'</span>: <span class="string">'value1'</span>, <span class="string">'key2'</span>: <span class="string">'value2'</span>}</span><br><span class="line"></span><br><span class="line">r = requests.get(<span class="string">"http://httpbin.org/get"</span>, params=payload)</span><br></pre></td></tr></table></figure><p>通过打印输出该 URL,你能看到 URL 已被正确编码:</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">print(r.url)</span><br><span class="line"></span><br><span class="line">http://httpbin.org/get?key2=value2&key1=value1</span><br></pre></td></tr></table></figure><p>注意字典里值为 None 的键都不会被添加到 URL 的查询字符串里。</p><p>你还可以将一个列表作为值传入:</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">payload = {<span class="string">'key1'</span>: <span class="string">'value1'</span>, <span class="string">'key2'</span>: [<span class="string">'value2'</span>, <span class="string">'value3'</span>]}</span><br><span class="line"></span><br><span class="line">r = requests.get(<span class="string">'http://httpbin.org/get'</span>, params=payload)</span><br><span class="line"></span><br><span class="line">print(r.url)</span><br><span class="line"></span><br><span class="line">http://httpbin.org/get?key1=value1&key2=value2&key2=value3</span><br></pre></td></tr></table></figure><h6 id="6-4-响应内容"><a href="#6-4-响应内容" class="headerlink" title="6.4 响应内容"></a>6.4 响应内容</h6><p>我们能读取服务器响应的内容。再次以 GitHub 时间线为例:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line">r = requests.get(<span class="string">'https://api.github.com/events'</span>)</span><br><span class="line">r.text</span><br><span class="line"></span><br><span class="line"><span class="string">u'[{"repository":{"open_issues":0,"url":"https://github.com/...</span></span><br></pre></td></tr></table></figure><p>Requests 会自动解码来自服务器的内容。大多数 unicode 字符集都能被无缝地解码。</p><p>请求发出后,Requests 会基于 HTTP 头部对响应的编码作出有根据的推测。当你访问 r.text 之时,Requests 会使用其推测的文本编码。你可以找出 Requests 使用了什么编码,并且能够使用 r.encoding 属性来改变它:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">r.encoding</span><br><span class="line"><span class="string">'utf-8'</span></span><br><span class="line"></span><br><span class="line">r.encoding = <span class="string">'ISO-8859-1'</span></span><br></pre></td></tr></table></figure><p>如果你改变了编码,每当你访问 r.text ,Request 都将会使用 r.encoding 的新值。你可能希望在使用特殊逻辑计算出文本的编码的情况下来修改编码。比如 HTTP 和 XML 自身可以指定编码。这样的话,你应该使用 r.content 来找到编码,然后设置 r.encoding 为相应的编码。这样就能使用正确的编码解析 r.text 了。</p><p>在你需要的情况下,Requests 也可以使用定制的编码。如果你创建了自己的编码,并使用 codecs 模块进行注册,你就可以轻松地使用这个解码器名称作为 r.encoding 的值, 然后由 Requests 来为你处理编码。</p><h6 id="6-5二进制响应内容"><a href="#6-5二进制响应内容" class="headerlink" title="6.5二进制响应内容"></a>6.5二进制响应内容</h6><p>你也能以字节的方式访问请求响应体,对于非文本请求:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">r.content</span><br><span class="line"></span><br><span class="line"><span class="string">b'[{"repository":{"open_issues":0,"url":"https://github.com/...</span></span><br></pre></td></tr></table></figure><p>Requests 会自动为你解码 gzip 和 deflate 传输编码的响应数据。</p><p>例如,以请求返回的二进制数据创建一张图片,你可以使用如下代码:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> PIL <span class="keyword">import</span> Image</span><br><span class="line"><span class="keyword">from</span> io <span class="keyword">import</span> BytesIO</span><br><span class="line"></span><br><span class="line">i = Image.open(BytesIO(r.content))</span><br></pre></td></tr></table></figure><h6 id="6-6-JSON-响应内容"><a href="#6-6-JSON-响应内容" class="headerlink" title="6.6 JSON 响应内容"></a>6.6 JSON 响应内容</h6><p>Requests 中也有一个内置的 JSON 解码器,助你处理 JSON 数据:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"></span><br><span class="line">r = requests.get(<span class="string">'https://api.github.com/events'</span>)</span><br><span class="line">r.json()</span><br><span class="line">[{<span class="string">u'repository'</span>: {<span class="string">u'open_issues'</span>: <span class="number">0</span>, <span class="string">u'url'</span>: <span class="string">'https://github.com/...</span></span><br></pre></td></tr></table></figure><p>如果 JSON 解码失败, r.json() 就会抛出一个异常。例如,响应内容是 401 (Unauthorized),尝试访问 r.json() 将会抛出 ValueError: No JSON object could be decoded 异常。</p><p>需要注意的是,成功调用 r.json() 并<strong>不</strong>意味着响应的成功。有的服务器会在失败的响应中包含一个 JSON 对象(比如 HTTP 500 的错误细节)。这种 JSON 会被解码返回。要检查请求是否成功,请使用 r.raise_for_status() 或者检查 r.status_code 是否和你的期望相同。</p><h6 id="6-7-原始响应内容"><a href="#6-7-原始响应内容" class="headerlink" title="6.7 原始响应内容"></a>6.7 原始响应内容</h6><p>在罕见的情况下,你可能想获取来自服务器的原始套接字响应,那么你可以访问 r.raw。 如果你确实想这么干,那请你确保在初始请求中设置了 stream=True。具体你可以这么做:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">r = requests.get(<span class="string">'https://api.github.com/events'</span>, stream=<span class="keyword">True</span>)</span><br><span class="line">r.raw</span><br><span class="line"><requests.packages.urllib3.response.HTTPResponse object at <span class="number">0x101194810</span>></span><br><span class="line">r.raw.read(<span class="number">10</span>)</span><br><span class="line"><span class="string">'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'</span></span><br></pre></td></tr></table></figure><p>但一般情况下,你应该以下面的模式将文本流保存到文件:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">with</span> open(filename, <span class="string">'wb'</span>) <span class="keyword">as</span> fd:</span><br><span class="line"> <span class="keyword">for</span> chunk <span class="keyword">in</span> r.iter_content(chunk_size):</span><br><span class="line"> fd.write(chunk)</span><br></pre></td></tr></table></figure><p>使用 Response.iter_content 将会处理大量你直接使用 Response.raw 不得不处理的。 当流下载时,上面是优先推荐的获取内容方式。 Note that chunk_size can be freely adjusted to a number that may better fit your use cases.</p><h6 id="6-8-定制请求头"><a href="#6-8-定制请求头" class="headerlink" title="6.8 定制请求头"></a>6.8 定制请求头</h6><p>如果你想为请求添加 HTTP 头部,只要简单地传递一个 dict 给 headers 参数就可以了。</p><p>例如,在前一个示例中我们没有指定 content-type:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">url = <span class="string">'https://api.github.com/some/endpoint'</span></span><br><span class="line">headers = {<span class="string">'user-agent'</span>: <span class="string">'my-app/0.0.1'</span>}</span><br><span class="line"></span><br><span class="line">r = requests.get(url, headers=headers)</span><br></pre></td></tr></table></figure><p>注意: 定制 header 的优先级低于某些特定的信息源,例如:</p><p>如果在 .netrc 中设置了用户认证信息,使用 headers= 设置的授权就不会生效。而如果设置了 auth= 参数,<code>.netrc</code> 的设置就无效了。</p><p>如果被重定向到别的主机,授权 header 就会被删除。</p><p>代理授权 header 会被 URL 中提供的代理身份覆盖掉。</p><p>在我们能判断内容长度的情况下,header 的 Content-Length 会被改写。</p><p>更进一步讲,Requests 不会基于定制 header 的具体情况改变自己的行为。只不过在最后的请求中,所有的 header 信息都会被传递进去。</p><p>注意: 所有的 header 值必须是 string、bytestring 或者 unicode。尽管传递 unicode header 也是允许的,但不建议这样做。</p><p>更加复杂的 POST 请求</p><p>通常,你想要发送一些编码为表单形式的数据——非常像一个 HTML 表单。要实现这个,只需简单地传递一个字典给 data 参数。你的数据字典在发出请求时会自动编码为表单形式:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">payload = {<span class="string">'key1'</span>: <span class="string">'value1'</span>, <span class="string">'key2'</span>: <span class="string">'value2'</span>}</span><br><span class="line"></span><br><span class="line">r = requests.post(<span class="string">"http://httpbin.org/post"</span>, data=payload)</span><br><span class="line"></span><br><span class="line">print(r.text)</span><br><span class="line"></span><br><span class="line">{</span><br><span class="line"> ...</span><br><span class="line"> <span class="string">"form"</span>: {</span><br><span class="line"> <span class="string">"key2"</span>: <span class="string">"value2"</span>,</span><br><span class="line"> <span class="string">"key1"</span>: <span class="string">"value1"</span></span><br><span class="line"> },</span><br><span class="line"> ...</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>你还可以为 data 参数传入一个元组列表。在表单中多个元素使用同一 key 的时候,这种方式尤其有效:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">payload = ((<span class="string">'key1'</span>, <span class="string">'value1'</span>), (<span class="string">'key1'</span>, <span class="string">'value2'</span>))</span><br><span class="line">r = requests.post(<span class="string">'http://httpbin.org/post'</span>, data=payload)</span><br><span class="line">print(r.text)</span><br><span class="line"></span><br><span class="line">{</span><br><span class="line"> ...</span><br><span class="line"> <span class="string">"form"</span>: {</span><br><span class="line"> <span class="string">"key1"</span>: [</span><br><span class="line"> <span class="string">"value1"</span>,</span><br><span class="line"> <span class="string">"value2"</span></span><br><span class="line"> ]</span><br><span class="line"> },</span><br><span class="line"> ...</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>很多时候你想要发送的数据并非编码为表单形式的。如果你传递一个 string 而不是一个 dict,那么数据会被直接发布出去。</p><p>例如,Github API v3 接受编码为 JSON 的 POST/PATCH 数据:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> json</span><br><span class="line"></span><br><span class="line">url = <span class="string">'https://api.github.com/some/endpoint'</span></span><br><span class="line">payload = {<span class="string">'some'</span>: <span class="string">'data'</span>}</span><br><span class="line"></span><br><span class="line">r = requests.post(url, data=json.dumps(payload))</span><br></pre></td></tr></table></figure><p>此处除了可以自行对 dict 进行编码,你还可以使用 json 参数直接传递,然后它就会被自动编码。这是 2.4.2 版的新加功能:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">url = <span class="string">'https://api.github.com/some/endpoint'</span></span><br><span class="line">payload = {<span class="string">'some'</span>: <span class="string">'data'</span>}</span><br><span class="line"></span><br><span class="line">r = requests.post(url, json=payload)</span><br></pre></td></tr></table></figure><p>POST一个多部分编码(Multipart-Encoded)的文件</p><p>Requests 使得上传多部分编码文件变得很简单:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">url = <span class="string">'http://httpbin.org/post'</span></span><br><span class="line">files = {<span class="string">'file'</span>: open(<span class="string">'report.xls'</span>, <span class="string">'rb'</span>)}</span><br><span class="line"></span><br><span class="line">r = requests.post(url, files=files)</span><br><span class="line">r.text</span><br><span class="line"></span><br><span class="line">{</span><br><span class="line"> ...</span><br><span class="line"> <span class="string">"files"</span>: {</span><br><span class="line"> <span class="string">"file"</span>: <span class="string">"<censored...binary...data>"</span></span><br><span class="line"> },</span><br><span class="line"> ...</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>你可以显式地设置文件名,文件类型和请求头:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">url = <span class="string">'http://httpbin.org/post'</span></span><br><span class="line">files = {<span class="string">'file'</span>: (<span class="string">'report.xls'</span>, open(<span class="string">'report.xls'</span>, <span class="string">'rb'</span>), <span class="string">'application/vnd.ms-excel'</span>, {<span class="string">'Expires'</span>: <span class="string">'0'</span>})}</span><br><span class="line"></span><br><span class="line">r = requests.post(url, files=files)</span><br><span class="line">r.text</span><br><span class="line">{</span><br><span class="line"> ...</span><br><span class="line"> <span class="string">"files"</span>: {</span><br><span class="line"> <span class="string">"file"</span>: <span class="string">"<censored...binary...data>"</span></span><br><span class="line"> },</span><br><span class="line"> ...</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>如果你想,你也可以发送作为文件来接收的字符串:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">url = <span class="string">'http://httpbin.org/post'</span></span><br><span class="line">files = {<span class="string">'file'</span>: (<span class="string">'report.csv'</span>, <span class="string">'some,data,to,send\nanother,row,to,send\n'</span>)}</span><br><span class="line"></span><br><span class="line">r = requests.post(url, files=files)</span><br><span class="line">r.text</span><br><span class="line">{</span><br><span class="line"> ...</span><br><span class="line"> <span class="string">"files"</span>: {</span><br><span class="line"> <span class="string">"file"</span>: <span class="string">"some,data,to,send\\nanother,row,to,send\\n"</span></span><br><span class="line"> },</span><br><span class="line"> ...</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>如果你发送一个非常大的文件作为 multipart/form-data 请求,你可能希望将请求做成数据流。默认下 requests 不支持, 但有个第三方包 requests-toolbelt 是支持的。你可以阅读 toolbelt 文档 来了解使用方法。</p><h6 id=""><a href="#" class="headerlink" title=" "></a> </h6><blockquote><p><strong>警告:</strong></p><p>我们强烈建议你用二进制模式(binary mode)打开文件。这是因为 Requests 可能会试图为你提供 Content-Length header,在它这样做的时候,这个值会被设为文件的字节数(bytes)。如果用文本模式(text mode)打开文件,就可能会发生错误。</p></blockquote><h6 id="6-9-响应状态码"><a href="#6-9-响应状态码" class="headerlink" title="6.9 响应状态码"></a>6.9 响应状态码</h6><p>我们可以检测响应状态码:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">r = requests.get(<span class="string">'http://httpbin.org/get'</span>)</span><br><span class="line">r.status_code</span><br><span class="line"><span class="number">200</span></span><br></pre></td></tr></table></figure><p>为方便引用,Requests还附带了一个内置的状态码查询对象:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">r.status_code == requests.codes.ok</span><br><span class="line"></span><br><span class="line"><span class="keyword">True</span></span><br></pre></td></tr></table></figure><p>如果发送了一个错误请求(一个 4XX 客户端错误,或者 5XX 服务器错误响应),我们可以通过 Response.raise_for_status() 来抛出异常:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">bad_r = requests.get(<span class="string">'http://httpbin.org/status/404'</span>)</span><br><span class="line">bad_r.status_code</span><br><span class="line"><span class="number">404</span></span><br><span class="line"></span><br><span class="line">bad_r.raise_for_status()</span><br><span class="line">Traceback (most recent call last):</span><br><span class="line">File <span class="string">"requests/models.py"</span>, line <span class="number">832</span>, <span class="keyword">in</span> raise_for_status</span><br><span class="line"> <span class="keyword">raise</span> http_error</span><br></pre></td></tr></table></figure><p>requests.exceptions.HTTPError: 404 Client Error 但是,由于我们的例子中 r 的 status_code 是 200 ,当我们调用 raise_for_status() 时,得到的是:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">r.raise_for_status()</span><br><span class="line"><span class="keyword">None</span></span><br></pre></td></tr></table></figure><p>一切都挺和谐哈。</p><h6 id="6-10-响应头"><a href="#6-10-响应头" class="headerlink" title="6.10 响应头"></a>6.10 响应头</h6><p>我们可以查看以一个 Python 字典形式展示的服务器响应头:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">r.headers</span><br><span class="line"></span><br><span class="line">{</span><br><span class="line"> <span class="string">'content-encoding'</span>: <span class="string">'gzip'</span>,</span><br><span class="line"> <span class="string">'transfer-encoding'</span>: <span class="string">'chunked'</span>,</span><br><span class="line"> <span class="string">'connection'</span>: <span class="string">'close'</span>,</span><br><span class="line"> <span class="string">'server'</span>: <span class="string">'nginx/1.0.4'</span>,</span><br><span class="line"> <span class="string">'x-runtime'</span>: <span class="string">'148ms'</span>,</span><br><span class="line"> <span class="string">'etag'</span>: <span class="string">'"e1ca502697e5c9317743dc078f67693f"'</span>,</span><br><span class="line"> <span class="string">'content-type'</span>: <span class="string">'application/json'</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>但是这个字典比较特殊:它是仅为 HTTP 头部而生的。根据 RFC 2616, <strong>HTTP 头部是大小写不敏感的。</strong></p><p>因此,我们可以使用任意大写形式来访问这些响应头字段:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">r.headers[<span class="string">'Content-Type'</span>]</span><br><span class="line"><span class="string">'application/json'</span></span><br><span class="line"></span><br><span class="line">r.headers.get(<span class="string">'content-type'</span>)</span><br><span class="line"><span class="string">'application/json'</span></span><br></pre></td></tr></table></figure><p>它还有一个特殊点,那就是服务器可以多次接受同一 header,每次都使用不同的值。但 Requests 会将它们合并,这样它们就可以用一个映射来表示出来,参见 RFC 7230:</p><p>A recipient MAY combine multiple header fields with the same field name into one “field-name: field-value” pair, without changing the semantics of the message, by appending each subsequent field value to the combined field value in order, separated by a comma.</p><p>接收者可以合并多个相同名称的 header 栏位,把它们合为一个 “field-name: field-value” 配对,将每个后续的栏位值依次追加到合并的栏位值中,用逗号隔开即可,这样做不会改变信息的语义。</p><h6 id="6-11-Cookie"><a href="#6-11-Cookie" class="headerlink" title="6.11 Cookie"></a>6.11 Cookie</h6><p>如果某个响应中包含一些 cookie,你可以快速访问它们:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">url = <span class="string">'http://example.com/some/cookie/setting/url'</span></span><br><span class="line">r = requests.get(url)</span><br><span class="line"></span><br><span class="line">r.cookies[<span class="string">'example_cookie_name'</span>]</span><br><span class="line"><span class="string">'example_cookie_value'</span></span><br></pre></td></tr></table></figure><p>要想发送你的cookies到服务器,可以使用 cookies 参数:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">url = <span class="string">'http://httpbin.org/cookies'</span></span><br><span class="line">cookies = dict(cookies_are=<span class="string">'working'</span>)</span><br><span class="line"></span><br><span class="line">r = requests.get(url, cookies=cookies)</span><br><span class="line">r.text</span><br><span class="line"><span class="string">'{"cookies": {"cookies_are": "working"}}'</span></span><br></pre></td></tr></table></figure><p>Cookie 的返回对象为 RequestsCookieJar,它的行为和字典类似,但接口更为完整,适合跨域名跨路径使用。你还可以把 Cookie Jar 传到 Requests 中:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">jar = requests.cookies.RequestsCookieJar()</span><br><span class="line">jar.set(<span class="string">'tasty_cookie'</span>, <span class="string">'yum'</span>, domain=<span class="string">'httpbin.org'</span>, path=<span class="string">'/cookies'</span>)</span><br><span class="line">jar.set(<span class="string">'gross_cookie'</span>, <span class="string">'blech'</span>, domain=<span class="string">'httpbin.org'</span>, path=<span class="string">'/elsewhere'</span>)</span><br><span class="line">url = <span class="string">'http://httpbin.org/cookies'</span></span><br><span class="line">r = requests.get(url, cookies=jar)</span><br><span class="line">r.text</span><br><span class="line"><span class="string">'{"cookies": {"tasty_cookie": "yum"}}'</span></span><br></pre></td></tr></table></figure><h6 id="6-12-重定向与请求历史"><a href="#6-12-重定向与请求历史" class="headerlink" title="6.12 重定向与请求历史"></a>6.12 重定向与请求历史</h6><p>默认情况下,除了 HEAD, Requests 会自动处理所有重定向。</p><p>可以使用响应对象的 history 方法来追踪重定向。</p><p>Response.history 是一个 Response 对象的列表,为了完成请求而创建了这些对象。这个对象列表按照从最老到最近的请求进行排序。</p><p>例如,Github 将所有的 HTTP 请求重定向到 HTTPS:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">r = requests.get(<span class="string">'http://github.com'</span>)</span><br><span class="line"></span><br><span class="line">r.url</span><br><span class="line"><span class="string">'https://github.com/'</span></span><br><span class="line"></span><br><span class="line">r.status_code</span><br><span class="line"><span class="number">200</span></span><br><span class="line"></span><br><span class="line">r.history</span><br><span class="line">[<Response [<span class="number">301</span>]>]</span><br></pre></td></tr></table></figure><p>如果你使用的是GET、OPTIONS、POST、PUT、PATCH 或者 DELETE,那么你可以通过 allow_redirects 参数禁用重定向处理:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">r = requests.get(<span class="string">'http://github.com'</span>, allow_redirects=<span class="keyword">False</span>)</span><br><span class="line">r.status_code</span><br><span class="line"><span class="number">301</span></span><br><span class="line">r.history</span><br><span class="line">[]</span><br></pre></td></tr></table></figure><p>如果你使用了 HEAD,你也可以启用重定向:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">r = requests.head(<span class="string">'http://github.com'</span>, allow_redirects=<span class="keyword">True</span>)</span><br><span class="line">r.url</span><br><span class="line"><span class="string">'https://github.com/'</span></span><br><span class="line">r.history</span><br><span class="line">[<Response [<span class="number">301</span>]>]</span><br></pre></td></tr></table></figure><h6 id="6-13-超时"><a href="#6-13-超时" class="headerlink" title="6.13 超时"></a>6.13 超时</h6><p>你可以告诉 requests 在经过以 timeout 参数设定的秒数时间之后停止等待响应。基本上所有的生产代码都应该使用这一参数。如果不使用,你的程序可能会永远失去响应:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">requests.get(<span class="string">'http://github.com'</span>, timeout=<span class="number">0.001</span>)</span><br><span class="line">Traceback (most recent call last):</span><br><span class="line"> File <span class="string">"<stdin>"</span>, line <span class="number">1</span>, <span class="keyword">in</span> <module></span><br><span class="line">requests.exceptions.Timeout: HTTPConnectionPool(host=<span class="string">'github.com'</span>, port=<span class="number">80</span>): Request timed out. (timeout=<span class="number">0.001</span>)</span><br></pre></td></tr></table></figure><blockquote><p><strong>注意:</strong></p><p>timeout 仅对连接过程有效,与响应体的下载无关。 timeout 并不是整个下载响应的时间限制,而是如果服务器在 timeout 秒内没有应答,将会引发一个异常(更精确地说,是在 timeout 秒内没有从基础套接字上接收到任何字节的数据时)If no timeout is specified explicitly, requests do not time out.</p></blockquote><h6 id="错误与异常"><a href="#错误与异常" class="headerlink" title="错误与异常"></a>错误与异常</h6><p>遇到网络问题(如:DNS 查询失败、拒绝连接等)时,Requests 会抛出一个 ConnectionError 异常。</p><p>如果 HTTP 请求返回了不成功的状态码, Response.raise_for_status() 会抛出一个 HTTPError 异常。</p><p>若请求超时,则抛出一个 Timeout 异常。</p><p>若请求超过了设定的最大重定向次数,则会抛出一个 TooManyRedirects 异常。</p><p>所有Requests显式抛出的异常都继承自 requests.exceptions.RequestException 。</p><p><strong>案例1:爬取豆瓣电影的电影名、评分等信息</strong></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> urllib.request</span><br><span class="line"><span class="keyword">from</span> urllib <span class="keyword">import</span> parse</span><br><span class="line"><span class="keyword">import</span> json</span><br><span class="line"></span><br><span class="line"><span class="string">"""</span></span><br><span class="line"><span class="string">获取豆瓣电影中的电影资源</span></span><br><span class="line"><span class="string">豆瓣电影url地址:https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0</span></span><br><span class="line"><span class="string">分析:</span></span><br><span class="line"><span class="string"> 1. 该页面中的的电影资源信息都是通过ajax异步加载进行刷新出来的</span></span><br><span class="line"><span class="string"> 2. 在F12下的network中过滤XHR(XMLHTTPRESPONSE)请求,可以查看到真正的异步的请求地址如下</span></span><br><span class="line"><span class="string"> https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=20</span></span><br><span class="line"><span class="string"> 3. 正在的请求地址中,type为类型,tag为标签(热门、经典、最新、爱情、科幻等等),sort为排序,page_limit为每一个的条数,page_start为开始的条数下标</span></span><br><span class="line"><span class="string"> 4. 获取tag类型的url地址为: https://movie.douban.com/j/search_tags?type=movie&source=</span></span><br><span class="line"><span class="string">"""</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">urllib_open</span><span class="params">(url)</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 公共的处理代码</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> header = {</span><br><span class="line"> <span class="string">'User-Agent'</span>: <span class="string">'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'</span></span><br><span class="line"> }</span><br><span class="line"> req = urllib.request.Request(url=url, headers=header)</span><br><span class="line"> res = urllib.request.urlopen(req)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> res.read().decode(<span class="string">'utf-8'</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_movie_tag</span><span class="params">(url)</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 获取电影的分类tag</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> tag_res = urllib_open(url)</span><br><span class="line"> <span class="comment"># 返回的tag_res的结果为'{"tags":["热门","最新","经典","可播放","豆瓣高分","冷门佳片","华语","欧美","韩国","日本","动作","喜剧","爱情","科幻","悬疑","恐怖","成长"]}'</span></span><br><span class="line"> <span class="comment"># 其结果为一个字符串类型的数据,需要将之转化为字典类型的</span></span><br><span class="line"> result = json.loads(tag_res)</span><br><span class="line"> content = result[<span class="string">'tags'</span>]</span><br><span class="line"> <span class="keyword">return</span> content</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_movies</span><span class="params">(tag_url, movies_url)</span>:</span></span><br><span class="line"> tag_content = get_movie_tag(tag_url)</span><br><span class="line"> <span class="comment"># 循环tag的内容,拼接出指定tag的电影内容</span></span><br><span class="line"> <span class="comment"># movies_url中指定电影类型的参数是tag=热门或者最新等等,所以需要进行tag的内容的编码</span></span><br><span class="line"> tag_list = []</span><br><span class="line"> print(tag_content)</span><br><span class="line"> <span class="keyword">for</span> tag <span class="keyword">in</span> tag_content:</span><br><span class="line"> data = {<span class="string">'tag'</span>: tag}</span><br><span class="line"> search_tag = parse.urlencode(data)</span><br><span class="line"> tag_list.append(search_tag)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> search_tag <span class="keyword">in</span> tag_list:</span><br><span class="line"> seatch_url = movies_url</span><br><span class="line"> seatch_url = seatch_url % (search_tag)</span><br><span class="line"> movies_res = urllib_open(seatch_url)</span><br><span class="line"> res = json.loads(movies_res)</span><br><span class="line"> result = res[<span class="string">'subjects'</span>]</span><br><span class="line"> <span class="keyword">for</span> res <span class="keyword">in</span> result:</span><br><span class="line"> print(<span class="string">'标题:%s,评分:%s'</span> % (res[<span class="string">'title'</span>], res[<span class="string">'rate'</span>]))</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> tag_url = <span class="string">'https://movie.douban.com/j/search_tags?type=movie&source='</span></span><br><span class="line"> movies_url = <span class="string">'https://movie.douban.com/j/search_subjects?type=movie&%s&sort=recommend&page_limit=20&page_start=0'</span></span><br><span class="line"> get_movies(tag_url, movies_url)</span><br></pre></td></tr></table></figure><p><strong>案例2:爬取图片</strong> </p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">from</span> bs4 <span class="keyword">import</span> BeautifulSoup</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">start_spider_image</span><span class="params">(url)</span>:</span></span><br><span class="line"> headers = {</span><br><span class="line"> <span class="string">'User-Agent'</span>: <span class="string">'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'</span></span><br><span class="line"> }</span><br><span class="line"> req = requests.get(url, headers=headers)</span><br><span class="line"> soup = BeautifulSoup(req.text, <span class="string">'lxml'</span>)</span><br><span class="line"> imgs = soup.find_all(<span class="string">'img'</span>, <span class="string">'photo-item__img'</span>)</span><br><span class="line"> img_link_list = []</span><br><span class="line"> <span class="keyword">for</span> img <span class="keyword">in</span> imgs:</span><br><span class="line"> img_link = img.get(<span class="string">'data-big-src'</span>)</span><br><span class="line"> img_link_list.append(img_link)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 文件保存的路径</span></span><br><span class="line"> path = <span class="string">'/Users/lizhonglin/Desktop/Code/spider00/day02/image'</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># 获取文件名</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> img_link_list:</span><br><span class="line"> <span class="comment"># 获取保存文件的文件名</span></span><br><span class="line"> filename = i.split(<span class="string">'?'</span>)[<span class="number">0</span>].split(<span class="string">'/'</span>)[<span class="number">-1</span>]</span><br><span class="line"> <span class="comment"># 文件写入操作</span></span><br><span class="line"> <span class="keyword">with</span> open(filename, <span class="string">'wb'</span>) <span class="keyword">as</span> f:</span><br><span class="line"> <span class="comment"># 切换到image目录</span></span><br><span class="line"> os.chdir(path)</span><br><span class="line"> <span class="comment"># 写入图片数据</span></span><br><span class="line"> f.write(requests.get(i).content)</span><br><span class="line"> f.close()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> image = input(<span class="string">'请输入搜索关键词英文:'</span>)</span><br><span class="line"> <span class="comment"># 请求url</span></span><br><span class="line"> url = <span class="string">'https://www.pexels.com/search/'</span> + image + <span class="string">'/'</span></span><br><span class="line"> start_spider_image(url)</span><br></pre></td></tr></table></figure><p> <strong>在使用爬虫之前,我们需要了解到很多的概念知识,包括同步、异步概念, 阻塞、非阻塞概念,并发、并行概念,多线程、多进程概念,线程锁概念,协程概念等等</strong></p><h5 id="7-同步异步"><a href="#7-同步异步" class="headerlink" title="7 . 同步异步"></a>7 . 同步异步</h5><ol><li><h6 id="同步"><a href="#同步" class="headerlink" title="同步"></a>同步</h6><ul><li>不同程序单元为了完成某个任务,在执行过程中需靠某种通信方式以<strong>协调一致</strong>,称这些程序单元是同步执行的。</li><li>例如购物系统中更新商品库存,需要用“行锁”作为通信信号,让不同的更新请求强制排队顺序执行,那更新库存的操作是同步的。</li><li>简言之,<strong>同步意味着有序</strong>。</li></ul></li><li><h6 id="异步"><a href="#异步" class="headerlink" title="异步"></a>异步</h6><ul><li>为完成某个任务,不同程序单元之间<strong>过程中无需通信协调</strong>,也能完成任务的方式。</li><li>不相关的程序单元之间可以是异步的。</li><li>例如,爬虫下载网页。调度程序调用下载程序后,即可调度其他任务,而无需与该下载任务保持通信以协调行为。不同网页的下载、保存等操作都是无关的,也无需相互通知协调。这些异步操作的完成时刻并不确定。</li><li>简言之,<strong>异步意味着无序</strong>。</li></ul><p>上文提到的“通信方式”通常是指异步和并发编程提供的同步原语,如信号量、锁、同步队列等等。我们需知道,虽然这些通信方式是为了让多个程序在一定条件下同步执行,但正因为是异步的存在,才需要这些通信方式。如果所有程序都是按序执行,其本身就是同步的,又何需这些同步信号呢?</p><p></p></li></ol><h5 id="8-阻塞非阻塞"><a href="#8-阻塞非阻塞" class="headerlink" title="8. 阻塞非阻塞"></a>8. 阻塞非阻塞</h5><ol><li><p>阻塞</p><ul><li>程序未得到所需计算资源时被挂起的状态。</li><li><strong>程序在等待某个操作完成期间,自身无法继续干别的事情,则称该程序在该操作上是阻塞的。</strong></li><li>常见的阻塞形式有:网络I/O阻塞、磁盘I/O阻塞、用户输入阻塞等。</li></ul><p>阻塞是无处不在的,包括CPU切换上下文时,所有的进程都无法真正干事情,它们也会被阻塞。(如果是多核CPU则正在执行上下文切换操作的核不可被利用。)</p><p></p></li><li><p>非阻塞</p><ul><li><strong>程序在等待某操作过程中,自身不被阻塞,可以继续运行干别的事情,则称该程序在该操作上是非阻塞的。</strong></li><li>非阻塞并<strong>不是</strong>在任何程序级别、任何情况下都可以存在的。</li><li>仅当程序封装的级别可以囊括独立的子程序单元时,它才可能存在非阻塞状态。</li></ul><p>非阻塞的存在是因为阻塞存在,正因为某个操作阻塞导致的耗时与效率低下,我们才要把它变成非阻塞的。</p><p></p></li></ol><h5 id="9-同步和阻塞的区别"><a href="#9-同步和阻塞的区别" class="headerlink" title="9. 同步和阻塞的区别"></a>9. 同步和阻塞的区别</h5><p>同步是一个过程,阻塞是线程的一个状态。</p><p>当多个线程操作同一公共变量的时候可能会出现竞争的情况,这时候需要使用同步来防止多个线程同时占用资源的情况,让一个线程在运行状态中,另外的线程处于就绪状态,当前一个线程处于暂停状态的时候,后面的处于就绪状态的线程,获取到资源以后,获取到时间片以后就会处于运行状态了。所以阻塞是线程的一个状态而已</p><h5 id="10-并发-并行"><a href="#10-并发-并行" class="headerlink" title="10. 并发 并行"></a>10. 并发 并行</h5><ol><li><p>并发</p><ul><li>并发描述的是程序的组织结构。指程序要被设计成多个可独立执行的子任务。</li><li><strong>以利用有限的计算机资源使多个任务可以被实时或近实时执行为目的。</strong></li></ul></li><li><p>并行</p><ul><li>并行描述的是程序的执行状态。指多个任务同时被执行。</li><li><strong>以利用富余计算资源(多核CPU)加速完成多个任务为目的。</strong></li></ul><p>并发提供了一种程序组织结构方式,让问题的解决方案可以并行执行,但并行执行不是必须的。</p><p></p></li></ol><blockquote><p>总结:</p><ul><li><strong>并行</strong>是为了利用多核加速多任务完成的进度</li><li><strong>并发</strong>是为了让独立的子任务都有机会被尽快执行,但不一定能加速整体进度</li><li><strong>非阻塞</strong>是为了提高程序整体执行效率</li><li><strong>异步</strong>是高效地组织非阻塞任务的方式</li></ul><p>要支持并发,必须拆分为多任务,不同任务相对而言才有阻塞/非阻塞、同步/异步。所以,并发、异步、非阻塞三个词总是如影随形。</p></blockquote><p>上面有这样的案例我们可以改造一下案例一,爬取豆瓣电影的名称和评分[使用多线程来实现]</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">import</span> threading</span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">from</span> urllib <span class="keyword">import</span> parse</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_tags</span><span class="params">(url)</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 获取电影分类</span></span><br><span class="line"><span class="string"> :param url:</span></span><br><span class="line"><span class="string"> :return: 电影分类信息</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> headers = {</span><br><span class="line"> <span class="string">'User-Agent'</span>: <span class="string">'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> req = requests.get(url, headers=headers)</span><br><span class="line"> <span class="keyword">return</span> req.json()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_movie</span><span class="params">(url)</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 获取电影信息</span></span><br><span class="line"><span class="string"> :param url:</span></span><br><span class="line"><span class="string"> :return:</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> headers = {</span><br><span class="line"> <span class="string">'User-Agent'</span>: <span class="string">'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'</span></span><br><span class="line"> }</span><br><span class="line"> req = requests.get(url, headers=headers)</span><br><span class="line"> result = req.json()</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> result[<span class="string">'subjects'</span>]:</span><br><span class="line"> title = i[<span class="string">'title'</span>]</span><br><span class="line"> rate = i[<span class="string">'rate'</span>]</span><br><span class="line"> <span class="comment"># 这步可以在优化一下 存储到数据库而不使用print.</span></span><br><span class="line"> print(<span class="string">'名称:%s ,评分:%s'</span> % (title, rate))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">GetMovie</span><span class="params">(threading.Thread)</span>:</span></span><br><span class="line"> <span class="string">"""定义多线程类"""</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self)</span>:</span></span><br><span class="line"> super(GetMovie, self).__init__()</span><br><span class="line"> <span class="comment"># 设置线程锁</span></span><br><span class="line"> self.movie_lock = threading.Lock()</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">update_movie_lock</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="comment"># 判断是否被锁住</span></span><br><span class="line"> <span class="keyword">if</span> self.movie_lock.acquire():</span><br><span class="line"> <span class="comment"># 如果被锁住就弹出一个连接,如果所有结果都被弹出了 就返回空</span></span><br><span class="line"> link = movie_url_list.pop() <span class="keyword">if</span> movie_url_list <span class="keyword">else</span> <span class="string">''</span></span><br><span class="line"> <span class="comment"># 释放线程锁</span></span><br><span class="line"> self.movie_lock.release()</span><br><span class="line"> <span class="keyword">return</span> link</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">run</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="comment"># 获取url的地址</span></span><br><span class="line"> link = self.update_movie_lock()</span><br><span class="line"> <span class="comment"># 判断是否有url</span></span><br><span class="line"> <span class="keyword">if</span> link:</span><br><span class="line"> <span class="comment"># 获取资源</span></span><br><span class="line"> get_movie(link)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> <span class="comment"># 分类的url</span></span><br><span class="line"> url = <span class="string">'https://movie.douban.com/j/search_tags?type=movie&source='</span></span><br><span class="line"> <span class="comment"># 电影信息的url</span></span><br><span class="line"> movie_url = <span class="string">'https://movie.douban.com/j/search_subjects?type=movie&%s&sort=recommend&page_limit=20&page_start=0'</span></span><br><span class="line"> <span class="comment"># 分类的所有信息</span></span><br><span class="line"> tags_list = get_tags(url)</span><br><span class="line"> <span class="comment"># 定义全局变量</span></span><br><span class="line"> <span class="keyword">global</span> movie_url_list</span><br><span class="line"> <span class="comment"># 定义所有的电影资源的url空列表</span></span><br><span class="line"> movie_url_list = []</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> tag <span class="keyword">in</span> tags_list[<span class="string">'tags'</span>]:</span><br><span class="line"> <span class="comment"># 循环遍历分类信息</span></span><br><span class="line"> data = {<span class="string">'tag'</span>: tag}</span><br><span class="line"> <span class="comment"># 组装新的url</span></span><br><span class="line"> m_url = movie_url % parse.urlencode(data)</span><br><span class="line"> movie_url_list.append(m_url)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 启动多线程</span></span><br><span class="line"> <span class="keyword">while</span> <span class="keyword">True</span>:</span><br><span class="line"> <span class="comment"># 如果movie_url_list有值</span></span><br><span class="line"> <span class="keyword">if</span> movie_url_list:</span><br><span class="line"> a1 = GetMovie()</span><br><span class="line"> a2 = GetMovie()</span><br><span class="line"></span><br><span class="line"> a1.start()</span><br><span class="line"> a2.start()</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">break</span></span><br></pre></td></tr></table></figure>]]></content>
<tags>
<tag> Spider基础 </tag>
</tags>
</entry>
<entry>
<title>Ajax写法</title>
<link href="/2018/06/30/Ajax%E5%86%99%E6%B3%95/"/>
<url>/2018/06/30/Ajax%E5%86%99%E6%B3%95/</url>
<content type="html"><![CDATA[<h4 id="什么是AJAX"><a href="#什么是AJAX" class="headerlink" title="什么是AJAX?"></a>什么是AJAX?</h4><p>AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。</p><p>AJAX 不是新的编程语言,而是一种使用现有标准的新方法。</p><p>AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。</p><p>AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。</p><p>常见的写法有:</p><h6 id="1-方式一"><a href="#1-方式一" class="headerlink" title="1.方式一"></a>1.方式一</h6><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1.</span>方式一</span><br><span class="line">$.ajax({</span><br><span class="line">url:<span class="string">''</span>,</span><br><span class="line"> type:<span class="string">''</span>,</span><br><span class="line"> dataType:<span class="string">''</span>,</span><br><span class="line"> data:<span class="string">''</span>,</span><br><span class="line"> headers:<span class="string">''</span>,</span><br><span class="line"> success:<span class="function"><span class="keyword">function</span>(<span class="params">msg</span>)</span>{</span><br><span class="line"> </span><br><span class="line"> },</span><br><span class="line"> error: <span class="function"><span class="keyword">function</span>(<span class="params">msg</span>)</span>{</span><br><span class="line"> </span><br><span class="line"> }</span><br><span class="line">});</span><br></pre></td></tr></table></figure><blockquote><p>参数含义:</p><p><strong>url:</strong> 要求为String类型的参数,(默认为当前页地址)发送请求的地址。</p><p><strong>type:</strong> 要求为String类型的参数,请求方式(post或get)默认为get。注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器支持.</p><p><strong>dataType:</strong> 要求为String类型的参数,预期服务器返回的数据类型。如果不指定,JQuery将自动根据http包mime信息返回responseXML或responseText,并作为回调函数参数传递。可用的类型如下:<br>xml:返回XML文档,可用JQuery处理。<br>html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。<br>script:返回纯文本JavaScript代码。不会自动缓存结果。除非设置了cache参数。注意在远程请求时(不在同一个域下),所有post请求都将转为get请求。<br>json:返回JSON数据。<br>jsonp:JSONP格式。使用SONP形式调用函数时,例如myurl?callback=?,JQuery将自动替换后一个“?”为正确的函数名,以执行回调函数。<br>text:返回纯文本字符串。</p><p><strong>data</strong>: 要求为Object或String类型的参数,发送到服务器的数据。如果已经不是字符串,将自动转换为字符串格式。get请求中将附加在url后。防止这种自动转换,可以查看 processData选项。对象必须为key/value格式,例如{foo1:”bar1”,foo2:”bar2”}转换为&foo1=bar1&foo2=bar2。如果是数组,JQuery将自动为不同值对应同一个名称。例如{foo:[“bar1”,”bar2”]}转换为&foo=bar1&foo=bar2。</p><p><strong>success:</strong>要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。<br> (1)由服务器返回,并根据dataType参数进行处理后的数据。<br> (2)描述状态的字符串。<br> function(data, textStatus){<br> //data可能是xmlDoc、jsonObj、html、text等等<br> this; //调用本次ajax请求时传递的options参数<br> }</p><p><strong>error:</strong> 要求为Function类型的参数,请求失败时被调用的函数。该函数有3个参数,即XMLHttpRequest对象、错误信息、捕获的错误对象(可选)。ajax事件函数如下:<br> function(XMLHttpRequest, textStatus, errorThrown){<br> //通常情况下textStatus和errorThrown只有其中一个包含信息<br> this; //调用本次ajax请求时传递的options参数<br> }</p><p><strong>header:</strong> 在python框架django中前端发起ajax请求如果是post请求需要传csrf参数就是通过header传的</p></blockquote><h6 id="2-方式二-get请求简写"><a href="#2-方式二-get请求简写" class="headerlink" title="2: 方式二 get请求简写"></a>2: 方式二 get请求简写</h6><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$.get(url,<span class="function"><span class="keyword">function</span>(<span class="params">msg</span>)</span>{</span><br><span class="line"> </span><br><span class="line">});</span><br></pre></td></tr></table></figure><h6 id="3-方式三-post请求简写"><a href="#3-方式三-post请求简写" class="headerlink" title="3: 方式三 post请求简写"></a>3: 方式三 post请求简写</h6><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$.post(url,data,<span class="function"><span class="keyword">function</span>(<span class="params">msg</span>)</span>{</span><br><span class="line"> </span><br><span class="line">});</span><br></pre></td></tr></table></figure><h6 id="4-方式四-提交上传文件"><a href="#4-方式四-提交上传文件" class="headerlink" title="4: 方式四 提交上传文件"></a>4: 方式四 提交上传文件</h6><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">$(<span class="keyword">this</span>).ajaxSubmit({</span><br><span class="line"> url:<span class="string">''</span>, </span><br><span class="line"> type:<span class="string">''</span>,</span><br><span class="line"> dataType:<span class="string">''</span>,</span><br><span class="line"> data:<span class="string">''</span>,</span><br><span class="line"> headers:<span class="string">''</span>,</span><br><span class="line"> success:<span class="function"><span class="keyword">function</span>(<span class="params">msg</span>)</span>{ </span><br><span class="line"> },</span><br><span class="line"> error: <span class="function"><span class="keyword">function</span>(<span class="params">msg</span>)</span>{</span><br><span class="line"> </span><br><span class="line"> }</span><br><span class="line">})</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>; <span class="comment">//阻止主动第二次提交</span></span><br></pre></td></tr></table></figure><h6 id="5-前端有多个值需要获取"><a href="#5-前端有多个值需要获取" class="headerlink" title="5, 前端有多个值需要获取"></a>5, 前端有多个值需要获取</h6><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">$(<span class="string">'#form-house-info'</span>).submit(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> a = $(<span class="keyword">this</span>).serialize() <span class="comment">//获取多个值</span></span><br><span class="line"> $.post(<span class="string">'/house/newhouseinfo/'</span>, a ,<span class="function"><span class="keyword">function</span> (<span class="params">data</span>) </span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (data.code == <span class="string">'200'</span>){</span><br><span class="line"> location.href = <span class="string">'/house/myhouse/'</span></span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">});</span><br></pre></td></tr></table></figure>]]></content>
<tags>
<tag> Ajax写法 </tag>
</tags>
</entry>
<entry>
<title>Flask项目部署</title>
<link href="/2018/06/23/Flask%E9%A1%B9%E7%9B%AE%E9%83%A8%E7%BD%B2/"/>
<url>/2018/06/23/Flask%E9%A1%B9%E7%9B%AE%E9%83%A8%E7%BD%B2/</url>
<content type="html"><![CDATA[<h4 id="Flask项目部署"><a href="#Flask项目部署" class="headerlink" title="Flask项目部署"></a>Flask项目部署</h4><h5 id="项目生产环境Flask-mariadb-uwsgi-nginx"><a href="#项目生产环境Flask-mariadb-uwsgi-nginx" class="headerlink" title="项目生产环境Flask + mariadb + uwsgi + nginx"></a>项目生产环境Flask + mariadb + uwsgi + nginx</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">1. 服务器系统</span><br><span class="line"></span><br><span class="line">Centos7.4</span><br><span class="line"></span><br><span class="line">2.数据库</span><br><span class="line"></span><br><span class="line">mariadb redis </span><br><span class="line"></span><br><span class="line">3. 程序运行环境</span><br><span class="line"></span><br><span class="line">python3.x</span><br></pre></td></tr></table></figure><p>由于Centos系统中自带的python版本是的2.x版本的.没有python3. 所以说需要我自己进行安装.</p><p>介绍了这么多就开始我们安装我们需要的软件和环境.</p><h6 id="1-安装python3"><a href="#1-安装python3" class="headerlink" title="1. 安装python3"></a>1. 安装python3</h6><p>首先需要安装python3的依赖包,可以复制下面的两行命令进行安装</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">yum -y groupinstall "Development tools"</span><br><span class="line"></span><br><span class="line">yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel</span><br></pre></td></tr></table></figure><p>安装好相关的依赖包之后要根据我们自己的项目需求选择对应的python3的版本,我这里使用的是python3.6.5的版本</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">使用wget命令下载我们的python3</span><br><span class="line"></span><br><span class="line">wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tar.xz</span><br></pre></td></tr></table></figure><p>我是是用的root账户登录的系统,所以默认的下载文件的地址是在[/root的目录].这样我们是用命令进入root目录找到我们python3.6.5程序使用xz命令进行文件的解压</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"># 解压文件</span><br><span class="line"></span><br><span class="line">xz -d Python-3.6.5.tar.xz</span><br><span class="line"></span><br><span class="line"># 解归档</span><br><span class="line"></span><br><span class="line">tar -xvf Python-3.6.5.tar</span><br></pre></td></tr></table></figure><p>切换至Python源代码目录并执行下面的命令进行配置和安装。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"># 切换到源代码目录</span><br><span class="line"></span><br><span class="line">cd Python-3.6.5</span><br><span class="line"></span><br><span class="line"># 配置</span><br><span class="line"></span><br><span class="line">./configure --prefix=/usr/local/python36 --enable-optimizations</span><br><span class="line"></span><br><span class="line"># 编译和安装</span><br><span class="line"></span><br><span class="line">make && make install</span><br></pre></td></tr></table></figure><p>执行上面的三条命令,然后我们就要经历10-20分钟左右的等待(取决于机器的配置).执行完成后会看到Complete! 这样就表示我们的python3.6.5已经安装好. 但是有一个问题是到这里我们的python3.6.5还是不能运行的.我们需要做最后一步操作.建立软件了到系统的环境变量中去.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"># 建立python3的软连接</span><br><span class="line"></span><br><span class="line">ln -s /usr/local/python36/bin/python3 /usr/bin/python3</span><br><span class="line"></span><br><span class="line"># 建立pip3的软件链接</span><br><span class="line"></span><br><span class="line">ln -s /usr/local/python36/bin/pip3 /usr/bin/pip3</span><br></pre></td></tr></table></figure><p>执行了这两步操作我们的python3就可以正常的在Centos系统中正常运行了.</p><h6 id="2-安装Mariadb数据库"><a href="#2-安装Mariadb数据库" class="headerlink" title="2. 安装Mariadb数据库"></a>2. 安装Mariadb数据库</h6><p>安装命令. 同时安装mariadb的数据库和客户端程序</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum -y install mariadb mariadb-server</span><br></pre></td></tr></table></figure><p>安装完成后我们要启动mariadb数据库[有如下常用的命令]</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"># 启动数据库</span><br><span class="line"></span><br><span class="line">systemctl start mariadb</span><br><span class="line"></span><br><span class="line"># 重启数据库</span><br><span class="line"></span><br><span class="line">systemctl restart mariadb</span><br><span class="line"></span><br><span class="line"># 停止数据库</span><br><span class="line"></span><br><span class="line">systemctl stop mariadb</span><br><span class="line"></span><br><span class="line"># 查看数据库的运行状态</span><br><span class="line"></span><br><span class="line">systemctl status mariadb</span><br><span class="line"></span><br><span class="line"># 设置数据库开机自动启动</span><br><span class="line"></span><br><span class="line">systemctl enable mariadb</span><br></pre></td></tr></table></figure><p>启动好数据库后.由于我们是首次使用数据库我们需要配置数据库的初始密码</p><p>设置密码的命令是:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysql_secure_installation</span><br></pre></td></tr></table></figure><p>这样就会进入到如下的页面,按照要求进行设置.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">Enter current password for root:<–初次运行直接回车</span><br><span class="line"></span><br><span class="line">设置密码</span><br><span class="line"></span><br><span class="line">Set root password? [Y/n] <– 是否设置root用户密码,输入y并回车或直接回车</span><br><span class="line"></span><br><span class="line">New password: <– 设置root用户的密码</span><br><span class="line">Re-enter new password: <– 再输入一次你设置的密码</span><br><span class="line"></span><br><span class="line">其他配置</span><br><span class="line"></span><br><span class="line">Remove anonymous users? [Y/n] <– 是否删除匿名用户,回车</span><br><span class="line"></span><br><span class="line">Disallow root login remotely? [Y/n] <–是否禁止root远程登录,回车,</span><br><span class="line"></span><br><span class="line">Remove test database and access to it? [Y/n] <– 是否删除test数据库,回车</span><br><span class="line"></span><br><span class="line">Reload privilege tables now? [Y/n] <– 是否重新加载权限表,回车</span><br></pre></td></tr></table></figure><p>初始化MariaDB完成,接下来测试登录的命令:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysql -u root -p</span><br></pre></td></tr></table></figure><p>会提示我们数据密码,这个时候我们输入刚才设置的密码就可以登录到数据库中了.</p><p>因为项目需要远程连接数据库,数据库默认是没有开启的所以我们需要开启远程连接.在mysql数据库中的user表中可以看到默认是只能本地连接的,所有可以添加一个新的用户,该用户可以远程访问</p><ol><li><p>创建用户</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"># 先使用数据库</span><br><span class="line"></span><br><span class="line">use mysql;</span><br><span class="line"></span><br><span class="line"># 针对ip</span><br><span class="line">create user 'root'@'192.168.10.10' identified by 'password';</span><br><span class="line"></span><br><span class="line">#全部</span><br><span class="line"> create user 'root'@'%' identified by 'password'; [本项目选择的这条命令,password要替换成自己需要设置的root密码]</span><br></pre></td></tr></table></figure></li><li><p>授权</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"># 给用户最大权限 [本项目选择这条命令,password要替换成自己需要设置的root密码]</span><br><span class="line">grant all privileges on *.* to 'root'@'%' identified by 'password';</span><br><span class="line"></span><br><span class="line"># 给部分权限(test 数据库)</span><br><span class="line"></span><br><span class="line">grant all privileges on test.* to 'root'@'%' identified by 'password' with grant option;</span><br><span class="line"></span><br><span class="line"># 刷新权限表</span><br><span class="line">flush privileges;</span><br><span class="line"></span><br><span class="line"># 查看</span><br><span class="line">show grants for 'root'@'localhost';</span><br></pre></td></tr></table></figure><p>接下来就可以在远程的数据库可视化工具中直接访问该服务器中的mysql了。</p><p>本项目用的是Nacicat</p><p><img src="/2018/06/23/Flask项目部署/na.png" alt=""></p><p></p></li></ol><h6 id="3-安装项目需要使用的虚拟环境"><a href="#3-安装项目需要使用的虚拟环境" class="headerlink" title="3. 安装项目需要使用的虚拟环境"></a>3. 安装项目需要使用的虚拟环境</h6><ol><li><p>安装virtualenv</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum install python-virtualenv</span><br></pre></td></tr></table></figure></li><li><p>创建虚拟环境</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">virtualenv --no-site-packages ajenv</span><br><span class="line"></span><br><span class="line">cd ajenv</span><br><span class="line"></span><br><span class="line"># 激活虚拟环境</span><br><span class="line">source bin/activate</span><br></pre></td></tr></table></figure></li><li><p>安装环境需要的包</p><p>项目文件夹下面自己建立了有一个requirement文件夹下面有一个re_install的文件.就是本项目需要用到的包.这样我们一次性就能全部安装好.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">pip3 install -r re_install.txt</span><br><span class="line"></span><br><span class="line">其中re_install.txt文件中记录的是需要安装包的名称以及对应的版本</span><br></pre></td></tr></table></figure><p></p></li></ol><h5 id="部署"><a href="#部署" class="headerlink" title="部署"></a>部署</h5><p>前面三个准备工作做好了这样我们就可以放心的做我们部署工作了.</p><h6 id="1-安装nginx服务器"><a href="#1-安装nginx服务器" class="headerlink" title="1. 安装nginx服务器"></a>1. 安装nginx服务器</h6><ol><li><p>添加nginx存储库</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum install epel-release</span><br></pre></td></tr></table></figure></li><li><p>安装nginx</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum install nginx</span><br></pre></td></tr></table></figure></li><li><p>运行启动nginx</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl start nginx</span><br></pre></td></tr></table></figure><p>常用的nginx运行命令</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">#查看nginx的状态</span><br><span class="line">systemctl status nginx </span><br><span class="line"># 启动</span><br><span class="line">systemctl start nginx</span><br><span class="line"># 停止关闭</span><br><span class="line">systemctl stop nginx</span><br><span class="line"># 设置开机启动</span><br><span class="line">systemctl enable nginx</span><br><span class="line"># 禁止开机启动</span><br><span class="line">systemctl disable nginx</span><br></pre></td></tr></table></figure><p>需要检查一下如果您正在运行防火墙,请运行以下命令以允许HTTP和HTTPS通信:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">sudo firewall-cmd --permanent --zone=public --add-service=http </span><br><span class="line"></span><br><span class="line">sudo firewall-cmd --permanent --zone=public --add-service=https</span><br><span class="line"></span><br><span class="line">sudo firewall-cmd --reloa</span><br></pre></td></tr></table></figure><p>这些都弄好了我们就可以输入服务器的ip地址到浏览器中看到如下界面:</p></li></ol><p><img src="/2018/06/23/Flask项目部署/nginx.png" alt="gin"></p><h6 id="2-安装uwsgi"><a href="#2-安装uwsgi" class="headerlink" title="2. 安装uwsgi"></a>2. 安装uwsgi</h6><ol><li><p>安装uwsgi (因为我们是python3的环境所以我们一定要使用pip3来安装,否则就安装到python2中去了.)</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip3 install uwsgi</span><br></pre></td></tr></table></figure></li><li><p>将uwsgi配置到环境变量中,建立软链接</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ln -s /usr/local/python36/bin/uwsgi /usr/bin/uwsgi</span><br></pre></td></tr></table></figure></li></ol><h6 id="3-配置项目代码-配置项目nginx-配置uwsgi-ini等"><a href="#3-配置项目代码-配置项目nginx-配置uwsgi-ini等" class="headerlink" title="3. 配置项目代码,配置项目nginx.配置uwsgi.ini等"></a>3. 配置项目代码,配置项目nginx.配置uwsgi.ini等</h6><p>本案例的配置文件,都习惯将每一个项目的配置文件,日志文件,虚拟环境放在一起,这样开发方便,运维也方便维护.项目的目录结构如下:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">[root@izm5eifctth7468z9e6fz0z home]#</span><br><span class="line"></span><br><span class="line">conff envf logf srcf</span><br></pre></td></tr></table></figure><p>由于我的系统中配置过其他项目.这个项目我重新命名了如上面的四个文件夹.其中:</p><p>conff是配置文件,用于存放项目的nginx.conf文件,uwsgi.ini文件</p><p>logf是日志文件,用于存放nginx的启动成功和失败文件,以及uwsgi的运行日志文件</p><p>envf是用于存放虚拟环境</p><p>srcf是项目文件,该目录下上传的是目录代码</p><h6 id="4-配置nginx-conf文件"><a href="#4-配置nginx-conf文件" class="headerlink" title="4. 配置nginx.conf文件"></a>4. 配置nginx.conf文件</h6><p>首先进入conff文件夹中创建一个名称为ajnginx.conf 的文件.</p><p>每一个项目对应有一个自己定义的nginx的配置文件,比如爱家项目,我定义为ajnginx.conf文件.具体配置内容如下:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">server {</span><br><span class="line"> listen 80;</span><br><span class="line"> server_name 47.104.205.141 localhost;</span><br><span class="line"></span><br><span class="line"> access_log /home/logf/access.log;</span><br><span class="line"> error_log /home/logf/error.log;</span><br><span class="line"></span><br><span class="line"> location / {</span><br><span class="line"> include uwsgi_params;</span><br><span class="line"> uwsgi_pass 127.0.0.1:8890;</span><br><span class="line"></span><br><span class="line"> uwsgi_param UWSGI_CHDIR /home/srcf/Aj;</span><br><span class="line"> uwsgi_param UWSGI_SCRIPT manage:app;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><blockquote><p>说明: </p><p>listen — 表示监听的端口</p><p>server_name — 表示服务名称(有域名可以换成域名)</p><p>access_log — nginx成功的文件日志地址</p><p>error_log — nginx失败了的错误日志文件地址</p><p>location — 接收请求</p><p>include uwsgi_params — 固定写法</p><p>uwsgi_param UWSGI_SCRIPT manage:app; # 启动flask的文件:Flask的实例</p><p>uwsgi_param UWSGI_CHDIR 项目的目录</p></blockquote><p>这个配置文件写好之后我们需要修改nginx总的配置文件.这个文件在:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim /etc/nginx/nginx.conf</span><br></pre></td></tr></table></figure><p>修改如下图的位置:</p><p><img src="/2018/06/23/Flask项目部署/zong.png" alt="on"></p><p>修改完成之后我们需要重新启动nginx服务器</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl restart nginx</span><br></pre></td></tr></table></figure><p>看到如下界面表示我们nginx服务器已经正常启动了</p><p><img src="/2018/06/23/Flask项目部署/nginx%E7%8A%B6%E6%80%81.png" alt="ginx状"></p><h6 id="5-配置uwsgi文件"><a href="#5-配置uwsgi文件" class="headerlink" title="5. 配置uwsgi文件"></a>5. 配置uwsgi文件</h6><p>在conff文件夹下在定义一个名称为uwsgi.ini文件.写入如下的配置信息</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">[uwsgi]</span><br><span class="line"></span><br><span class="line">socket=127.0.0.1:8890</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">chdir=/home/srcf/Aj</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">pythonpath=/usr/local/python36/bin/python3</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">pythonhome=/home/envf/ajenv</span><br><span class="line"></span><br><span class="line">callbale=app</span><br><span class="line"></span><br><span class="line">logto = /home/logf/uwsgi.log</span><br></pre></td></tr></table></figure><blockquote><p>说明:</p><p>[uwsgi] — 固定写法必须要有</p><p>socket — 要与nginx中uwsgi_pass一致</p><p>chdir — 项目所在的目录</p><p>pythonpath — python3所在的目录</p><p>pythonhome — 项目虚拟环境的目录</p><p>logto — 项目日志文件位置</p></blockquote><p>这里配置完成就可以开始启动我们的项目了.</p><h6 id="6-迁移我们的数据库"><a href="#6-迁移我们的数据库" class="headerlink" title="6. 迁移我们的数据库"></a>6. 迁移我们的数据库</h6><p><img src="/2018/06/23/Flask项目部署/%E6%95%B0%E6%8D%AE%E8%BF%81%E7%A7%BB.png" alt="据迁"></p><p><img src="/2018/06/23/Flask项目部署/QIYI.png" alt="IY"></p><p>运行项目必须进入到conff文件夹下面,运行的命令是:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">uwsgi --ini uwsgi.ini</span><br></pre></td></tr></table></figure><p>结果:</p><p><img src="/2018/06/23/Flask项目部署/aj.png" alt=""></p><p>多个网站的可以参考文章《<a href="https://kujirashark.github.io/2018/11/09/nginx-uwsgi%E6%88%96nginx-python%E4%B8%ADmanage%E9%83%A8%E7%BD%B2%E5%A4%9A%E4%B8%AA%E7%BD%91%E7%AB%99/" target="_blank" rel="noopener">nginx+uwsgi或nginx+python中manage部署多个网站</a>》</p><p>原创出品,欢迎转载收藏。</p><blockquote><p>作者:lizhonglin</p><p><strong>github:</strong> <a href="https://github.com/kujirashark/" target="_blank" rel="noopener">https://github.com/kujirashark/</a></p><p><strong>blog:</strong> <a href="https://kujirashark.github.io/" target="_blank" rel="noopener">https://kujirashark.github.io/</a></p></blockquote>]]></content>
<tags>
<tag> Flask部署 </tag>
</tags>
</entry>
<entry>
<title>初学者的flask项目</title>
<link href="/2018/06/18/%E5%88%9D%E5%AD%A6%E8%80%85%E7%9A%84flask%E9%A1%B9%E7%9B%AE/"/>
<url>/2018/06/18/%E5%88%9D%E5%AD%A6%E8%80%85%E7%9A%84flask%E9%A1%B9%E7%9B%AE/</url>
<content type="html"><![CDATA[<p><原创>:学了一周的flask项目,在这里把我自己的做的项目分享给大家.实现了如下的功能.</p><h4 id="项目内容"><a href="#项目内容" class="headerlink" title="项目内容:"></a>项目内容:</h4><h5 id="1-班级管理"><a href="#1-班级管理" class="headerlink" title="1,班级管理"></a>1,班级管理</h5><ol><li>班级列表</li><li>班级增加</li><li>班级修改</li><li>查看班级中的学生</li></ol><h5 id="2-学生管理的增删改查"><a href="#2-学生管理的增删改查" class="headerlink" title="2,学生管理的增删改查"></a>2,学生管理的增删改查</h5><ol><li>学生列表</li><li>学生添加</li><li>学生修改</li></ol><h5 id="3-权限的增加"><a href="#3-权限的增加" class="headerlink" title="3,权限的增加"></a>3,权限的增加</h5><ol><li>角色的增加</li><li>角色列表<ol><li>查看用户权限</li><li>添加用户权限</li><li>减少用户权限</li></ol></li><li>权限列表</li><li>添加权限</li></ol><h5 id="4-用户管理"><a href="#4-用户管理" class="headerlink" title="4,用户管理"></a>4,用户管理</h5><ol><li>用户列表</li><li>用户添加</li><li>用户角色分配</li></ol><h5 id="5-系统管理"><a href="#5-系统管理" class="headerlink" title="5,系统管理"></a>5,系统管理</h5><ol><li>修改密码</li><li>退出</li></ol><ol><li>用户登录注册<ol><li>用户注册</li><li>用户登录验证</li></ol></li></ol><h5 id="6-页面分页"><a href="#6-页面分页" class="headerlink" title="6,页面分页"></a>6,页面分页</h5><hr><h5 id="详细的项目代码"><a href="#详细的项目代码" class="headerlink" title="详细的项目代码"></a>详细的项目代码</h5><p>在这里我就省略建立项目的流程直接来开始我们的项目…..</p><p>建立项目的流程不会可以自行百度flask官网</p><h5 id="1-首先介绍一下项目的文件构成-如下图"><a href="#1-首先介绍一下项目的文件构成-如下图" class="headerlink" title="1.首先介绍一下项目的文件构成,如下图"></a>1.首先介绍一下项目的文件构成,如下图</h5><p><img src="/2018/06/18/初学者的flask项目/1.png" alt="1"></p><h5 id="2-启动文件的配置"><a href="#2-启动文件的配置" class="headerlink" title="2, 启动文件的配置"></a>2, 启动文件的配置</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#manange.py文件的内容</span></span><br><span class="line"><span class="keyword">from</span> flask_script <span class="keyword">import</span> Manager</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> utils.functions <span class="keyword">import</span> create_app</span><br><span class="line"></span><br><span class="line">app = create_app()</span><br><span class="line"></span><br><span class="line">manage = Manager(app=app)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> manage.run()</span><br></pre></td></tr></table></figure><h5 id="3-重要的配置"><a href="#3-重要的配置" class="headerlink" title="3,重要的配置"></a>3,重要的配置</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#utils中funtions.py文件中的类容,重要的配置</span></span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> redis</span><br><span class="line"><span class="keyword">from</span> flask <span class="keyword">import</span> Flask</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> App.user_views <span class="keyword">import</span> user_blueprint</span><br><span class="line"><span class="keyword">from</span> App.models <span class="keyword">import</span> db</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">create_app</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="comment"># 定义系统路径的变量</span></span><br><span class="line"> BASE_DIR = os.path.dirname(os.path.dirname(__file__))</span><br><span class="line"> <span class="comment"># 定义静态文件的路径</span></span><br><span class="line"> static_dir = os.path.join(BASE_DIR, <span class="string">'static'</span>)</span><br><span class="line"> <span class="comment"># 定义模板文件的路径</span></span><br><span class="line"> templates_dir = os.path.join(BASE_DIR, <span class="string">'templates'</span>)</span><br><span class="line"> <span class="comment"># 初始化app 和manage.py文件关联</span></span><br><span class="line"> app = Flask(__name__,</span><br><span class="line"> static_folder=static_dir,</span><br><span class="line"> template_folder=templates_dir)</span><br><span class="line"> <span class="comment"># 注册蓝图</span></span><br><span class="line"> app.register_blueprint(blueprint=user_blueprint, url_prefix=<span class="string">'/user'</span>)</span><br><span class="line"> <span class="comment"># 配置mysql数据库</span></span><br><span class="line"> app.config[<span class="string">'SQLALCHEMY_DATABASE_URI'</span>] = <span class="string">'mysql+pymysql://root:[email protected]:3306/Htai'</span></span><br><span class="line"> app.config[<span class="string">'SQLALCHEMY_TRACK_MODIFICATIONS'</span>] = <span class="keyword">False</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># 设置session密钥</span></span><br><span class="line"> app.config[<span class="string">'SECRET_KEY'</span>] = <span class="string">'secret_key'</span></span><br><span class="line"> <span class="comment"># 设置连接的redis数据库 默认连接到本地6379</span></span><br><span class="line"> app.config[<span class="string">'SESSION_TYPE'</span>] = <span class="string">'redis'</span></span><br><span class="line"> <span class="comment"># 设置远程</span></span><br><span class="line"> app.config[<span class="string">'SESSION_REDIS'</span>] = redis.Redis(host=<span class="string">'127.0.0.1'</span>, port=<span class="number">6379</span>)</span><br><span class="line"> <span class="comment"># 初始化db</span></span><br><span class="line"> db.init_app(app=app)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> app</span><br></pre></td></tr></table></figure><h5 id="4-登录验证的装饰器"><a href="#4-登录验证的装饰器" class="headerlink" title="4,登录验证的装饰器"></a>4,登录验证的装饰器</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">from</span> flask <span class="keyword">import</span> url_for,redirect,session</span><br><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> wraps</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">is_login</span><span class="params">(func)</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 定义登录注册验证的装饰器</span></span><br><span class="line"><span class="string"> :return: check_login</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"><span class="meta"> @wraps(func)</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">check_login</span><span class="params">(*args,**kwargs)</span>:</span></span><br><span class="line"> user_id = session.get(<span class="string">'user_id'</span>)</span><br><span class="line"> <span class="keyword">if</span> user_id:</span><br><span class="line"> <span class="keyword">return</span> func(*args,**kwargs)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'user.login'</span>))</span><br><span class="line"> <span class="keyword">return</span> check_login</span><br></pre></td></tr></table></figure><h5 id="5-建立项目的模型"><a href="#5-建立项目的模型" class="headerlink" title="5,建立项目的模型"></a>5,建立项目的模型</h5><p>建立模型我们要对我们需求进行详细ORM(对象关系映射)的分析</p><p>student <————> grade 一对多</p><p>user <————> role 一对多</p><p>role <————> permission 多对多</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> datetime <span class="keyword">import</span> datetime</span><br><span class="line"><span class="comment"># 导入SQLAlchemy模块</span></span><br><span class="line"><span class="keyword">from</span> flask_sqlalchemy <span class="keyword">import</span> SQLAlchemy</span><br><span class="line"><span class="comment"># 初始化db</span></span><br><span class="line">db = SQLAlchemy()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Grade</span><span class="params">(db.Model)</span>:</span></span><br><span class="line"> <span class="string">"""班级模型"""</span></span><br><span class="line"> g_id = db.Column(db.Integer, autoincrement=<span class="keyword">True</span>, primary_key=<span class="keyword">True</span>)</span><br><span class="line"> g_name = db.Column(db.String(<span class="number">20</span>), unique=<span class="keyword">True</span>)</span><br><span class="line"> g_create_time = db.Column(db.DateTime, default=datetime.now)</span><br><span class="line"> <span class="comment"># 设置与班级 一对多的关联关系</span></span><br><span class="line"> students = db.relationship(<span class="string">'Student'</span>,backref= <span class="string">'grade'</span>)</span><br><span class="line"> <span class="comment"># 自定义表名</span></span><br><span class="line"> __tablename__ = <span class="string">'grade'</span></span><br><span class="line"> <span class="comment"># 初始化字段 方便以后视图使用</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, name)</span>:</span></span><br><span class="line"> self.g_name = name</span><br><span class="line"> <span class="comment"># 定义保存数据的方法 后面视图好使用</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">save</span><span class="params">(self)</span>:</span></span><br><span class="line"> db.session.add(self)</span><br><span class="line"> db.session.commit()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Student</span><span class="params">(db.Model)</span>:</span></span><br><span class="line"> <span class="string">"""学生模型"""</span></span><br><span class="line"> s_id = db.Column(db.Integer, autoincrement=<span class="keyword">True</span>, primary_key=<span class="keyword">True</span>)</span><br><span class="line"> s_name = db.Column(db.String(<span class="number">16</span>), unique=<span class="keyword">True</span>)</span><br><span class="line"> s_sex = db.Column(db.Integer)</span><br><span class="line"> <span class="comment"># 设置与班级 一对多的关联关系</span></span><br><span class="line"> grade_id = db.Column(db.Integer, db.ForeignKey(<span class="string">'grade.g_id'</span>), nullable=<span class="keyword">True</span>)</span><br><span class="line"></span><br><span class="line"> __tablename__ = <span class="string">'student'</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, s_name, s_sex,grade_id)</span>:</span></span><br><span class="line"> self.s_name = s_name</span><br><span class="line"> self.s_sex = s_sex</span><br><span class="line"> self.grade_id =grade_id</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">save</span><span class="params">(self)</span>:</span></span><br><span class="line"> db.session.add(self)</span><br><span class="line"> db.session.commit()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">User</span><span class="params">(db.Model)</span>:</span></span><br><span class="line"> <span class="string">"""用户模型"""</span></span><br><span class="line"> u_id = db.Column(db.Integer, autoincrement=<span class="keyword">True</span>, primary_key=<span class="keyword">True</span>)</span><br><span class="line"> username = db.Column(db.String(<span class="number">16</span>), unique=<span class="keyword">True</span>)</span><br><span class="line"> password = db.Column(db.String(<span class="number">250</span>))</span><br><span class="line"> u_create_time = db.Column(db.DateTime, default=datetime.now)</span><br><span class="line"> <span class="comment"># 用户和角色的一对多的关联关系</span></span><br><span class="line"> role_id = db.Column(db.Integer, db.ForeignKey(<span class="string">'role.r_id'</span>))</span><br><span class="line"></span><br><span class="line"> __tablename__ = <span class="string">'user'</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self,username,password)</span>:</span></span><br><span class="line"> self.username = username</span><br><span class="line"> self.password = password</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">save</span><span class="params">(self)</span>:</span></span><br><span class="line"> db.session.add(self)</span><br><span class="line"> db.session.commit()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 角色和权限的(多对多的)关联表</span></span><br><span class="line"><span class="comment"># r_p为关联表的表名</span></span><br><span class="line">r_p = db.Table(<span class="string">'r_p'</span>,</span><br><span class="line"> db.Column(<span class="string">'role_id'</span>, db.Integer, db.ForeignKey(<span class="string">'role.r_id'</span>), primary_key=<span class="keyword">True</span>),</span><br><span class="line"> db.Column(<span class="string">'permission_id'</span>, db.Integer, db.ForeignKey(<span class="string">'permission.p_id'</span>), primary_key=<span class="keyword">True</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Role</span><span class="params">(db.Model)</span>:</span></span><br><span class="line"> r_id = db.Column(db.Integer, autoincrement=<span class="keyword">True</span>, primary_key=<span class="keyword">True</span>)</span><br><span class="line"> r_name = db.Column(db.String(<span class="number">10</span>))</span><br><span class="line"> <span class="comment"># 用户和角色的一对多的关联关系</span></span><br><span class="line"> users = db.relationship(<span class="string">'User'</span>, backref=<span class="string">'role'</span>)</span><br><span class="line"></span><br><span class="line"> __tablename__ = <span class="string">'role'</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self,r_name)</span>:</span></span><br><span class="line"> self.r_name = r_name</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">save</span><span class="params">(self)</span>:</span></span><br><span class="line"> db.session.add(self)</span><br><span class="line"> db.session.commit()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Permission</span><span class="params">(db.Model)</span>:</span></span><br><span class="line"> p_id = db.Column(db.Integer, autoincrement=<span class="keyword">True</span>, primary_key=<span class="keyword">True</span>)</span><br><span class="line"> p_name = db.Column(db.String(<span class="number">16</span>), unique=<span class="keyword">True</span>)</span><br><span class="line"> p_er = db.Column(db.String(<span class="number">16</span>), unique=<span class="keyword">True</span>)</span><br><span class="line"> <span class="comment"># 角色和权限的多对多的关系</span></span><br><span class="line"> roles = db.relationship(<span class="string">'Role'</span>, secondary=r_p, backref=db.backref(<span class="string">'permission'</span>, lazy=<span class="keyword">True</span>))</span><br><span class="line"></span><br><span class="line"> __tablename__ = <span class="string">'permission'</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self,p_name,p_er)</span>:</span></span><br><span class="line"> self.p_name = p_name</span><br><span class="line"> self.p_er = p_er</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">save</span><span class="params">(self)</span>:</span></span><br><span class="line"> db.session.add(self)</span><br><span class="line"> db.session.commit()</span><br></pre></td></tr></table></figure><h5 id="6-在后台数据库中创建数据库为Htai的数据库"><a href="#6-在后台数据库中创建数据库为Htai的数据库" class="headerlink" title="6,在后台数据库中创建数据库为Htai的数据库"></a>6,在后台数据库中创建数据库为Htai的数据库</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">建库sql语句:</span><br><span class="line">create database Htai default charset utf8;</span><br></pre></td></tr></table></figure><h5 id="7-开始写我们的视图中的代码"><a href="#7-开始写我们的视图中的代码" class="headerlink" title="7,开始写我们的视图中的代码"></a>7,开始写我们的视图中的代码</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@user_blueprint.route('/create_db/')</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">create_db</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 创建数据</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> db.create_all()</span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="meta">@user_blueprint.route('/drop_db/')</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">drop_db</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 删除数据库</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> db.drop_all()</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'删除成功'</span></span><br></pre></td></tr></table></figure><p>执行这个地址就能把我们创建好的模型在数据库中创建好对应的表以供我们后续的功能的使用.</p><h5 id="8-我们来实现第一个功能查看我们的首页"><a href="#8-我们来实现第一个功能查看我们的首页" class="headerlink" title="8,我们来实现第一个功能查看我们的首页"></a>8,我们来实现第一个功能查看我们的首页</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@user_blueprint.route('/home/', methods=['GET'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">home</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 首页</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'index.html'</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/head/', methods=['GET'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">head</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 页头</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> user = session.get(<span class="string">'username'</span>)</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'head.html'</span>, user=user)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/left/', methods=['GET'])</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">left</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""左侧栏"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> <span class="comment"># 获取登录的用户信息</span></span><br><span class="line"> user = session.get(<span class="string">'username'</span>)</span><br><span class="line"> <span class="comment"># 获取用户的权限</span></span><br><span class="line"> permissions = User.query.filter_by(username=user).first().role.permission</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'left.html'</span>, permissions=permissions)</span><br></pre></td></tr></table></figure><p>这样我们就能看见我们初始项目的样子了.如下图</p><p><img src="/2018/06/18/初学者的flask项目/home.png" alt="om"></p><p>下面我们就一点一点的实现上面我们所说的功能,代码如下重要的内容我写好了注释</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br><span class="line">441</span><br><span class="line">442</span><br><span class="line">443</span><br><span class="line">444</span><br><span class="line">445</span><br><span class="line">446</span><br><span class="line">447</span><br><span class="line">448</span><br><span class="line">449</span><br><span class="line">450</span><br><span class="line">451</span><br><span class="line">452</span><br><span class="line">453</span><br><span class="line">454</span><br><span class="line">455</span><br><span class="line">456</span><br><span class="line">457</span><br><span class="line">458</span><br><span class="line">459</span><br><span class="line">460</span><br><span class="line">461</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@user_blueprint.route('/register/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">register</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 用户注册页面</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'register.html'</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"> <span class="comment"># 获取用户填写的信息</span></span><br><span class="line"> username = request.form.get(<span class="string">'username'</span>)</span><br><span class="line"> pwd1 = request.form.get(<span class="string">'pwd1'</span>)</span><br><span class="line"> pwd2 = request.form.get(<span class="string">'pwd2'</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 定义个变量来控制过滤用户填写的信息</span></span><br><span class="line"> flag = <span class="keyword">True</span></span><br><span class="line"> <span class="comment"># 判断用户是否信息都填写了.(all()函数可以判断用户填写的字段是否有空)</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> all([username, pwd1, pwd2]):</span><br><span class="line"> msg, flag = <span class="string">'* 请填写完整信息'</span>, <span class="keyword">False</span></span><br><span class="line"> <span class="comment"># 判断用户名是长度是否大于16</span></span><br><span class="line"> <span class="keyword">if</span> len(username) > <span class="number">16</span>:</span><br><span class="line"> msg, flag = <span class="string">'* 用户名太长'</span>, <span class="keyword">False</span></span><br><span class="line"> <span class="comment"># 判断两次填写的密码是否一致</span></span><br><span class="line"> <span class="keyword">if</span> pwd1 != pwd2:</span><br><span class="line"> msg, flag = <span class="string">'* 两次密码不一致'</span>, <span class="keyword">False</span></span><br><span class="line"> <span class="comment"># 如果上面的检查有任意一项没有通过就返回注册页面,并提示响应的信息</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> flag:</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'register.html'</span>, msg=msg)</span><br><span class="line"> <span class="comment"># 核对输入的用户是否已经被注册了</span></span><br><span class="line"> u = User.query.filter(User.username == username).first()</span><br><span class="line"> <span class="comment"># 判断用户名是否已经存在</span></span><br><span class="line"> <span class="keyword">if</span> u:</span><br><span class="line"> msg = <span class="string">'用户名已经存在'</span></span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'register.html'</span>, msg=msg)</span><br><span class="line"> <span class="comment"># 上面的验证全部通过后就开始创建新用户</span></span><br><span class="line"> user = User(username=username, password=pwd1)</span><br><span class="line"> <span class="comment"># 保存注册的用户</span></span><br><span class="line"> user.save()</span><br><span class="line"> <span class="comment"># 跳转到登录页面</span></span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'user.login'</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/login/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">login</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 登录</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'login.html'</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"> username = request.form.get(<span class="string">'username'</span>)</span><br><span class="line"> password = request.form.get(<span class="string">'password'</span>)</span><br><span class="line"> <span class="comment"># 判断用户名和密码是否填写</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> all([username, password]):</span><br><span class="line"> msg = <span class="string">'* 请填写好完整的信息'</span></span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'login.html'</span>, msg=msg)</span><br><span class="line"> <span class="comment"># 核对用户名和密码是否一致</span></span><br><span class="line"> user = User.query.filter_by(username=username, password=password).first()</span><br><span class="line"> <span class="comment"># 如果用户名和密码一致</span></span><br><span class="line"> <span class="keyword">if</span> user:</span><br><span class="line"> <span class="comment"># 向session中写入相应的数据</span></span><br><span class="line"> session[<span class="string">'user_id'</span>] = user.u_id</span><br><span class="line"> session[<span class="string">'username'</span>] = user.username</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'index.html'</span>)</span><br><span class="line"> <span class="comment"># 如果用户名和密码不一致返回登录页面,并给提示信息</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> msg = <span class="string">'* 用户名或者密码不一致'</span></span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'login.html'</span>, msg=msg)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/logout/', methods=['GET'])</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">logout</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 退出登录</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> <span class="comment"># 清空session</span></span><br><span class="line"> session.clear()</span><br><span class="line"> <span class="comment"># 跳转到登录页面</span></span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'user.login'</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/grade/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">grade_list</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 显示班级列表</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> <span class="comment"># 查询第几页的数据</span></span><br><span class="line"> page = int(request.args.get(<span class="string">'page'</span>,<span class="number">1</span>))</span><br><span class="line"> <span class="comment"># 每页的条数是多少,默认为5条</span></span><br><span class="line"> page_num = int(request.args.get(<span class="string">'page_num'</span>,<span class="number">5</span>))</span><br><span class="line"> <span class="comment"># 查询当前第几个的多少条数据</span></span><br><span class="line"> paginate = Grade.query.order_by(<span class="string">'g_id'</span>).paginate(page,page_num)</span><br><span class="line"> <span class="comment"># 获取某也的具体数据</span></span><br><span class="line"> grades = paginate.items</span><br><span class="line"> <span class="comment"># 返回获取到的班级信息给前端页面</span></span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'grade.html'</span>, grades=grades,paginate=paginate)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/addgrade/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_grade</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""添加班级"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'addgrade.html'</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"> g_name = request.form.get(<span class="string">'g_name'</span>)</span><br><span class="line"> g = Grade.query.filter(Grade.g_name == g_name).first()</span><br><span class="line"> <span class="comment"># 判断要添加的信息数据库中是否存在(因为班级名称不能重复)</span></span><br><span class="line"> <span class="keyword">if</span> g:</span><br><span class="line"> msg = <span class="string">'*班级名称不能重复,请核对好在来添加'</span></span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'addgrade.html'</span>, msg=msg)</span><br><span class="line"> <span class="comment"># 创建班级</span></span><br><span class="line"> grade = Grade(g_name)</span><br><span class="line"> <span class="comment"># 保存班级信息</span></span><br><span class="line"> grade.save()</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'user.grade_list'</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/edit_grade/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">edit_grade</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""编辑班级"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> g_id = request.args.get(<span class="string">'g_id'</span>)</span><br><span class="line"> g_name = Grade.query.filter(Grade.g_id == g_id).first().g_name</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'addgrade.html'</span>, g_name=g_name, g_id=g_id)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"> <span class="comment"># 获取需要修改的班级id</span></span><br><span class="line"> g_id = request.form.get(<span class="string">'g_id'</span>)</span><br><span class="line"> g_name = request.form.get(<span class="string">'g_name'</span>)</span><br><span class="line"> <span class="comment"># 通过获取到的班级id</span></span><br><span class="line"> grade = Grade.query.filter(Grade.g_id == g_id).first()</span><br><span class="line"> <span class="comment"># 重新给班级赋值</span></span><br><span class="line"> grade.g_name = g_name</span><br><span class="line"> grade.save()</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'user.grade_list'</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/grade_student/', methods=['GET'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">grade_students_list</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""班级中学习的信息列表"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> g_id = request.args.get(<span class="string">'g_id'</span>)</span><br><span class="line"> stus = Student.query.filter(Student.grade_id == g_id).all()</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'student.html'</span>, stus=stus)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/student/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">student_list</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""学生信息列表"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> page = int(request.args.get(<span class="string">'page'</span>,<span class="number">1</span>))</span><br><span class="line"> page_num = int(request.args.get(<span class="string">'page_num'</span>,<span class="number">5</span>))</span><br><span class="line"> paginate = Student.query.order_by(<span class="string">'s_id'</span>).paginate(page,page_num)</span><br><span class="line"> stus = paginate.items</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'student.html'</span>, stus=stus,paginate=paginate)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/addstu/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_stu</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""添加学生"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> grades = Grade.query.all()</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'addstu.html'</span>, grades=grades)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"> s_name = request.form.get(<span class="string">'s_name'</span>)</span><br><span class="line"> s_sex = request.form.get(<span class="string">'s_sex'</span>)</span><br><span class="line"> grade_id = request.form.get(<span class="string">'g_name'</span>)</span><br><span class="line"></span><br><span class="line"> stu = Student.query.filter(Student.s_name == s_name).first()</span><br><span class="line"> <span class="keyword">if</span> stu:</span><br><span class="line"> msg = <span class="string">'* 学习姓名不能重复'</span></span><br><span class="line"> grades = Grade.query.all()</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'addstu.html'</span>, grades=grades, msg=msg)</span><br><span class="line"> stu = Student(s_name=s_name, s_sex=s_sex, grade_id=grade_id)</span><br><span class="line"> stu.save()</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'user.student_list'</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/roles/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">roles_list</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""角色信息列表"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> roles = Role.query.all()</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'roles.html'</span>, roles=roles)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/addroles/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_roles</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""添加角色"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'addroles.html'</span>)</span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"></span><br><span class="line"> r_name = request.form.get(<span class="string">'r_name'</span>)</span><br><span class="line"> role = Role(r_name=r_name)</span><br><span class="line"> role.save()</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'user.roles_list'</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/userperlist/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">user_per_list</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""用户权限列表"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> r_id = request.args.get(<span class="string">'r_id'</span>)</span><br><span class="line"> pers = Role.query.filter(Role.r_id == r_id).first().permission</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'user_per_list.html'</span>, pers=pers)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"> r_id = request.args.get(<span class="string">'r_id'</span>)</span><br><span class="line"> p_id = request.form.get(<span class="string">'p_id'</span>)</span><br><span class="line"> <span class="comment"># 获取到角色对象</span></span><br><span class="line"> role = Role.query.get(r_id)</span><br><span class="line"> <span class="comment"># 获取到权限对象</span></span><br><span class="line"> per = Permission.query.get(p_id)</span><br><span class="line"> <span class="comment"># 解除角色和权限的对应关系</span></span><br><span class="line"> per.roles.remove(role)</span><br><span class="line"> <span class="comment"># 保存解除的关联的信息</span></span><br><span class="line"> db.session.commit()</span><br><span class="line"> pers = Role.query.filter(Role.r_id == r_id).first().permission</span><br><span class="line"> <span class="comment"># 返回到用户权限列表</span></span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'user_per_list.html'</span>, pers=pers, r_id=r_id)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/adduserper/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_user_per</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""添加用户权限"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> permissions = Permission.query.all()</span><br><span class="line"> r_id = request.args.get(<span class="string">'r_id'</span>)</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'add_user_per.html'</span>, permissions=permissions, r_id=r_id)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"> r_id = request.form.get(<span class="string">'r_id'</span>)</span><br><span class="line"> p_id = request.form.get(<span class="string">'p_id'</span>)</span><br><span class="line"> <span class="comment"># 获取角色对象</span></span><br><span class="line"> role = Role.query.get(r_id)</span><br><span class="line"> <span class="comment"># 获取权限对象</span></span><br><span class="line"> per = Permission.query.get(p_id)</span><br><span class="line"> <span class="comment"># 添加对应的角色和权限的对应关系</span></span><br><span class="line"> per.roles.append(role)</span><br><span class="line"> <span class="comment"># 添加</span></span><br><span class="line"> db.session.add(per)</span><br><span class="line"> <span class="comment"># 保存信息</span></span><br><span class="line"> db.session.commit()</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'user.roles_list'</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/subuserper/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">sub_user_per</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""减少用户权限"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> r_id = request.args.get(<span class="string">'r_id'</span>)</span><br><span class="line"> pers = Role.query.filter(Role.r_id == r_id).first().permission</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'user_per_list.html'</span>, pers=pers, r_id=r_id)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"> r_id = request.args.get(<span class="string">'r_id'</span>)</span><br><span class="line"> p_id = request.form.get(<span class="string">'p_id'</span>)</span><br><span class="line"> role = Role.query.get(r_id)</span><br><span class="line"> per = Permission.query.get(p_id)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 解除角色和权限的对应关系</span></span><br><span class="line"> per.roles.remove(role)</span><br><span class="line"> db.session.commit()</span><br><span class="line"></span><br><span class="line"> pers = Role.query.filter(Role.r_id == r_id).first().permission</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'user_per_list.html'</span>, pers=pers, r_id=r_id)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/permissions/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">permission_list</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""权限列表"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> permissions = Permission.query.all()</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'permissions.html'</span>, permissions=permissions)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/addpermission/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_permission</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""添加权限"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> pers = Permission.query.all()</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'addpermission.html'</span>, pers=pers)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"> p_name = request.form.get(<span class="string">'p_name'</span>)</span><br><span class="line"> p_er = request.form.get(<span class="string">'p_er'</span>)</span><br><span class="line"></span><br><span class="line"> p_name_test_repeat = Permission.query.filter(Permission.p_name == p_name).first()</span><br><span class="line"> <span class="keyword">if</span> p_name_test_repeat:</span><br><span class="line"> msg = <span class="string">'*权限名称重复'</span></span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'addpermission.html'</span>, msg=msg)</span><br><span class="line"></span><br><span class="line"> p_er_test_repeat = Permission.query.filter(Permission.p_er == p_er).first()</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> p_er_test_repeat:</span><br><span class="line"> msg1 = <span class="string">'*权限简写名重复'</span></span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'addpermission.html'</span>, msg1=msg1)</span><br><span class="line"></span><br><span class="line"> permission = Permission(p_name=p_name, p_er=p_er)</span><br><span class="line"> permission.save()</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'user.permission_list'</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/eidtorpermission/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">eidtor_permission</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""编辑权限"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> p_id = request.args.get(<span class="string">'p_id'</span>)</span><br><span class="line"> pers = Permission.query.filter(Permission.p_id == p_id).first()</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'addpermission.html'</span>, pers=pers, p_id=p_id)</span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"> p_id = request.form.get(<span class="string">'p_id'</span>)</span><br><span class="line"> p_name = request.form.get(<span class="string">'p_name'</span>)</span><br><span class="line"> p_er = request.form.get(<span class="string">'p_er'</span>)</span><br><span class="line"></span><br><span class="line"> p_name_test_repeat = Permission.query.filter(Permission.p_name == p_name).first()</span><br><span class="line"> <span class="keyword">if</span> p_name_test_repeat:</span><br><span class="line"> msg = <span class="string">'*权限名称重复'</span></span><br><span class="line"> pers = Permission.query.all()</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'addpermission.html'</span>, msg=msg, pers=pers)</span><br><span class="line"></span><br><span class="line"> p_er_test_repeat = Permission.query.filter(Permission.p_er == p_er).first()</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> p_er_test_repeat:</span><br><span class="line"> msg1 = <span class="string">'*权限简写名重复'</span></span><br><span class="line"> pers = Permission.query.all()</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'addpermission.html'</span>, msg1=msg1, pers=pers)</span><br><span class="line"></span><br><span class="line"> per = Permission.query.filter(Permission.p_id == p_id).first()</span><br><span class="line"> per.p_name = p_name</span><br><span class="line"> per.p_er = p_er</span><br><span class="line"> db.session.commit()</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'user.permission_list'</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/userlist/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">user_list</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""用户信息列表"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> page = int(request.args.get(<span class="string">'page'</span>,<span class="number">1</span>))</span><br><span class="line"> page_num = int(request.args.get(<span class="string">'page_num'</span>,<span class="number">5</span>))</span><br><span class="line"> paginate = User.query.order_by(<span class="string">'u_id'</span>).paginate(page,page_num)</span><br><span class="line"> users = paginate.items</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'users.html'</span>, users=users,paginate=paginate)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/adduser/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add_user</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""添加用户信息"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'adduser.html'</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"> username = request.form.get(<span class="string">'username'</span>)</span><br><span class="line"> password1 = request.form.get(<span class="string">'password1'</span>)</span><br><span class="line"> password2 = request.form.get(<span class="string">'password2'</span>)</span><br><span class="line"></span><br><span class="line"> flag = <span class="keyword">True</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> all([username, password1, password2]):</span><br><span class="line"> msg, flag = <span class="string">'请填写完整信息'</span>, <span class="keyword">False</span></span><br><span class="line"> <span class="keyword">if</span> len(username) > <span class="number">16</span>:</span><br><span class="line"> msg, flag = <span class="string">'用户名太长'</span>, <span class="keyword">False</span></span><br><span class="line"> <span class="keyword">if</span> password1 != password2:</span><br><span class="line"> msg, flag = <span class="string">'两次密码不一致'</span>, <span class="keyword">False</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> flag:</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'adduser.html'</span>, msg=msg)</span><br><span class="line"> user = User(username=username, password=password1)</span><br><span class="line"> user.save()</span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'user.user_list'</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/assignrole/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">assign_user_role</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""分配用户权限"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> u_id = request.args.get(<span class="string">'u_id'</span>)</span><br><span class="line"> roles = Role.query.all()</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'assign_user_role.html'</span>, roles=roles, u_id=u_id)</span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"> r_id = request.form.get(<span class="string">'r_id'</span>)</span><br><span class="line"> u_id = request.form.get(<span class="string">'u_id'</span>)</span><br><span class="line"> user = User.query.filter_by(u_id=u_id).first()</span><br><span class="line"> user.role_id = r_id</span><br><span class="line"> db.session.commit()</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'user.user_list'</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/changepwd/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">change_password</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""修改用户密码"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> username = session.get(<span class="string">'username'</span>)</span><br><span class="line"> user = User.query.filter_by(username=username).first()</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'changepwd.html'</span>, user=user)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"> username = session.get(<span class="string">'username'</span>)</span><br><span class="line"> pwd1 = request.form.get(<span class="string">'pwd1'</span>)</span><br><span class="line"> pwd2 = request.form.get(<span class="string">'pwd2'</span>)</span><br><span class="line"> pwd3 = request.form.get(<span class="string">'pwd3'</span>)</span><br><span class="line"></span><br><span class="line"> pwd = User.query.filter(User.password == pwd1, User.username == username).first()</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> pwd:</span><br><span class="line"> msg = <span class="string">'请输入正确的旧密码'</span></span><br><span class="line"> username = session.get(<span class="string">'username'</span>)</span><br><span class="line"> user = User.query.filter_by(username=username).first()</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'changepwd.html'</span>, msg=msg, user=user)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> all([pwd2, pwd3]):</span><br><span class="line"> msg = <span class="string">'密码不能为空'</span></span><br><span class="line"> username = session.get(<span class="string">'username'</span>)</span><br><span class="line"> user = User.query.filter_by(username=username).first()</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'changepwd.html'</span>, msg=msg, user=user)</span><br><span class="line"> <span class="keyword">if</span> pwd2 != pwd3:</span><br><span class="line"> msg = <span class="string">'两次密码不一致,请重新输入'</span></span><br><span class="line"> username = session.get(<span class="string">'username'</span>)</span><br><span class="line"> user = User.query.filter_by(username=username).first()</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'changepwd.html'</span>, msg=msg, user=user)</span><br><span class="line"> pwd.password = pwd2</span><br><span class="line"> db.session.commit()</span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'user.change_pass_sucess'</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@user_blueprint.route('/changepwdsu/', methods=['GET'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">change_pass_sucess</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""修改密码成功后"""</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'changepwdsu.html'</span>)</span><br></pre></td></tr></table></figure><p>到这里我们的项目的功能就完全实现了.</p><p>比较重要的地方有分页效果. 在我们数据量大了如何去处理分页数据</p><h6 id="后端代码"><a href="#后端代码" class="headerlink" title="后端代码"></a>后端代码</h6><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@user_blueprint.route('/grade/', methods=['GET', 'POST'])</span></span><br><span class="line"><span class="meta">@is_login</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">grade_list</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 显示班级列表</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> <span class="comment"># 查询第几页的数据</span></span><br><span class="line"> page = int(request.args.get(<span class="string">'page'</span>,<span class="number">1</span>))</span><br><span class="line"> <span class="comment"># 每页的条数是多少,默认为5条</span></span><br><span class="line"> page_num = int(request.args.get(<span class="string">'page_num'</span>,<span class="number">5</span>))</span><br><span class="line"> <span class="comment"># 查询当前第几个的多少条数据</span></span><br><span class="line"> paginate = Grade.query.order_by(<span class="string">'g_id'</span>).paginate(page,page_num)</span><br><span class="line"> <span class="comment"># 获取某也的具体数据</span></span><br><span class="line"> grades = paginate.items</span><br><span class="line"> <span class="comment"># 返回获取到的班级信息给前端页面</span></span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'grade.html'</span>, grades=grades,paginate=paginate)</span><br></pre></td></tr></table></figure><h6 id="前端代码"><a href="#前端代码" class="headerlink" title="前端代码"></a>前端代码</h6><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"MainForm"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"form_boxA"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">h2</span>></span>班级信息列表<span class="tag"></<span class="name">h2</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">table</span> <span class="attr">cellpadding</span>=<span class="string">"0"</span> <span class="attr">cellspacing</span>=<span class="string">"0"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">tr</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">th</span>></span>序号<span class="tag"></<span class="name">th</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">th</span>></span>班级名称<span class="tag"></<span class="name">th</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">th</span>></span>创建时间<span class="tag"></<span class="name">th</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">th</span>></span>操作<span class="tag"></<span class="name">th</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">tr</span>></span></span><br><span class="line"> {% for grade in grades %}</span><br><span class="line"> <span class="tag"><<span class="name">tr</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">td</span>></span>{{grade.g_id }}<span class="tag"></<span class="name">td</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">td</span>></span>{{grade.g_name }}<span class="tag"></<span class="name">td</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">td</span>></span>{{grade.g_create_time}}<span class="tag"></<span class="name">td</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">td</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/user/edit_grade/?g_id={{grade.g_id }}"</span>></span>编辑<span class="tag"></<span class="name">a</span>></span> |</span><br><span class="line"> <span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"#"</span>></span>删除<span class="tag"></<span class="name">a</span>></span> |</span><br><span class="line"> <span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/user/grade_student/?g_id={{grade.g_id}}"</span>></span>查看学生<span class="tag"></<span class="name">a</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">td</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">tr</span>></span></span><br><span class="line"> {% endfor %}</span><br><span class="line"> <span class="tag"></<span class="name">table</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">p</span> <span class="attr">class</span>=<span class="string">"msg"</span>></span>共找到{{paginate.total}}条匹配记录<span class="tag"></<span class="name">p</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="name">ul</span> <span class="attr">id</span>=<span class="string">"PageNum"</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">li</span>></span><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/user/grade/?page=1"</span>></span>首页<span class="tag"></<span class="name">a</span>></span><span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> {% if paginate.has_prev %}</span><br><span class="line"> <span class="tag"><<span class="name">li</span>></span><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/user/grade/?page={{ paginate.prev_num }}"</span>></span>上一页<span class="tag"></<span class="name">a</span>></span><span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> {% endif %}</span><br><span class="line"></span><br><span class="line"> {% for p in paginate.iter_pages() %}</span><br><span class="line"> <span class="tag"><<span class="name">li</span>></span></span><br><span class="line"> {% if p %}</span><br><span class="line"> {% if p != paginate.page %}</span><br><span class="line"> <span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/user/grade/?page={{ p }}"</span>></span>{{ p }}<span class="tag"></<span class="name">a</span>></span></span><br><span class="line"> {% else %}</span><br><span class="line"> <span class="tag"><<span class="name">span</span>></span> {{ p }} <span class="tag"></<span class="name">span</span>></span></span><br><span class="line"> {% endif %}</span><br><span class="line"> {% else %}</span><br><span class="line"> <span class="tag"><<span class="name">span</span>></span>...<span class="tag"></<span class="name">span</span>></span></span><br><span class="line"> {% endif %}</span><br><span class="line"> <span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> {% endfor %}</span><br><span class="line"></span><br><span class="line"> {% if paginate.has_next %}</span><br><span class="line"> <span class="tag"><<span class="name">li</span>></span><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/user/grade/?page={{ paginate.next_num }}"</span>></span>下一页<span class="tag"></<span class="name">a</span>></span><span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> {% endif %}</span><br><span class="line"> <span class="tag"><<span class="name">li</span>></span><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/user/grade/?page={{ paginate.pages }}"</span>></span>尾页<span class="tag"></<span class="name">a</span>></span><span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">span</span>></span>| 共{{paginate.pages}}页 | 当前第{{paginate.page}}页<span class="tag"></<span class="name">span</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">ul</span>></span></span><br></pre></td></tr></table></figure><p>项目所有的页面有:</p><p><img src="/2018/06/18/初学者的flask项目/qdym.png" alt="dy"></p><p>需要练习的我都把所有的代码放git上面了.可以去下载哦!!希望对大家学习有帮助.</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">下载地址:</span><br><span class="line">https://github.com/kujirashark/learingnote/tree/master/flask/flask项目</span><br></pre></td></tr></table></figure>]]></content>
<tags>
<tag> 完整的flask项目 </tag>
</tags>
</entry>
<entry>
<title>自定义django中间件实现登录</title>
<link href="/2018/06/06/%E8%87%AA%E5%AE%9A%E4%B9%89django%E4%B8%AD%E9%97%B4%E4%BB%B6%E5%AE%9E%E7%8E%B0%E7%99%BB%E5%BD%95/"/>
<url>/2018/06/06/%E8%87%AA%E5%AE%9A%E4%B9%89django%E4%B8%AD%E9%97%B4%E4%BB%B6%E5%AE%9E%E7%8E%B0%E7%99%BB%E5%BD%95/</url>
<content type="html"><![CDATA[<blockquote><p>作者:李忠林</p><p>Github: <a href="https://github.com/kujirashark" target="_blank" rel="noopener">https://github.com/kujirashark</a></p><p>日期: 2018年6月5日</p></blockquote><h5 id="django中注册登录实现"><a href="#django中注册登录实现" class="headerlink" title="django中注册登录实现"></a>django中注册登录实现</h5><h6 id="自定义中间件"><a href="#自定义中间件" class="headerlink" title="自定义中间件"></a>自定义中间件</h6><p> 其实说django自己也带了中间件,但是用起来有点不灵活,需要验证的每个url前面需要包一层login_required(),自我感觉有点不方便.说干就干吧.</p><p>首先在我们的项目文件夹下面创建一个新的目录专门用来存放我们中间件和其他函数.文件夹的名字我们就命名为:utils.在使用python manage.py startapp user 建立好我们用户的应用,所有与用户相关的东西都放这里面来.</p><p><img src="/2018/06/06/自定义django中间件实现登录/file1.png" alt="ile"></p><p>文件中的UserAuthMiddleware.py就是我们要自定义中间件的文件.init文件就是我们要去初始化中间件.</p><p>下面我们就在UserAuthMiddleware.py中开始写我们的代码了.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> datetime <span class="keyword">import</span> datetime</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> django.db.models <span class="keyword">import</span> Q</span><br><span class="line"><span class="keyword">from</span> django.http <span class="keyword">import</span> HttpResponseRedirect</span><br><span class="line"><span class="keyword">from</span> django.core.urlresolvers <span class="keyword">import</span> reverse</span><br><span class="line"><span class="keyword">from</span> django.utils.deprecation <span class="keyword">import</span> MiddlewareMixin</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> user.models <span class="keyword">import</span> UserTicketModel</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">UserAuthMiddle</span><span class="params">(MiddlewareMixin)</span>:</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">process_request</span><span class="params">(self, request)</span>:</span></span><br><span class="line"> <span class="comment"># 验证cookie中的ticket,验证不通过,跳转到登录页面</span></span><br><span class="line"> <span class="comment"># 验证通过,request.user 就能获取当前登录的用户信息</span></span><br><span class="line"> <span class="comment"># path = request.path</span></span><br><span class="line"> <span class="comment"># 需要登录验证, 个人中心和购物车</span></span><br><span class="line"> need_login = [<span class="string">'/axf/mine/'</span>, <span class="string">'/axf/cart/'</span>]</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> request.path <span class="keyword">in</span> need_login:</span><br><span class="line"> <span class="comment"># 先获取cookie中的ticket的参数</span></span><br><span class="line"> ticket = request.COOKIES.get(<span class="string">'ticket'</span>)</span><br><span class="line"> <span class="comment"># 如果没有ticket 直接跳转到登录</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> ticket:</span><br><span class="line"> <span class="keyword">return</span> HttpResponseRedirect(reverse(<span class="string">'user:login'</span>))</span><br><span class="line"> <span class="comment"># 查询ticket对应的用户</span></span><br><span class="line"> user_ticket = UserTicketModel.objects.filter(ticket=ticket).first()</span><br><span class="line"> <span class="keyword">if</span> user_ticket:</span><br><span class="line"> <span class="comment"># 获取到有认证的相关信息</span></span><br><span class="line"> <span class="comment"># 1. 验证当前认证信息是否过期,如果没有过期,request.user赋值</span></span><br><span class="line"> <span class="comment"># 2. 如果过期了,跳转到登录,并删除认证信息</span></span><br><span class="line"> <span class="comment"># --------------------------------- #</span></span><br><span class="line"> <span class="comment"># 判断当期时间是否与服务器ticket的时间过期</span></span><br><span class="line"> <span class="comment"># replace()将user_ticket.out_time中的tzinfo替换掉</span></span><br><span class="line"> <span class="keyword">if</span> datetime.now() > user_ticket.out_time.replace(tzinfo=<span class="keyword">None</span>):</span><br><span class="line"> <span class="comment"># 过期 就删除这个用户认证的所有信息 并跳转到登录页面</span></span><br><span class="line"> UserTicketModel.objects.filter(user=user_ticket.user).delete()</span><br><span class="line"> <span class="keyword">return</span> HttpResponseRedirect(reverse(<span class="string">'user:login'</span>))</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="comment"># 没有过期 ,赋值request.user ,并且删除多余的认证信息</span></span><br><span class="line"> request.user = user_ticket.user</span><br><span class="line"> <span class="comment"># 删除多余的认证信息 ~Q取反</span></span><br><span class="line"> UserTicketModel.objects.filter(Q(user=user_ticket.user) & ~Q(ticket=ticket)).delete()</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">None</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> HttpResponseRedirect(reverse(<span class="string">'user:login'</span>))</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">None</span></span><br></pre></td></tr></table></figure><p>引入模块的顺序是先引入系统自带的模块—>在引入django带的模块—>在引入自己定义的模块.已经登录注册的中间件我们就定义好了.那么我们如何去使用它呢?</p><p>进入我们的项目中的settings.py的文件找到我们的中间件配置的位置把我们定义好的东西引入进来具体如下:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">MIDDLEWARE = [</span><br><span class="line"> <span class="string">'django.middleware.security.SecurityMiddleware'</span>,</span><br><span class="line"> <span class="string">'django.contrib.sessions.middleware.SessionMiddleware'</span>,</span><br><span class="line"> <span class="string">'django.middleware.common.CommonMiddleware'</span>,</span><br><span class="line"> <span class="string">'django.middleware.csrf.CsrfViewMiddleware'</span>,</span><br><span class="line"> <span class="string">'django.contrib.auth.middleware.AuthenticationMiddleware'</span>,</span><br><span class="line"> <span class="string">'django.contrib.messages.middleware.MessageMiddleware'</span>,</span><br><span class="line"> <span class="string">'django.middleware.clickjacking.XFrameOptionsMiddleware'</span>,</span><br><span class="line"> <span class="comment"># 下面这个就是我们定义好的中间件了</span></span><br><span class="line"> <span class="string">'utils.UserAuthMiddleWare.UserAuthMiddle'</span>, </span><br><span class="line">]</span><br></pre></td></tr></table></figure><p>再来到我们定义好的models.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.db <span class="keyword">import</span> models</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">UesrModel</span><span class="params">(models.Model)</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 保存用户</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> username = models.CharField(max_length=<span class="number">32</span>, unique=<span class="keyword">True</span>)</span><br><span class="line"> password = models.CharField(max_length=<span class="number">256</span>) <span class="comment"># 密码</span></span><br><span class="line"> email = models.CharField(max_length=<span class="number">64</span>, unique=<span class="keyword">True</span>)</span><br><span class="line"> <span class="comment"># False 代表女</span></span><br><span class="line"> sex = models.BooleanField(default=<span class="keyword">False</span>) <span class="comment"># 性别</span></span><br><span class="line"> icon = models.ImageField(upload_to=<span class="string">'icons'</span>) <span class="comment"># toux</span></span><br><span class="line"> is_delete = models.BooleanField(default=<span class="keyword">False</span>) <span class="comment"># 是否删除</span></span><br><span class="line"></span><br><span class="line"> <span class="class"><span class="keyword">class</span> <span class="title">Meta</span>:</span></span><br><span class="line"> db_table = <span class="string">'axf_users'</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">UserTicketModel</span><span class="params">(models.Model)</span>:</span></span><br><span class="line"><span class="string">"""</span></span><br><span class="line"><span class="string">保存用户登录需要用的ticket</span></span><br><span class="line"><span class="string">"""</span></span><br><span class="line"> user = models.ForeignKey(UesrModel) <span class="comment"># 关联用户</span></span><br><span class="line"> ticket = models.CharField(max_length=<span class="number">256</span>) <span class="comment"># 密码</span></span><br><span class="line"> out_time = models.DateTimeField() <span class="comment"># 过期时间</span></span><br><span class="line"></span><br><span class="line"> <span class="class"><span class="keyword">class</span> <span class="title">Meta</span>:</span></span><br><span class="line"> db_table = <span class="string">'axf_users_ticket'</span></span><br></pre></td></tr></table></figure><p>以上准备工作都做好了之后我们就开始来配置我们的[URL]和views.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.conf.urls <span class="keyword">import</span> url</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> user <span class="keyword">import</span> views</span><br><span class="line"></span><br><span class="line">urlpatterns = [</span><br><span class="line"> <span class="comment"># 注册</span></span><br><span class="line"> url(<span class="string">r'^register/'</span>, views.register, name=<span class="string">'register'</span>),</span><br><span class="line"> <span class="comment"># 登录</span></span><br><span class="line"> url(<span class="string">r'^login/'</span>, views.login, name=<span class="string">'login'</span>),</span><br><span class="line"> <span class="comment"># 注销</span></span><br><span class="line"> url(<span class="string">r'^logout/'</span>, views.logout, name=<span class="string">'logout'</span>),</span><br><span class="line"></span><br><span class="line">]</span><br></pre></td></tr></table></figure><p>建立我们的登录注册注销的views</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> datetime <span class="keyword">import</span> datetime, timedelta</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> django.contrib.auth.hashers <span class="keyword">import</span> make_password, check_password</span><br><span class="line"><span class="keyword">from</span> django.core.urlresolvers <span class="keyword">import</span> reverse</span><br><span class="line"><span class="keyword">from</span> django.http <span class="keyword">import</span> HttpResponse, HttpResponseRedirect</span><br><span class="line"><span class="keyword">from</span> django.shortcuts <span class="keyword">import</span> render</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> user.models <span class="keyword">import</span> UesrModel, UserTicketModel</span><br><span class="line"><span class="keyword">from</span> utils.function <span class="keyword">import</span> get_ticket</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">register</span><span class="params">(request)</span>:</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> <span class="keyword">return</span> render(request, <span class="string">'user/user_register.html'</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"> username = request.POST[<span class="string">'username'</span>]</span><br><span class="line"> email = request.POST[<span class="string">'email'</span>]</span><br><span class="line"> password = request.POST[<span class="string">'password'</span>]</span><br><span class="line"> icon = request.FILES[<span class="string">'icon'</span>]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 需要验证参数都不为空</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> all([username, email, password]):</span><br><span class="line"> <span class="comment"># 验证不通过向页面返回信息</span></span><br><span class="line"> msg = <span class="string">'参数不能为空'</span></span><br><span class="line"> <span class="keyword">return</span> render(request, <span class="string">'user/user_register.html'</span>, {<span class="string">'msg'</span>: msg})</span><br><span class="line"> <span class="comment"># 加密 make_password()</span></span><br><span class="line"> password = make_password(request.POST[<span class="string">'password'</span>])</span><br><span class="line"> <span class="comment"># 创建用户</span></span><br><span class="line"> UesrModel.objects.create(username=username,</span><br><span class="line"> email=email,</span><br><span class="line"> password=password,</span><br><span class="line"> icon=icon)</span><br><span class="line"> <span class="comment"># 跳转到登录页面</span></span><br><span class="line"> <span class="keyword">return</span> HttpResponseRedirect(reverse(<span class="string">'user:login'</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">login</span><span class="params">(request)</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 登录</span></span><br><span class="line"><span class="string"> :param request:</span></span><br><span class="line"><span class="string"> :return:</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> <span class="keyword">return</span> render(request, <span class="string">'user/user_login.html'</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"></span><br><span class="line"> username = request.POST.get(<span class="string">'username'</span>)</span><br><span class="line"> password = request.POST.get(<span class="string">'password'</span>)</span><br><span class="line"> <span class="comment"># 验证用户是否存在</span></span><br><span class="line"> user = UesrModel.objects.filter(username=username).first()</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> user:</span><br><span class="line"> <span class="comment"># 验证密码是否正确</span></span><br><span class="line"> <span class="keyword">if</span> check_password(password, user.password):</span><br><span class="line"> <span class="comment"># 1. 保存ticket在客户端</span></span><br><span class="line"> ticket = get_ticket()</span><br><span class="line"> response = HttpResponseRedirect(reverse(<span class="string">'axf:mine'</span>))</span><br><span class="line"> <span class="comment"># 获取系统时间 并使用timedelta函数 加一天为过期时间</span></span><br><span class="line"> out_time = datetime.now() + timedelta(days=<span class="number">1</span>)</span><br><span class="line"> <span class="comment"># 设置过期时间</span></span><br><span class="line"> response.set_cookie(<span class="string">'ticket'</span>, ticket, expires=out_time)</span><br><span class="line"> <span class="comment"># 2. 保存ticket 到服务器的user_ticket表中</span></span><br><span class="line"> UserTicketModel.objects.create(user=user,</span><br><span class="line"> out_time=out_time,</span><br><span class="line"> ticket=ticket)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> response</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> msg = <span class="string">'密码不正确'</span></span><br><span class="line"> <span class="keyword">return</span> render(request, <span class="string">'user/user_login.html'</span>, {<span class="string">'msg'</span>: msg})</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> msg = <span class="string">'用户名不正常'</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> render(request, <span class="string">'user/user_login.html'</span>, {<span class="string">'msg'</span>: msg})</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">logout</span><span class="params">(request)</span>:</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 用户注销</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> <span class="comment"># 注销,删除当前登录的用户的cookies中的ticket信息</span></span><br><span class="line"> response = HttpResponseRedirect(reverse(<span class="string">'user:login'</span>))</span><br><span class="line"> response.delete_cookie(<span class="string">'ticket'</span>)</span><br><span class="line"> <span class="keyword">return</span> response</span><br></pre></td></tr></table></figure><p>来到这一步我们的工作就差不多结束了.这样我们就可以启动服务器来测试我们定义的中间件是否有效. 推荐都使用debug来检查我们写代码的问题,这样对我们自己的能力提升是非常大的.</p><p> ——————<end>————-</end></p>]]></content>
<tags>
<tag> 中间件 </tag>
</tags>
</entry>
<entry>
<title>Django中模型查询</title>
<link href="/2018/06/03/Django%E4%B8%AD%E6%A8%A1%E5%9E%8B%E6%9F%A5%E8%AF%A2/"/>
<url>/2018/06/03/Django%E4%B8%AD%E6%A8%A1%E5%9E%8B%E6%9F%A5%E8%AF%A2/</url>
<content type="html"><![CDATA[<h3 id="Django中模型查询"><a href="#Django中模型查询" class="headerlink" title="Django中模型查询"></a>Django中模型查询</h3><h5 id="1,定义属性"><a href="#1,定义属性" class="headerlink" title="1,定义属性"></a>1,定义属性</h5><p>Django根据属性的类型确定以下信息:</p><ul><li>当前选择的数据库支持字段的类型</li><li>渲染管理表单时使用的默认html控件</li><li>在管理站点最低限度的验证</li></ul><p>django会为表创建自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后django不会再创建自动增长的主键列。</p><ul><li>默认创建的主键列属性为id,可以使用pk代替,pk全拼为primary key。</li><li>注意:pk是主键的别名,若主键名为id2,那么pk是id2的别名。</li></ul><p>属性命名限制:</p><ul><li>不能是python的保留关键字。</li><li>不允许使用连续的下划线,这是由django的查询方式决定的</li><li>定义属性时需要指定字段类型,通过字段类型的参数指定选项,语法如下:<br><strong>属性=models.字段类型(选项)</strong></li></ul><h5 id="2,字段类型"><a href="#2,字段类型" class="headerlink" title="2,字段类型"></a>2,字段类型</h5><p>使用时需要引入django.db.models包,字段类型如下:</p><ul><li>AutoField:自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性。</li><li>BooleanField:布尔字段,值为True或False。</li><li>NullBooleanField:支持Null、True、False三种值。</li><li>CharField(max_length=字符长度):字符串。<br>参数max_length表示最大字符个数。</li><li>TextField:大文本字段,一般超过4000个字符时使用。</li><li>IntegerField:整数。</li><li>DecimalField(max_digits=None, decimal_places=None):十进制浮点数。<br>++ 参数max_digits表示总位数。<br>++ 参数decimal_places表示小数位数。</li><li>FloatField:浮点数。</li><li>DateField[auto_now=False, auto_now_add=False]):日期。<br>++ 参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于”最后一次修改”的时间戳,它总是使用当前日期,默认为false。<br>++ 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false。<br>++参数auto_now_add和auto_now是相互排斥的,组合将会发生错误。</li><li>TimeField:时间,参数同DateField。</li><li>DateTimeField:日期时间,参数同DateField。</li><li>FileField:上传文件字段。</li><li>ImageField:继承于FileField,对上传的内容进行校验,确保是有效的图片。</li></ul><h5 id="3,选项"><a href="#3,选项" class="headerlink" title="3,选项"></a>3,选项</h5><p>通过选项实现对字段的约束,选项如下:</p><ul><li>null:如果为True,表示允许为空,默认值是False。</li><li>blank:如果为True,则该字段允许为空白,默认值是False。</li><li>对比:null是数据库范畴的概念,blank是表单验证证范畴的。</li><li>db_column:字段的名称,如果未指定,则使用属性的名称。</li><li>db_index:若值为True, 则在表中会为此字段创建索引,默认值是False。</li><li>default:默认值。</li><li>primary_key:若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用。</li><li>unique:如果为True, 这个字段在表中必须有唯一值,默认值是False。</li></ul><h5 id="4,字段查询"><a href="#4,字段查询" class="headerlink" title="4,字段查询"></a>4,字段查询</h5><p>all():返回模型类对应表格中的所有数据。<br>例:查询图书所有信息。<br>BookInfo.objects.all();->select * from booktest_bookinfo;</p><p>get():返回表格中满足条件的一条数据。<br>如果查到多条数据,则抛异常:MultipleObjectsReturned<br>查询不到数据,则抛异常:DoesNotExist<br>例:查询图书id为3的图书信息。<br>BookInfo.objects.get(id=3) –> select * from booktest_bookinfo where id = 3;</p><p>filter():参数写查询条件,返回满足条件QuerySet集合数据。<br>条件格式:<br><strong>模型类属性名</strong>__条件名=值<br>注意:此处是模型类属性名,不是表中的字段名</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">1. 判等 exact。</span><br><span class="line">例:查询编号为1的图书。</span><br><span class="line">BookInfo.object.filter(id=1)</span><br><span class="line">BookInfo.object.filter(id__exact=1)此处的exact可以省略</span><br><span class="line"></span><br><span class="line">2. 模糊查询 like</span><br><span class="line">例:查询书名包含'传'的图书。contains</span><br><span class="line">BookInfo.objects.filter(btitle__contains=’传’)</span><br><span class="line">例:查询书名以'部'结尾的图书 endswith 开头:startswith</span><br><span class="line">BookInfo.objects.filter(btitle__endswith=’部’)</span><br><span class="line">BookInfo.objects.filter(btitle__startswith=’天’)</span><br><span class="line"></span><br><span class="line">3. 空查询 where 字段名 isnull</span><br><span class="line">例:查询书名不为空的图书。isnull</span><br><span class="line">BookInfo.objects.filter(btitle__isnull=False)</span><br><span class="line"></span><br><span class="line">4. 范围查询 where id in (1,3,5) </span><br><span class="line">例:查询编号为1或3或5的图书。In</span><br><span class="line">BookInfo.objects.filter(id__in=[1,3,5])</span><br><span class="line"></span><br><span class="line">5. 比较查询 gt lt(less than) gte(equal) lte</span><br><span class="line">例:查询编号大于等于3的图书。</span><br><span class="line">BookInfo.objects.filter(id__gte=3)</span><br><span class="line"></span><br><span class="line">6. 日期查询</span><br><span class="line">例:查询1980年发表的图书。</span><br><span class="line">BookInfo.objects.filter(bpub_date__year = 1980)</span><br><span class="line">例:查询1980年1月1日后发表的图。</span><br><span class="line">BookInfo.objects.filter(bpub_date__gt = date(1980,1,1))</span><br><span class="line"></span><br><span class="line">7. exclude:返回不满足条件的数据。</span><br><span class="line">例:查询id不为3的图书信息。</span><br><span class="line">BookInfo.objects.exclude(id=3)123456789101112131415161718192021222324252627282930313233</span><br></pre></td></tr></table></figure><h5 id="5,F对象"><a href="#5,F对象" class="headerlink" title="5,F对象"></a>5,F对象</h5><p>作用:用于类属性之间的比较条件。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">使用之前需要先导入:</span><br><span class="line">from django.db.models import F</span><br><span class="line">例:查询图书阅读量大于评论量图书信息。where bread > bcomment</span><br><span class="line">BookInfo.objects.filter(bread__gt = F(‘bcomment’))</span><br><span class="line">例:查询图书阅读量大于2倍评论量图书信息。</span><br><span class="line">BookInfo.objects.filter(bread__gt=F(‘bcomment’)*2)</span><br></pre></td></tr></table></figure><h5 id="6,Q对象"><a href="#6,Q对象" class="headerlink" title="6,Q对象"></a>6,Q对象</h5><p>作用:用于查询时的逻辑条件。可以对Q对象进行&|~操作。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">使用之前需要先导入:</span><br><span class="line">from django.db.models import Q</span><br><span class="line">例:查询id大于3且阅读大于30的图书的信息。</span><br><span class="line">BookInfo.objects.filter(id__gt=3, bread__gt=30)</span><br><span class="line">BooInfo.objects.filter(Q(id__gt=3) & Q(bread__gt=3))</span><br><span class="line">例:查询id大于3或者阅读大于30的图书的信息。</span><br><span class="line">BookInfo.objects.filter(Q(id__gt=3) | Q(bread__gt=30))</span><br><span class="line">例:查询id不等于3图书的信息。</span><br><span class="line">BookInfo.objects.filter(~Q(id=3))123456789</span><br></pre></td></tr></table></figure><h5 id="7,order-by-返回QuerySet"><a href="#7,order-by-返回QuerySet" class="headerlink" title="7,order_by 返回QuerySet"></a>7,order_by 返回QuerySet</h5><p>作用:进行查询结果进行排序。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">例:查询所有图书的信息,按照id从小到大进行排序。</span><br><span class="line">BookInfo.objects.all()order_by('id')</span><br><span class="line">例:查询所有图书的信息,按照id从大到小进行排序。</span><br><span class="line">BookInfo.objects.all().order_by('-id')</span><br><span class="line">例:把id大于3的图书信息按阅读量从大到小排序显示;</span><br><span class="line">BookInfo.objects.filter(id__gt=3).order_by('-bread')123456</span><br></pre></td></tr></table></figure><h5 id="8,聚合函数"><a href="#8,聚合函数" class="headerlink" title="8,聚合函数"></a>8,聚合函数</h5><p>作用:对查询结果进行聚合操作。<br>sum count max min avg<br>aggregate:调用这个函数来使用聚合。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">使用前需先导入聚合类:</span><br><span class="line">from django.db.models import Sum,Count,Max,Min,Avg</span><br><span class="line">例:查询所有图书的数目。select count(*) from booktest_bookinfo;</span><br><span class="line">BookInfo.objects.aggregate(Count('id'))</span><br><span class="line">{'id__count': 5} 注意返回值类型及键名</span><br><span class="line">例:查询所有图书阅读量的总和。</span><br><span class="line">BookInfo.objects.aggregate(Sum(‘bread’))</span><br><span class="line">{‘bread__sum’:120} 注意返回值类型及键名12345678</span><br></pre></td></tr></table></figure><p>count函数<br>作用:统计满足条件数据的数目。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">例:统计所有图书的数目。</span><br><span class="line">BookInfo.objects.all().count()</span><br><span class="line">例:统计id大于3的所有图书的数目。</span><br><span class="line">BookInfo.objects.filter(id__gt = 3).count()1234</span><br></pre></td></tr></table></figure><h5 id="9,查询相关函数返回值总结:"><a href="#9,查询相关函数返回值总结:" class="headerlink" title="9,查询相关函数返回值总结:"></a>9,查询相关函数返回值总结:</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">get:返回一个对象</span><br><span class="line">all:QuerySet(也就是[])</span><br><span class="line">filter:QuerySet</span><br><span class="line">exclude:QuerySet</span><br><span class="line">order_by:QuerySet</span><br><span class="line">aggregate:字典</span><br><span class="line">count:值1234567</span><br></pre></td></tr></table></figure><h5 id="10,查询集"><a href="#10,查询集" class="headerlink" title="10,查询集"></a>10,查询集</h5><blockquote><p>all, filter, exclude, order_by调用这些函数会产生一个查询集,可以在查询集上继续调用这些函数。</p></blockquote><p>查询集特性:</p><ul><li>1)惰性查询:只有在实际使用查询集中的数据的时候才会发生对数据库的真正查询。</li><li>2)缓存:当使用的是同一个查询集时,第一次的时候会发生实际数据库的查询,然后把结果缓存起来,之后再使用这个查询集时,使用的是缓存中的结果。</li></ul><p>限制查询集:</p><blockquote><p>可以对一个查询集进行取下标或者切片操作来限制查询集的结果。</p></blockquote><ul><li>b[0]就是取出查询集的第一条数据,</li><li>b[0:1].get()也可取出查询集的第一条数据。</li><li>如果b[0]不存在,会抛出IndexError异常,</li><li>如果b[0:1].get()不存在,会抛出DoesNotExist异常。</li></ul><blockquote><p>对一个查询集进行切片操作会产生一个新的查询集,下标不允许为负数。</p></blockquote><ul><li>exists:判断一个查询集中是否有数据。<br>有返回True,没有返回False</li></ul><h5 id="11,模型类关系"><a href="#11,模型类关系" class="headerlink" title="11,模型类关系"></a>11,模型类关系</h5><p>1)一对多关系<br>例:图书类-英雄类<br>models.ForeignKey() 定义在多的类中。</p><p>2)多对多关系<br>例:新闻类-新闻类型类<br>models.ManyToManyField() 定义在哪个类中都可以。</p><p>3)一对一关系<br>例:员工基本信息类-员工详细信息类<br>models.OneToOneField() 定义在哪个类中都可以。</p><h5 id="12,关联查询(一对多)"><a href="#12,关联查询(一对多)" class="headerlink" title="12,关联查询(一对多)"></a>12,关联查询(一对多)</h5><p>在一对多关系中,一对应的类我们把它叫做一类,多对应的那个类我们把它叫做多类,我们把多类中定义的建立关联的类属性叫做关联属性。</p><h6 id="A、通过对象执行关联查询"><a href="#A、通过对象执行关联查询" class="headerlink" title="A、通过对象执行关联查询"></a>A、通过对象执行关联查询</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">例:查询图书id为1的所有英雄的信息。</span><br><span class="line"> b = BookInfo.objects.get(id=1)</span><br><span class="line"> b.heroinfo_set.all()</span><br><span class="line"></span><br><span class="line">例:查询id为1的英雄所属图书信息。</span><br><span class="line"> h = HeroInfo.objects.get(id=1)</span><br><span class="line"> h.hbook</span><br><span class="line"> h.hbook_id12345678</span><br></pre></td></tr></table></figure><p>格式:</p><ul><li><p>由一类的对象查询多类的时候:</p><blockquote><p>一类的对象.多类名小写_set.all() #查询所用数据</p></blockquote></li><li><p>由多类的对象查询一类的时候:</p><blockquote><p>多类的对象.关联属性 #查询多类的对象对应的一类的对象</p></blockquote></li><li><p>由多类的对象查询一类对象的id时候:</p><blockquote><p>多类的对象. 关联属性_id</p></blockquote></li></ul><h6 id="B、通过模型类实现关联查询:"><a href="#B、通过模型类实现关联查询:" class="headerlink" title="B、通过模型类实现关联查询:"></a>B、通过模型类实现关联查询:</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">例:查询图书,要求图书中英雄的描述包含'八'。Join</span><br><span class="line">BookInfo.objects.filter(heroinfo__hcomment__contains='八')</span><br><span class="line"></span><br><span class="line">例:查询图书,要求图书中的英雄的id大于3.</span><br><span class="line">BookInfo.objects.filter(heroinfo__id__gt=3)</span><br><span class="line"></span><br><span class="line">例:查询书名为“天龙八部”的所有英雄。</span><br><span class="line">HeroInfo.objects.filter(hbook__btitle = '天龙八部')12345678</span><br></pre></td></tr></table></figure><p>格式:</p><ul><li>通过多类的条件查询一类的数据:</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">一类名.objects.filter(多类名小写__多类属性名__条件名=值)1</span><br></pre></td></tr></table></figure><ul><li>通过一类的条件查询多类的数据:</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">多类名.objects.filter(关联属性__一类属性名__条件名=值)1</span><br></pre></td></tr></table></figure><h5 id="13,自关联-特殊的一对多的关系"><a href="#13,自关联-特殊的一对多的关系" class="headerlink" title="13,自关联,特殊的一对多的关系"></a>13,自关联,特殊的一对多的关系</h5><p>对于地区信息、分类信息等数据,表结构非常类似,每个表的数据量十分有限,为了充分利用数据表的大量数据存储功能,可以可以设计成一张表,内部的关系字段指向本表的主键,这就是自关联的表结构。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">#定义地区模型类,存储省、市、区县信息</span><br><span class="line">class AreaInfo(models.Model):</span><br><span class="line"> atitle=models.CharField(max_length=30)</span><br><span class="line"></span><br><span class="line"> # 关系属性使用self指向本类,要求null和blank允许为空,因为一级数据是没有父级的。</span><br><span class="line"></span><br><span class="line"> aParent=models.ForeignKey('self',null=True,blank=True)1234567</span><br></pre></td></tr></table></figure><h5 id="14,管理器"><a href="#14,管理器" class="headerlink" title="14,管理器"></a>14,管理器</h5><p>BookInfo.objects.all()->objects是一个什么东西呢?<br>答:objects是Django帮我自动生成的管理器,通过这个管理器可以实现对数据的查询。</p><p>objects是models.Manger类的一个对象。自定义管理器之后Django不再帮我们生成默认的objects管理器。</p><p>1)自定义一个管理器类,这个类集成models.Manger类。<br>2)再在具体的模型类里定义一个自定义管理器类的对象。</p><blockquote><p>自定义管理器类的应用场景:</p></blockquote><ul><li>1)改变查询的结果集。<br>比如调用BookInfo.books.all()返回的是没有删除的图书的数据。</li><li>2)在管理器类中定义一个方法帮我们创建对应的模型类对象。<br>使用self.model()就可以创建一个跟自定义管理器对应的模型类对象。</li></ul><h5 id="15,元选项"><a href="#15,元选项" class="headerlink" title="15,元选项"></a>15,元选项</h5><p>Django默认生成的表名:</p><blockquote><p>应用名小写_模型类名小写。</p></blockquote><p>元选项:</p><blockquote><p>需要在模型类中定义一个元类Meta,在里面定义一个类属性db_table就可以指定表名。</p></blockquote><h5 id="16,管理器和元选项案例:"><a href="#16,管理器和元选项案例:" class="headerlink" title="16,管理器和元选项案例:"></a>16,管理器和元选项案例:</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"># 自定义一个管理器类</span><br><span class="line">class BookInfoManager(models.Manager):</span><br><span class="line"> # 重写父类的all函数, 返回数据表中没有删除的数据</span><br><span class="line"># all filter order_by exclude都调用get_queryset()函数,单独重写</span><br><span class="line"></span><br><span class="line"> #作用1:改变查询的结果集</span><br><span class="line"> def all(self):</span><br><span class="line"> # 1.调用父类的方法查询出所有图书 QuerySet</span><br><span class="line"> res = super().get_queryset().all()</span><br><span class="line"> # 2.对结果进行过滤</span><br><span class="line"> return res.filter(isDelete=False)</span><br><span class="line"></span><br><span class="line"> # 作用2:创建对应模型类的对象,并可以进行一些初始化值</span><br><span class="line"> def create(self, btitle, bpub_date):</span><br><span class="line"> # b = BookInfo()</span><br><span class="line"> # 动态创建一个BookInfo类的对象,类名更改之后这句代码也不需要变化</span><br><span class="line"> b = self.model()</span><br><span class="line"> b.btitle = btitle</span><br><span class="line"> b.bpub_date = bpub_date</span><br><span class="line"> b.bread = 0</span><br><span class="line"> b.bcomment = 0</span><br><span class="line"> b.isDelete = False</span><br><span class="line"> return b</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># 一类</span><br><span class="line"># 属性名 = models.字段类型(选项)</span><br><span class="line">class BookInfo(models.Model):</span><br><span class="line"> btitle = models.CharField(max_length=20, db_column='title')</span><br><span class="line"> # btitle = models.CharField(max_length=20, unique=True, db_index=True) #图书标题</span><br><span class="line"> bpub_date = models.DateField(auto_now_add=True) # 出版日期</span><br><span class="line"> bread = models.IntegerField(default=0) # 阅读量</span><br><span class="line"> bcomment = models.IntegerField(default=0) # 评论数</span><br><span class="line"> isDelete = models.BooleanField(default=False) # 软删除</span><br><span class="line"></span><br><span class="line"> # python自带的manager类管理器</span><br><span class="line"> # books = models.Manager()</span><br><span class="line"> # 自定义一个类管理起器对象</span><br><span class="line"> objects = BookInfoManager()</span><br><span class="line"></span><br><span class="line"> # 元选项</span><br><span class="line"> class Meta:</span><br><span class="line"> db_table = 'bookinfo' # 指定表名,db_table不能变</span><br></pre></td></tr></table></figure>]]></content>
<tags>
<tag> Django查询 </tag>
</tags>
</entry>
<entry>
<title>最适合初学Django框架的项目</title>
<link href="/2018/06/03/%E6%9C%80%E9%80%82%E5%90%88%E5%88%9D%E5%AD%A6Django%E6%A1%86%E6%9E%B6%E7%9A%84%E9%A1%B9%E7%9B%AE/"/>
<url>/2018/06/03/%E6%9C%80%E9%80%82%E5%90%88%E5%88%9D%E5%AD%A6Django%E6%A1%86%E6%9E%B6%E7%9A%84%E9%A1%B9%E7%9B%AE/</url>
<content type="html"><![CDATA[<p>初学Django 包含了页面的增删改查,ajax,分页,中间件,权限……等等知识点</p><hr><p>自己学了一段时间的Django了,开始的是时候有点懵,不过细细回味了一下,于是乎把学习的部分内容总结了一下.以一个项目来分享给大家.希望对大家有帮助.</p><p>项目的样子:</p><p><img src="/2018/06/03/最适合初学Django框架的项目/home.png" alt="om"></p><p><img src="/2018/06/03/最适合初学Django框架的项目/adminye.png" alt="dminy"></p><p><img src="/2018/06/03/最适合初学Django框架的项目/xsxx.png" alt="sx"></p><p><img src="/2018/06/03/最适合初学Django框架的项目/bjxx.png" alt="jx"></p><p><img src="/2018/06/03/最适合初学Django框架的项目/tjxs.png" alt="jx"></p><p><img src="/2018/06/03/最适合初学Django框架的项目/xm.png" alt=""></p><hr><p>创建可以循环使用的虚拟环境</p><h6 id="1安装virtualenv"><a href="#1安装virtualenv" class="headerlink" title="1安装virtualenv"></a>1安装virtualenv</h6><ul><li>pip install virtualenv </li></ul><h6 id="2-使用–no-site-packages"><a href="#2-使用–no-site-packages" class="headerlink" title="2 .使用–no-site-packages"></a>2 .使用–no-site-packages</h6><ul><li>virtualenv –no-site-packages djangoenv</li><li>进入虚拟环境激活虚拟环境 命令:source activate</li></ul><h6 id="3检查pip已经安装过哪些包"><a href="#3检查pip已经安装过哪些包" class="headerlink" title="3检查pip已经安装过哪些包"></a>3检查pip已经安装过哪些包</h6><ul><li>pip freeze:查看pip安装过的包</li><li>pip list:查看所有安装过的包</li></ul><h6 id="4-安装需要用的库"><a href="#4-安装需要用的库" class="headerlink" title="4.安装需要用的库"></a>4.安装需要用的库</h6><ul><li>pip install django==1.11</li><li>pip install pymysql</li></ul><h6 id="5-创建项目并且运行"><a href="#5-创建项目并且运行" class="headerlink" title="5.创建项目并且运行"></a>5.创建项目并且运行</h6><ol><li><p>创建项目</p><p>django-amdin startproject day1 </p></li><li><p>创建app</p><p>python manage.py startapp app</p></li><li><p>启动服务器</p><p>python manage.py runserver</p></li></ol><h6 id="6-配置MySQL"><a href="#6-配置MySQL" class="headerlink" title="6.配置MySQL"></a>6.配置MySQL</h6><ul><li><p>进入项目下的init文件中</p><p><strong>import pymysql</strong></p><p><strong>pymysql.install_as_MySQLdb()</strong></p></li></ul><h6 id="7-配置setting和其他文件"><a href="#7-配置setting和其他文件" class="headerlink" title="7.配置setting和其他文件"></a>7.配置setting和其他文件</h6><hr><h5 id="URL反向解析"><a href="#URL反向解析" class="headerlink" title="URL反向解析"></a>URL反向解析</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">在[url]文件中配置namespace. 在应用下面的[url]文件中配置name</span><br><span class="line"></span><br><span class="line">src = '/app/left/'</span><br><span class="line"></span><br><span class="line">src = "{% url 'namespace:name' %}"</span><br></pre></td></tr></table></figure><hr><h6 id="静态解析"><a href="#静态解析" class="headerlink" title="静态解析"></a>静态解析</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">针对静态url加载css/js等等</span><br></pre></td></tr></table></figure><p></p><p>需要在setting文件中配置</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># Static files (CSS, JavaScript, Images)</span><br><span class="line"># https://docs.djangoproject.com/en/1.11/howto/static-files/</span><br><span class="line"></span><br><span class="line">STATIC_URL = '/static/'</span><br><span class="line"></span><br><span class="line">STATICFILES_DIRS = [os.path.join(BASE_DIR,'static'),]</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><img src='/statc/img/xxx.css'></span><br><span class="line"></span><br><span class="line">加载静态内容</span><br><span class="line">{% load static %}</span><br><span class="line"></span><br><span class="line"><img src='{% static "img/xxx.css" %}'></span><br></pre></td></tr></table></figure><hr><h6 id="由于项目文件太多我把项目源码放git了"><a href="#由于项目文件太多我把项目源码放git了" class="headerlink" title="由于项目文件太多我把项目源码放git了"></a>由于项目文件太多我把项目源码放git了</h6><p>项目的环境:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Django==1.11</span><br><span class="line">PyMySQL==0.8.1</span><br></pre></td></tr></table></figure><p>下载地址:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://github.com/kujirashark/learingnote</span><br></pre></td></tr></table></figure>]]></content>
<tags>
<tag> Django </tag>
</tags>
</entry>
<entry>
<title>Django之Cookie和Session</title>
<link href="/2018/05/25/Django%E4%B9%8BCookie%E5%92%8CSession/"/>
<url>/2018/05/25/Django%E4%B9%8BCookie%E5%92%8CSession/</url>
<content type="html"><![CDATA[<h5 id="django中的cookie和session"><a href="#django中的cookie和session" class="headerlink" title="django中的cookie和session"></a>django中的cookie和session</h5><blockquote><h6 id="cookie(储存在用户本地终端上的数据)"><a href="#cookie(储存在用户本地终端上的数据)" class="headerlink" title="cookie(储存在用户本地终端上的数据)"></a>cookie(储存在用户本地终端上的数据)</h6><p>Cookie,有时也用其复数形式 <a href="https://baike.baidu.com/item/Cookies/187064" target="_blank" rel="noopener">Cookies</a>,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。定义于 RFC2109 和 2965 中的都已废弃,最新取代的规范是 RFC6265 [1]<a href=""> </a> 。(可以叫做浏览器缓存)</p></blockquote><blockquote><h6 id="session(计算机语言)"><a href="#session(计算机语言)" class="headerlink" title="session(计算机语言)"></a>session(计算机语言)</h6><p>:在计算机中,尤其是在网络应用中,称为“会话控制”。Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。例如,如果用户指明不喜欢查看图形,就可以将该信息存储在 Session 对象中。有关使用 Session 对象的详细信息,请参阅“ASP 应用程序”部分的“管理会话”。注意 会话状态仅在支持 cookie 的浏览器中保留。</p></blockquote><h6 id="用户跟踪的三种技术"><a href="#用户跟踪的三种技术" class="headerlink" title="用户跟踪的三种技术"></a>用户跟踪的三种技术</h6><blockquote><p>1.cookie 请求头 <最常用></p><p>2.url重写 地址栏</p><p>3.隐藏域/隐式表单域 表达提交</p></blockquote><h6 id="执行表单额外的验证"><a href="#执行表单额外的验证" class="headerlink" title="执行表单额外的验证"></a>执行表单额外的验证</h6><p>方法名必须以clean_开头.这个方法是自动执行的.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">#例如:</span><br><span class="line">class CarRecordForm(forms.ModelForm):</span><br><span class="line"> carno = forms.CharField(min_length=7, max_length=7, label='车牌号', error_messages={'carno': '请输入有效的车牌号'})</span><br><span class="line"> reason = forms.CharField(max_length=50, label='违章原因')</span><br><span class="line"> punish = forms.CharField(max_length=50, required=False, label='处罚方式')</span><br><span class="line"></span><br><span class="line"> """</span><br><span class="line"> # 执行额外的表单数据验证</span><br><span class="line"> def clean_carno(self):</span><br><span class="line"> _carno = self.cleaned_data['carno']</span><br><span class="line"> if not condition:</span><br><span class="line"> raise forms.ValidationError('...')</span><br><span class="line"> return _carno</span><br><span class="line"> """</span><br></pre></td></tr></table></figure><blockquote><p>如果是GET请求可以给初始数据.需要使用:initial={} 初始数据没有填写完整</p></blockquote><h6 id="cookie"><a href="#cookie" class="headerlink" title="cookie"></a>cookie</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">#cookie是保存在浏览器的临时文件中的用户数据(通常是识别用户的ID/token或者是用户的偏好设置).</span><br><span class="line"></span><br><span class="line">#因为在每次请求服务器时在HTTP请求的请求头中都会携带本网站的Cookie数据</span><br><span class="line"></span><br><span class="line">#那么服务器就可以获取这些信息来识别用户的身份或者了解用户的偏好 这就是所谓的用户跟踪</span><br><span class="line"></span><br><span class="line">#因为HTTP本身是无状态的 所有需要使用Cookie/隐藏域/url重写这样的技术实现用户跟踪</span><br><span class="line"></span><br><span class="line">#从请求中读取指定的cookie — 通过cookie的名字找到对应的值</span><br><span class="line"></span><br><span class="line">#如果请求中没有指定名字的cookie可以通过get方法的第二个参数设置一个默认的返回值</span><br><span class="line"></span><br><span class="line">#当下次请求的时候会通过请求头的时候传给服务器对比.对比上才能登陆.如果任意一边丢失都会重新登陆</span><br></pre></td></tr></table></figure><h6 id="session"><a href="#session" class="headerlink" title="session"></a>session</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">#通过request对象的session属性可以获取到session</span><br><span class="line"># session相当于是服务器端用来保存用户数据的一个字典</span><br><span class="line"># session利用了Cookie保存sessionid</span><br><span class="line"># 通过sessionid就可以获取与某个用户对应的会话(也就是用户数据)</span><br><span class="line"># 如果在浏览器中清除了Cookie那么也就清除了sessionid</span><br><span class="line"># 再次访问服务器时服务器会重新分配新的sessionid这也就意味着之前的用户数据无法找回</span><br><span class="line"># 默认情况下Django的session被设定为持久会话而非浏览器续存期会话</span><br><span class="line"># 通过SESSION_EXPIRE_AT_BROWSER_CLOSE和SESSION_COOKIE_AGE参数可以修改默认设定</span><br><span class="line"># Django中的session是进行了持久化处理的因此需要设定session的序列化方式</span><br><span class="line"># 1.6版开始Django默认的session序列化器是JsonSerializer</span><br><span class="line"># 可以通过SESSION_SERIALIZER来设定其他的序列化器(例如PickleSerializer)</span><br><span class="line">(例如:SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer')</span><br></pre></td></tr></table></figure><h6 id="项目中的cookie"><a href="#项目中的cookie" class="headerlink" title="项目中的cookie"></a>项目中的cookie</h6><h6 id="项目中的cookie-1"><a href="#项目中的cookie-1" class="headerlink" title="项目中的cookie"></a>项目中的cookie</h6><p>案例:记录用户的上次访问时间</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line">def ajax_search(request):</span><br><span class="line"> current_time = datetime.now().ctime()</span><br><span class="line"> # Cookie是保存在浏览器临时文件中的用户数据(通常是识别用户身份的ID/token或者是用户的偏好设置)</span><br><span class="line"> # 因为每次请求服务器时在HTTP请求的请求头中都会携带本网站的Cookie数据</span><br><span class="line"> # 那么服务器就可以获取这些信息来识别用户身份或者了解用户的偏好 这就是所谓的用户跟踪</span><br><span class="line"> # 因为HTTP本身是无状态的 所以需要使用Cookie/隐藏域/URL重写这样的技术来实现用户跟踪</span><br><span class="line"> # 从请求中读取指定的cookie - 通过cookie的名字找到对应的值</span><br><span class="line"> # 如果请求中没有指定名字的cookie可以通过get方法的第二个参数设置一个默认的返回值</span><br><span class="line"> last_visit_time = request.COOKIES.get('last_visit_time')</span><br><span class="line"> if request.method == 'GET':</span><br><span class="line"> response = render(request, 'search2.html',</span><br><span class="line"> {'last': last_visit_time if last_visit_time</span><br><span class="line"> else '你是第一次访问我们的网站'})</span><br><span class="line"> # 通过render渲染页面后先用set_cookie方法设置cookie后再返回HttpResponse对象</span><br><span class="line"> # 第一个参数是cookie的名字 第二个参数是cookie的值 第三个参数是过期时间(秒)</span><br><span class="line"> response.set_cookie('last_visit_time', current_time, max_age=MAX_AGE)</span><br><span class="line"> return response</span><br><span class="line"> else:</span><br><span class="line"> carno = request.POST['carno']</span><br><span class="line"> record_list = list(CarRecord.objects.filter(carno__icontains=carno))</span><br><span class="line"> # 第一个参数是要转换成JSON格式(序列化)的对象</span><br><span class="line"> # encoder参数要指定完成自定义对象序列化的编码器(JSONEncoder的子类型)</span><br><span class="line"> # safe参数的值如果为True那么传入的第一个参数只能是字典</span><br><span class="line"> # return HttpResponse(json.dumps(record_list), content_type='application/json; charset=utf-8')</span><br><span class="line"> return JsonResponse(record_list, encoder=CarRecordEncoder,</span><br><span class="line"> safe=False)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">def search(request):</span><br><span class="line"> # 请求行中的请求命令</span><br><span class="line"> # print(request.method)</span><br><span class="line"> # 请求行中的路径</span><br><span class="line"> # print(request.path)</span><br><span class="line"> # 请求头(以HTTP_打头的键是HTTP请求的请求头)</span><br><span class="line"> # print(request.META)</span><br><span class="line"> # 查询参数: http://host/path/resource?a=b&c=d</span><br><span class="line"> # print(request.GET)</span><br><span class="line"> # 表单参数</span><br><span class="line"> # print(request.POST)</span><br><span class="line"> if request.method == 'GET':</span><br><span class="line"> ctx = {'show_result': False}</span><br><span class="line"> else:</span><br><span class="line"> carno = request.POST['carno']</span><br><span class="line"> ctx = {</span><br><span class="line"> 'show_result': True,</span><br><span class="line"> 'record_list': list(CarRecord.objects.filter(carno__contains=carno))}</span><br><span class="line"> return render(request, 'search.html', ctx)</span><br></pre></td></tr></table></figure><h5 id="Django项目完整步骤"><a href="#Django项目完整步骤" class="headerlink" title="Django项目完整步骤:"></a>Django项目完整步骤:</h5><h6 id="1-建项目"><a href="#1-建项目" class="headerlink" title="1.建项目"></a>1.建项目</h6><h6 id="2-安装pymysql"><a href="#2-安装pymysql" class="headerlink" title="2.安装pymysql"></a>2.安装pymysql</h6><h6 id="3-在项目文件夹下面的init-配置pymysql"><a href="#3-在项目文件夹下面的init-配置pymysql" class="headerlink" title="3.在项目文件夹下面的init 配置pymysql"></a>3.在项目文件夹下面的<strong>init</strong> 配置pymysql</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">在项目文件夹下面的__init__ 配置pymysql</span><br><span class="line">import pymysql</span><br><span class="line">pymysql.install_as_MySQLdb()</span><br></pre></td></tr></table></figure><h6 id="4-配置INSTALLED-APPS"><a href="#4-配置INSTALLED-APPS" class="headerlink" title="4.配置INSTALLED_APPS"></a>4.配置INSTALLED_APPS</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">INSTALLED_APPS = [</span><br><span class="line"> 'django.contrib.admin',</span><br><span class="line"> 'django.contrib.auth',</span><br><span class="line"> 'django.contrib.contenttypes',</span><br><span class="line"> 'django.contrib.sessions',</span><br><span class="line"> 'django.contrib.messages',</span><br><span class="line"> 'django.contrib.staticfiles',</span><br><span class="line"> 'cart.apps.CartConfig',</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line">中间件 位于浏览器和服务器中间</span><br><span class="line">过滤拦截器</span><br><span class="line">拦截请求和响应</span><br><span class="line">HttpResonse</span><br><span class="line">拦截下来 附加额外的操作</span><br><span class="line">MIDDLEWARE = [</span><br><span class="line"> 'django.middleware.security.SecurityMiddleware',</span><br><span class="line"> 'django.contrib.sessions.middleware.SessionMiddleware',</span><br><span class="line"> 'django.middleware.common.CommonMiddleware',</span><br><span class="line"> 'django.middleware.csrf.CsrfViewMiddleware',</span><br><span class="line"> 'django.contrib.auth.middleware.AuthenticationMiddleware',</span><br><span class="line"> 'django.contrib.messages.middleware.MessageMiddleware',</span><br><span class="line"> 'django.middleware.clickjacking.XFrameOptionsMiddleware',</span><br><span class="line">]</span><br></pre></td></tr></table></figure><h6 id="5数据库的配置"><a href="#5数据库的配置" class="headerlink" title="5数据库的配置"></a>5数据库的配置</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">DATABASES = {</span><br><span class="line"> 'default': {</span><br><span class="line"> 'ENGINE': 'django.db.backends.mysql',</span><br><span class="line"> 'NAME': 'shop',</span><br><span class="line"> 'HOST':'127.0.0.1',</span><br><span class="line"> 'POST':'3306',</span><br><span class="line"> 'USER':'root',</span><br><span class="line"> 'PASSWORD':'123456'</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h6 id="6配置静态资源"><a href="#6配置静态资源" class="headerlink" title="6配置静态资源"></a>6配置静态资源</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">STATICFILES_DIRS = [os.path.join(BASE_DIR,'static'),]</span><br><span class="line">STATIC_URL = '/static/'</span><br></pre></td></tr></table></figure><h6 id="7配置时区-语言"><a href="#7配置时区-语言" class="headerlink" title="7配置时区/语言"></a>7配置时区/语言</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">LANGUAGE_CODE = 'zh-hans'</span><br><span class="line"></span><br><span class="line">TIME_ZONE = 'Asia/Chongqing'</span><br></pre></td></tr></table></figure><h6 id="8配置url"><a href="#8配置url" class="headerlink" title="8配置url"></a>8配置url</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">from cart import views</span><br><span class="line"></span><br><span class="line">urlpatterns = [</span><br><span class="line"> path('',views.index),</span><br><span class="line"> path('add_to_cart/<int:id>',views.add_to_cart),</span><br><span class="line"> path('show_cart',views.show_cart),</span><br><span class="line"> path('admin/', admin.site.urls),</span><br><span class="line">]</span><br></pre></td></tr></table></figure><h6 id="9写视图"><a href="#9写视图" class="headerlink" title="9写视图"></a>9写视图</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">from django.shortcuts import render</span><br><span class="line"></span><br><span class="line">def index(request):</span><br><span class="line"> pass</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">def add_to_cart(request):</span><br><span class="line"> pass</span><br><span class="line"></span><br><span class="line">def show_cart(request):</span><br><span class="line"> pass</span><br></pre></td></tr></table></figure><h6 id="10-建立models"><a href="#10-建立models" class="headerlink" title="10 建立models"></a>10 建立models</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">from django.db import models</span><br><span class="line"></span><br><span class="line">class Goods(models.Model):</span><br><span class="line"> """商品模型类"""</span><br><span class="line"> id = models.AutoField(primary_key=True,db_column='gid')</span><br><span class="line"> name = models.CharField(max_length=50,db_column='gname')</span><br><span class="line"> price = models.DecimalField(max_digits=10,decimal_places=2,db_column='gprice')</span><br><span class="line"> image = models.CharField(max_length=255,db_column='gimage')</span><br><span class="line"> class Meta:</span><br><span class="line"></span><br><span class="line"> db_table = 'tb_goods'</span><br><span class="line"> ordering = ('id',)</span><br></pre></td></tr></table></figure><h6 id="11迁移"><a href="#11迁移" class="headerlink" title="11迁移"></a>11迁移</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">python manage.py makemigrations cart </span><br><span class="line">python manage.py migrate</span><br></pre></td></tr></table></figure><h6 id="12注册后台管理员账户"><a href="#12注册后台管理员账户" class="headerlink" title="12注册后台管理员账户"></a>12注册后台管理员账户</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">例如:</span><br><span class="line">from django.contrib import admin</span><br><span class="line"></span><br><span class="line">from cart.models import Goods</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">class GoodsAdmin(admin.ModelAdmin):</span><br><span class="line"> list_display = ('id','name','price','image')</span><br><span class="line"> search_fields = ('name',)</span><br><span class="line"> </span><br><span class="line">admin.site.register(Goods,GoodsAdmin)</span><br></pre></td></tr></table></figure><h6 id="13-GUANLIY"><a href="#13-GUANLIY" class="headerlink" title="13:GUANLIY"></a>13:GUANLIY</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">(venv) lizhonglindeMacBook-Pro:shop lizhonglin$ python manage.py createsuperuser </span><br><span class="line">Username (leave blank to use 'lizhonglin'): admin</span><br><span class="line">Email address: [email protected]</span><br><span class="line">Password: </span><br><span class="line">Password (again): </span><br><span class="line">Superuser created successfully.</span><br><span class="line">(venv) lizhonglindeMacBook-Pro:shop lizhonglin$</span><br></pre></td></tr></table></figure><h6 id="14进入管理员界面查看数据"><a href="#14进入管理员界面查看数据" class="headerlink" title="14进入管理员界面查看数据"></a>14进入管理员界面查看数据</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">可以插入数据</span><br></pre></td></tr></table></figure><h6 id="15配置url"><a href="#15配置url" class="headerlink" title="15配置url"></a>15配置url</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">配置首页</span><br><span class="line">def index(request):</span><br><span class="line"> good_list = list(Goods.objects.all())</span><br><span class="line"> return render(request,'goods.html',{'goods_list':good_list})</span><br></pre></td></tr></table></figure><h6 id="16开始在视图中定制自己的功能"><a href="#16开始在视图中定制自己的功能" class="headerlink" title="16开始在视图中定制自己的功能"></a>16开始在视图中定制自己的功能</h6>]]></content>
<tags>
<tag> cookie与session </tag>
</tags>
</entry>
<entry>
<title>Web框架Django(一)</title>
<link href="/2018/05/25/Web%E6%A1%86%E6%9E%B6Django-%E4%B8%80/"/>
<url>/2018/05/25/Web%E6%A1%86%E6%9E%B6Django-%E4%B8%80/</url>
<content type="html"><![CDATA[<h4 id="Web应用框架"><a href="#Web应用框架" class="headerlink" title="Web应用框架"></a>Web应用框架</h4><hr><p>Web应用框架(Web application framework)是一种开发框架,用来支持动态网站、网络应用程序及<a href="https://baike.baidu.com/item/%E7%BD%91%E7%BB%9C%E6%9C%8D%E5%8A%A1" target="_blank" rel="noopener">网络服务</a>的开发。其类型有基于请求的和基于组件的两种框架</p><h6 id="常见的框架有"><a href="#常见的框架有" class="headerlink" title="常见的框架有"></a>常见的框架有</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">FlaskDjangoTornadoPyramidBottleWeb2pyweb.py</span><br></pre></td></tr></table></figure><h6 id="mvc架构"><a href="#mvc架构" class="headerlink" title="mvc架构"></a>mvc架构</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">-- model</span><br><span class="line">-- controller</span><br><span class="line">-- view</span><br><span class="line">数据和数据的解耦合</span><br><span class="line"></span><br><span class="line">MVC:模型-视图-控制器</span><br><span class="line">目标:模型(数据)和视图(显示)解耦合</span><br></pre></td></tr></table></figure><p><img src="/2018/05/25/Web框架Django-一/Users/lizhonglin/Library/Containers/com.tencent.qq/Data/Library/Caches/Images/E9A163A7E421E04FD77B1807356B447F.jpg" alt="9A163A7E421E04FD77B1807356B447"></p><p>通过控制器,将数据和显示分离,好处是同一个视图可以加载不同的模型,同一个模型也可以显示成不同的视图</p><p>稍具规模的系统都会使用MVC架构或者它的变体(MVP、MVVM等)</p><p>它是对面向对象设计原则中迪米特法则的一个最好的践行</p><h6 id="python中的的模式"><a href="#python中的的模式" class="headerlink" title="python中的的模式"></a>python中的的模式</h6><p><img src="/2018/05/25/Web框架Django-一/Users/lizhonglin/Library/Containers/com.tencent.qq/Data/Library/Caches/Images/5CAC360BC60D562BC3E621664BF9ABBB.jpg" alt="CAC360BC60D562BC3E621664BF9ABB"></p><h5 id="Windows中django操作"><a href="#Windows中django操作" class="headerlink" title="Windows中django操作"></a>Windows中django操作</h5><h6 id="1,检查python的版本"><a href="#1,检查python的版本" class="headerlink" title="1,检查python的版本"></a>1,检查python的版本</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">python --version</span><br><span class="line">python --version</span><br></pre></td></tr></table></figure><h6 id="2,创建虚拟环境"><a href="#2,创建虚拟环境" class="headerlink" title="2,创建虚拟环境"></a>2,创建虚拟环境</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python -m venv hello_django_venv</span><br></pre></td></tr></table></figure><h6 id="3-进入文件夹"><a href="#3-进入文件夹" class="headerlink" title="3, 进入文件夹"></a>3, 进入文件夹</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">cd hello_django_venv</span><br><span class="line">激活虚拟环境</span><br><span class="line">cd srcipts </span><br><span class="line">deactivate (不激活)</span><br></pre></td></tr></table></figure><h6 id="4-安装django框架"><a href="#4-安装django框架" class="headerlink" title="4, 安装django框架"></a>4, 安装django框架</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install django 版本(指定版本就加上) {==1.11 (==指定版本)}</span><br></pre></td></tr></table></figure><h6 id="5-检查django的版本"><a href="#5-检查django的版本" class="headerlink" title="5,检查django的版本"></a>5,检查django的版本</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">django-admin --version</span><br></pre></td></tr></table></figure><h6 id="6-创建项目"><a href="#6-创建项目" class="headerlink" title="6, 创建项目"></a>6, 创建项目</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">django-admin startproject hello_django</span><br></pre></td></tr></table></figure><h6 id="7-进入项目目录"><a href="#7-进入项目目录" class="headerlink" title="7,进入项目目录"></a>7,进入项目目录</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python manage.py runserver 启动服务</span><br></pre></td></tr></table></figure><h5 id="Macos-linux下面创建django虚拟环境"><a href="#Macos-linux下面创建django虚拟环境" class="headerlink" title="Macos\linux下面创建django虚拟环境"></a>Macos\linux下面创建django虚拟环境</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">1,mkdir hello_django 创建项目目录</span><br><span class="line">2,cd hello_django/ 切换到项目目录</span><br><span class="line">3,python3 -m venv hd_venv 使用venv模块创建虚拟环境,目录名hd_venv</span><br><span class="line">4,source hd_venv/bin/activate 激活虚拟环境 </span><br><span class="line">5,python -m pip install --upgrade pip 更新pip到最新版本</span><br><span class="line">6,pip install django 使用pip安装django</span><br><span class="line">7,django-admin --version 通过安装django时安装的脚本工具django-admin检查django版本</span><br><span class="line">8,在虚拟环境下面创建项目</span><br><span class="line">django-admin startproject hello_django</span><br><span class="line">9,启动服务</span><br><span class="line">python manage.py runserver 启动服务</span><br><span class="line"> ctrl+c 停服务</span><br><span class="line"> </span><br><span class="line">10,建应用</span><br><span class="line"> python manage.py startapp hrs</span><br><span class="line"> </span><br><span class="line">11,注册功能</span><br><span class="line"># 下面的列表容器表示项目中安装了哪些应用</span><br><span class="line">INSTALLED_APPS = [</span><br><span class="line"> 'django.contrib.admin',</span><br><span class="line"> 'django.contrib.auth',</span><br><span class="line"> 'django.contrib.contenttypes',</span><br><span class="line"> 'django.contrib.sessions',</span><br><span class="line"> 'django.contrib.messages',</span><br><span class="line"> 'django.contrib.staticfiles',</span><br><span class="line"> 'hrs',</span><br><span class="line"> 'crms',</span><br><span class="line"> 'sysms',</span><br><span class="line">]</span><br><span class="line">12,修改view.py文件</span><br><span class="line">13,配置urls.py</span><br></pre></td></tr></table></figure><h6 id="配置文件"><a href="#配置文件" class="headerlink" title="配置文件"></a>配置文件</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">#国际化</span><br><span class="line">USE_I18N = True</span><br><span class="line">#本地化</span><br><span class="line">USE_L10N = True</span><br><span class="line"></span><br><span class="line">USE_TZ = True</span><br><span class="line"></span><br><span class="line">#保证存储到数据库中的是 UTC 时间;</span><br><span class="line">#在函数之间传递时间参数时,确保时间已经转换成 UTC 时间;</span><br></pre></td></tr></table></figure><h6 id="查看你已经更改了那个配置项"><a href="#查看你已经更改了那个配置项" class="headerlink" title="查看你已经更改了那个配置项"></a>查看你已经更改了那个配置项</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python manage.py diffsettings</span><br></pre></td></tr></table></figure><h6 id="配置网站静态资源"><a href="#配置网站静态资源" class="headerlink" title="配置网站静态资源"></a>配置网站静态资源</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">STATIC_URL = '/static/' 配置静态资源</span><br><span class="line"></span><br><span class="line">{% load static %} 加载静态资源</span><br><span class="line"></span><br><span class="line">原文:https://docs.djangoproject.com/en/2.0/howto/static-files/</span><br></pre></td></tr></table></figure><h6 id="连接数据库"><a href="#连接数据库" class="headerlink" title="连接数据库"></a>连接数据库</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">1,配置数据库</span><br><span class="line">DATABASES = {</span><br><span class="line"> 'default': {</span><br><span class="line"> 'ENGINE': 'django.db.backends.mysql',</span><br><span class="line"> 'NAME': 'oa',</span><br><span class="line"> 'HOST':'localhost',</span><br><span class="line"> 'PORT': '3306',</span><br><span class="line"> 'USER': 'root',</span><br><span class="line"> 'PASSWORD': '123456'</span><br><span class="line"> </span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">2,安装依赖库</span><br><span class="line">pip install pymysql</span><br><span class="line"></span><br><span class="line">3,配置__init__</span><br></pre></td></tr></table></figure><p><img src="/2018/05/25/Web框架Django-一/var/folders/v9/jcddlqfx4tg9c57c6xvt8gyr0000gn/T/abnerworks.Typora/image-201805221001203.png" alt="mage-20180522100120"></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">4.执行</span><br><span class="line">python manage.py migrate 迁移工具 (可以自动建表)</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">生成迁移</span><br><span class="line">python manage.py makemigrations hrs </span><br><span class="line"></span><br><span class="line">执行迁移</span><br><span class="line">python manage.py migrate</span><br></pre></td></tr></table></figure><blockquote><p>两个一对多 取代多对多</p></blockquote><h6 id="创建Django超级管理员"><a href="#创建Django超级管理员" class="headerlink" title="创建Django超级管理员"></a>创建Django超级管理员</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">^C(venv) lizhonglindeMacBook-Pro:oa lizhonglin$ python manage.py createsuperuser </span><br><span class="line">Username (leave blank to use 'lizhonglin'): admin</span><br><span class="line">Email address: [email protected]</span><br><span class="line">Password: </span><br><span class="line">Password (again): </span><br><span class="line">This password is too short. It must contain at least 8 characters.</span><br><span class="line">This password is too common.</span><br><span class="line">This password is entirely numeric.</span><br><span class="line">Password: </span><br><span class="line">Password (again): </span><br><span class="line">Superuser created successfully.</span><br><span class="line">(venv) lizhonglindeMacBook-Pro:oa lizhonglin$</span><br></pre></td></tr></table></figure><h6 id="注册admin-py"><a href="#注册admin-py" class="headerlink" title="注册admin.py"></a>注册admin.py</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">例如:</span><br><span class="line">from django.contrib import admin</span><br><span class="line"></span><br><span class="line">from cart.models import Goods</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">class GoodsAdmin(admin.ModelAdmin):</span><br><span class="line"> list_display = ('id','name','price','image')</span><br><span class="line"> search_fields = ('name',)</span><br><span class="line"> </span><br><span class="line">admin.site.register(Goods,GoodsAdmin)</span><br></pre></td></tr></table></figure><h6 id="项目中的shell"><a href="#项目中的shell" class="headerlink" title="项目中的shell"></a>项目中的shell</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python manage.py shell</span><br></pre></td></tr></table></figure><h6 id="增-删-改-查"><a href="#增-删-改-查" class="headerlink" title="增 删 改 查"></a>增 删 改 查</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">创建一个部门</span><br><span class="line">dept = Dept(no='90',name='研发二部',location='武汉')</span><br><span class="line"></span><br><span class="line">获取一个部门</span><br><span class="line">Dept.object.get(pk=20) 获取一个</span><br><span class="line"></span><br><span class="line">获取所有</span><br><span class="line">Dept.object.all()</span><br><span class="line"></span><br><span class="line">保存</span><br><span class="line">dept.save() </span><br><span class="line"></span><br><span class="line">删除</span><br><span class="line">dept.delect()</span><br></pre></td></tr></table></figure><p>表格 :</p><table><thead><tr><th>no</th><th>name</th><th>location</th></tr></thead><tbody><tr><td>10</td><td>技术二部</td><td>武汉</td></tr><tr><td>20</td><td>行政部</td><td>成都</td></tr><tr><td>30</td><td>销售部</td><td>重庆</td></tr><tr><td>40</td><td>综合部</td><td>成都</td></tr><tr><td>60</td><td>网络部</td><td>成都</td></tr><tr><td></td><td></td></tr></tbody></table><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line">python manage.py shell </span><br><span class="line"></span><br><span class="line">精确查询某个部门</span><br><span class="line">Dept.objects.filter(name='行政部')</span><br><span class="line"></span><br><span class="line">模糊查询</span><br><span class="line">>>> Dept.objects.filter(name__contains='网')</span><br><span class="line"><QuerySet [<Dept: 网络部>]></span><br><span class="line">>>> </span><br><span class="line"></span><br><span class="line">忽略大小写模糊查询</span><br><span class="line">>>> Dept.objects.filter(name__icontains='网')</span><br><span class="line"></span><br><span class="line">查询大于30的部门</span><br><span class="line">>>> Dept.objects.filter(no__gt=30)</span><br><span class="line"><QuerySet [<Dept: 综合部>, <Dept: 网络部>]></span><br><span class="line"></span><br><span class="line">查询到大于等于30的部门</span><br><span class="line">>>> Dept.objects.filter(no__gte=30)</span><br><span class="line"><QuerySet [<Dept: 销售部>, <Dept: 综合部>, <Dept: 网络部>]></span><br><span class="line"></span><br><span class="line">倒叙查询所有</span><br><span class="line">>>> Dept.objects.all().order_by('-no')</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">切片查询</span><br><span class="line">>>> Dept.objects.all().order_by('no')[0:3]</span><br><span class="line"><QuerySet [<Dept: 技术二部>, <Dept: 行政部>, <Dept: 销售部>]></span><br><span class="line">>>> </span><br><span class="line"></span><br><span class="line">原始查询</span><br><span class="line">>>> Dept.objects.raw('select name from tb_dept')</span><br><span class="line"><RawQuerySet: select name from tb_dept></span><br><span class="line"></span><br><span class="line">查询小于30的部门</span><br><span class="line">>>> Dept.objects.filter(no__lt=30)</span><br><span class="line"><QuerySet [<Dept: 技术二部>, <Dept: 行政部>]></span><br><span class="line">>>> </span><br><span class="line"></span><br><span class="line">删除部门</span><br><span class="line">>>> Dept.object.get(pk=30).delect()</span><br></pre></td></tr></table></figure><h6 id="django配置日志"><a href="#django配置日志" class="headerlink" title="django配置日志"></a>django配置日志</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">#配置日志输出到控制台</span><br><span class="line"></span><br><span class="line">LOGGING = {</span><br><span class="line"> 'version': 1,</span><br><span class="line"> 'disable_existing_loggers': False,</span><br><span class="line"> 'handlers': {</span><br><span class="line"> 'console': {</span><br><span class="line"> 'class': 'logging.StreamHandler',</span><br><span class="line"> },</span><br><span class="line"> },</span><br><span class="line"> 'loggers': {</span><br><span class="line"> 'django': {</span><br><span class="line"> 'handlers': ['console'],</span><br><span class="line"> 'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG'),</span><br><span class="line"> },</span><br><span class="line"> },</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h6 id="request"><a href="#request" class="headerlink" title="request"></a>request</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">request.META 获取请求头的东西和本机的东西</span><br><span class="line">request.POST</span><br><span class="line">request.GET 获取使用GET请求的参数</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">查询这个部门的所有员工</span><br><span class="line"></span><br><span class="line">1, Emp.objects.filter(dept__no=no) </span><br><span class="line"></span><br><span class="line">反向查询</span><br><span class="line">先查询部门在查部门的员工 建表的时候可以加在ForeignKey中related_name </span><br><span class="line">related_name="+" 阻止反向查询</span><br><span class="line">2, Dept.object.filter(no=no).emp_set.all() </span><br><span class="line"></span><br><span class="line">3 .select_related('dept')</span><br></pre></td></tr></table></figure><h6 id="QuerySet知识点"><a href="#QuerySet知识点" class="headerlink" title="QuerySet知识点"></a>QuerySet知识点</h6><p>QuerySet 使用的是惰性查询 ===如果不是非要取数据的时候就不会去取数据,要用到数据的时候才会去取数据.这样做是为了节省服务器的内存开销(延迟开销) 节省空间的—消耗时间</p><p>数据量大的时候先:筛选—排序—切片 .select_related</p><blockquote><p>写程序要尽量避免硬代码\硬编码</p></blockquote><h6 id="配置URL"><a href="#配置URL" class="headerlink" title="配置URL"></a>配置URL</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">django1.x版本</span><br><span class="line">命名捕获组 URL('emps/(?P<NAME>[0-9]+)',views.emps</span><br><span class="line"></span><br><span class="line">diango2.x版本</span><br><span class="line">path('emps/<int:no>',views.emps,name='empsindept'),</span><br></pre></td></tr></table></figure><hr><h5 id="未完待续………"><a href="#未完待续………" class="headerlink" title="未完待续……….."></a>未完待续………..</h5><hr>]]></content>
<tags>
<tag> Django学习笔记(一) </tag>
</tags>
</entry>
<entry>
<title>CentOS学习笔记</title>
<link href="/2018/05/25/CentOS%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<url>/2018/05/25/CentOS%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</url>
<content type="html"><![CDATA[<h3 id="CentOS笔记"><a href="#CentOS笔记" class="headerlink" title="CentOS笔记"></a>CentOS笔记</h3><p>CentOS(Community Enterprise Operating System,中文意思是:社区企业操作系统)是Linux发行版之一,它是来自于Red Hat Enterprise Linux依照<a href="https://baike.baidu.com/item/%E5%BC%80%E6%94%BE%E6%BA%90%E4%BB%A3%E7%A0%81" target="_blank" rel="noopener">开放源代码</a>规定释出的源代码所编译而成。由于出自同样的<a href="https://baike.baidu.com/item/%E6%BA%90%E4%BB%A3%E7%A0%81" target="_blank" rel="noopener">源代码</a>,因此有些要求高度稳定性的<a href="https://baike.baidu.com/item/%E6%9C%8D%E5%8A%A1%E5%99%A8" target="_blank" rel="noopener">服务器</a>以CentOS替代商业版的<a href="https://baike.baidu.com/item/Red%20Hat" target="_blank" rel="noopener">Red Hat</a> Enterprise Linux使用。两者的不同,在于CentOS并不包含封闭源代码软件。</p><hr><p><<计算机文化>> —学习计算机基础概念</p><hr><h5 id="Linux发行版本"><a href="#Linux发行版本" class="headerlink" title="Linux发行版本"></a>Linux发行版本</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Redhat Linux </span><br><span class="line">Ubuntu</span><br><span class="line">CentOS</span><br></pre></td></tr></table></figure><h5 id="macOS软件连接"><a href="#macOS软件连接" class="headerlink" title="macOS软件连接"></a>macOS软件连接</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">mac</span><br><span class="line">http://xclient.info/?t=cf45be83ba9e7cbc54b5a457f912356b56190ed7</span><br></pre></td></tr></table></figure><h5 id="阿里云远程登录报错解决办法"><a href="#阿里云远程登录报错解决办法" class="headerlink" title="阿里云远程登录报错解决办法"></a>阿里云远程登录报错解决办法</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@</span><br><span class="line">@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @</span><br><span class="line">@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@</span><br><span class="line">IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!</span><br><span class="line">Someone could be eavesdropping on you right now (man-in-the-middle attack)!</span><br><span class="line">It is also possible that a host key has just been changed.</span><br><span class="line">The fingerprint for the RSA key sent by the remote host is</span><br><span class="line">SHA256:37dpXib6L1tiX7BJUdo+oYFQLlGCllIjWo9n/czvRH8.</span><br><span class="line">Please contact your system administrator.</span><br><span class="line">Add correct host key in /Users/lizhonglin/.ssh/known_hosts to get rid of this message.</span><br><span class="line">Offending RSA key in /Users/lizhonglin/.ssh/known_hosts:2</span><br><span class="line">RSA host key for 47.104.85.246 has changed and you have requested strict checking.</span><br><span class="line">Host key verification failed.</span><br><span class="line"></span><br><span class="line">[进程已完成]</span><br></pre></td></tr></table></figure><blockquote><p>解决方法:</p><p>vi ~/.ssh/known_hosts 在本地机器删除对应的密钥信息</p><p>方法一:<br>rm -rf ~/.ssh/known_hosts</p><hr><p>优点:干净利索<br>缺点:把其他正确的公钥信息也删除,下次链接要全部重新经过认证</p><p>方法二:<br>vi ~/.ssh/known_hosts<br>删除对应ip的相关rsa信息(本例可知删除53行信息即可)</p><hr><p>优点:其他正确的公钥信息保留<br>缺点:还要vi,还要找到对应信息,稍微优点繁琐</p><p>方法三:<br>清除旧的公钥信息<br>ssh-keygen -R 192.168.0.100</p><hr><p>优点:快、稳、狠<br>缺点:没有缺点</p></blockquote><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">ssh登陆出现警告:</span><br><span class="line">ssh登录,permission denied(publickey.gssapi-with-mic)</span><br><span class="line">用ssh登录Linux,出现permission denied(publickey.gssapi-with-mic.password)错误。</span><br><span class="line">解决方法:</span><br><span class="line">修改/etc/ssh/sshd_config文件,PasswordAuthentication no修改为yes</span><br></pre></td></tr></table></figure><h5 id="命令"><a href="#命令" class="headerlink" title="命令"></a>命令</h5><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line">www.kernel.org linux 内核下载地址 -->参考-- minix(教学) </span><br><span class="line">who /w 查询哪些用户登录呢系统/ 显示跟详细</span><br><span class="line">clear清屏</span><br><span class="line">ps 查看shell版本</span><br><span class="line"></span><br><span class="line">adduser 用户名 创建用户</span><br><span class="line">passwd 用户名 创建用户密码 (如果直接回车改当前用户密码/跟上用户名是修改用户名的密码)</span><br><span class="line"></span><br><span class="line">whoami /who am i 查看自己是谁</span><br><span class="line"></span><br><span class="line">logout /exit 登出账户</span><br><span class="line"></span><br><span class="line">shutdown /init 0 关闭服务器</span><br><span class="line">reboot /init 6 重启服务器</span><br><span class="line"></span><br><span class="line">uname 查看自己用的什么系统</span><br><span class="line">hostname 查看主机名</span><br><span class="line">userdel 删除用户</span><br><span class="line">wall 警告</span><br><span class="line">敲两下tab键 可以查看当前能使用过的命令数</span><br><span class="line"></span><br><span class="line">man /info(更详细更专业) 查看命名的使用手册 (按q退出 按h是帮助)</span><br><span class="line">pass --help 获取命令帮助信息</span><br><span class="line">显示太长可以加上| 例如:pass --help |less </span><br><span class="line">whatis passwd 获取简短帮助</span><br><span class="line">which python 查找命令在哪里</span><br><span class="line">whereis python 查找命令在哪里</span><br><span class="line"></span><br><span class="line">pwd 显示当前的目录路径</span><br><span class="line"></span><br><span class="line">查看历史命令 history 使用!编号就可以调取</span><br><span class="line">echo 回声命令 </span><br><span class="line">echo $HISTSIZE 查看系统输入的命令历史记录</span><br><span class="line">sodu 以管理员权限做某些事情</span><br><span class="line">ssh 用户名@ip </span><br><span class="line">scp 安全拷贝</span><br></pre></td></tr></table></figure><h5 id="实用命令"><a href="#实用命令" class="headerlink" title="实用命令"></a>实用命令</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">su 切换用户</span><br><span class="line">etc 配置目录</span><br><span class="line">usr 用户目录</span><br><span class="line">home 用户家目录</span><br></pre></td></tr></table></figure><h5 id="操作文件和文件夹"><a href="#操作文件和文件夹" class="headerlink" title="操作文件和文件夹"></a>操作文件和文件夹</h5><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">touch 创建文件 (如果文件存在会修改文件的最后访问时间)</span><br><span class="line">ls -l 查看长格式</span><br><span class="line">ls -a 查看所有文件</span><br><span class="line">ls 列出所有文件</span><br><span class="line">ls -la 长格式查看全部文件</span><br><span class="line">ls -r 反转顺序</span><br><span class="line">ls -R 递归显示目录</span><br><span class="line"></span><br><span class="line">cd abc/foo</span><br><span class="line">cd ../..</span><br><span class="line">cd ~</span><br><span class="line">rm remove 既可以删文件又可以删除文件</span><br><span class="line">rm -rf / 慎用</span><br></pre></td></tr></table></figure><h5 id="常用操作命令"><a href="#常用操作命令" class="headerlink" title="常用操作命令"></a>常用操作命令</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">history 可以查看当天的历史命令(使用!编号就可以把命令在执行一遍)</span><br><span class="line">cp ----copy 复制文件</span><br><span class="line">mv ---move 剪切移动</span><br><span class="line">cat /head/tail 查看文件内容</span><br><span class="line">cat index.html | more/less 分页查看文件内容</span><br><span class="line">head -5 index.html 查看5行内容</span><br><span class="line">tail -2 index.html 查看最后2两行</span><br><span class="line">cat index.html | grep '<div>' 查询文件中指定的内容</span><br><span class="line">grep '<div>' index.html 也可以这样搜索</span><br><span class="line">grep '<div>' index.html -n 查询多少行有这个对应的数据</span><br><span class="line">grep '<div>' / -R -n & 让命令在后台执行</span><br><span class="line">grep '<div>' / -R -n > result.txt & 命令在后台执行 并且重新执行</span><br><span class="line">grep '<div>' / -R -n > result.txt 2> error.txt & 错误重定向</span><br><span class="line">& 在后台执行</span><br><span class="line"></span><br><span class="line">>是输出重定向</span><br><span class="line">2> 执行命令错误了 在行另外一个文件</span><br><span class="line">>> 追加输出重定向</span><br><span class="line">输入重定向用<</span><br><span class="line"></span><br><span class="line">jobs 可以查看后台有没有任务在执行</span><br><span class="line">fg %1把任务拿前台来执行</span><br><span class="line">bg %1 在次把任务拿到后台执行</span><br><span class="line">top 查看cpu的占用率</span><br><span class="line">grep 搜文件内容中 </span><br><span class="line">wc 数行数和单词数</span><br><span class="line">uniq 去掉相邻的重复的内容</span><br><span class="line">sort 对内容排序(返回修改后的列表,不改变文件的内容)</span><br><span class="line">diff 版本比较两个文件的内容</span><br><span class="line">file 分析文件的性质(根据文件里面数据的特征值来分析)</span><br><span class="line"></span><br><span class="line">find 查找文件 </span><br><span class="line">ctrl+c 终止一个命令的执行</span><br></pre></td></tr></table></figure><h5 id="远程拷贝文件"><a href="#远程拷贝文件" class="headerlink" title="远程拷贝文件"></a>远程拷贝文件</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">ssh 用户名@ip </span><br><span class="line"></span><br><span class="line">scp he [email protected]:/home/hellokitty/</span><br><span class="line"></span><br><span class="line">CentOS:</span><br><span class="line">cat /etc/centos-release 查看操作系统版本</span><br><span class="line">[root@izm5eifctth7468z9e6fz0z ~]# cat /etc/centos-release</span><br><span class="line">CentOS Linux release 7.4.1708 (Core)</span><br><span class="line">[root@izm5eifctth7468z9e6fz0z ~]#</span><br></pre></td></tr></table></figure><h5 id="创建硬链接-软链接"><a href="#创建硬链接-软链接" class="headerlink" title="创建硬链接/软链接"></a>创建硬链接/软链接</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">ln filename 目录 创建硬链接</span><br><span class="line"></span><br><span class="line">ln -s /etc/e.txt filename 创建软连接相当于windows下面的快捷方式.</span><br><span class="line">ln -s ~/guess.py /usr/bin/guess 创建软链接</span><br></pre></td></tr></table></figure><h5 id="redis下载地址"><a href="#redis下载地址" class="headerlink" title="redis下载地址"></a>redis下载地址</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">redis.io</span><br><span class="line">http://download.redis.io/releases/redis-3.2.11.tar.gz</span><br></pre></td></tr></table></figure><h5 id="下载文件的压缩-解压缩-归档-解归档"><a href="#下载文件的压缩-解压缩-归档-解归档" class="headerlink" title="下载文件的压缩/解压缩/归档/解归档"></a>下载文件的压缩/解压缩/归档/解归档</h5><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">解压缩</span><br><span class="line"></span><br><span class="line">后缀为gz的</span><br><span class="line">gzip 文件 压缩</span><br><span class="line">gunzip 文件名 解压文件 -v 可以看见详细的解压过程</span><br><span class="line"></span><br><span class="line">后缀为xz的</span><br><span class="line">xz -z</span><br><span class="line">xz -d</span><br><span class="line">xz -z -9 压缩比</span><br><span class="line"></span><br><span class="line">解归档</span><br><span class="line">[root@izm5eifctth7468z9e6fz0z ~]# tar -xvf redis-3.2.11.tar</span><br><span class="line"></span><br><span class="line">归档</span><br><span class="line">tar -cvf all.tar * *表示归档当前目录所有文件</span><br><span class="line">tar -xvf all.tar 解归档</span><br></pre></td></tr></table></figure><h5 id="别名-和-反别名"><a href="#别名-和-反别名" class="headerlink" title="别名 和 反别名"></a>别名 和 反别名</h5><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">alias ll= 'ls -l' 定制别名</span><br><span class="line"></span><br><span class="line">unalias ll 反别名</span><br></pre></td></tr></table></figure><h5 id="vim使用"><a href="#vim使用" class="headerlink" title="vim使用"></a>vim使用</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">syntax off 关闭高亮语法</span><br><span class="line">syntax no 开启</span><br><span class="line">set ts = 4 设置tap键 为4个空格</span><br><span class="line">修改vim配置文件:</span><br><span class="line">[root@izm5eifctth7468z9e6fz0z ~]# vim .vimrc</span><br><span class="line"></span><br><span class="line">!v 可以打开刚才执行过以v开头的在执行一遍</span><br><span class="line">ming</span><br><span class="line"></span><br><span class="line">在末行模式下面要执行系统命令可以</span><br><span class="line">! 命令</span><br><span class="line">要回vim 按回车</span><br><span class="line"></span><br><span class="line">在末行模式:</span><br><span class="line">:inoremap pymain if __name__ == '__main__': </span><br><span class="line"></span><br><span class="line">命令模式输入</span><br><span class="line">/ 可以做搜索 n 向下搜索 N向上搜索</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">排版</span><br><span class="line">.center() 字符串居中</span><br><span class="line">rjust() 右对齐</span><br><span class="line">ljust() 左对齐</span><br></pre></td></tr></table></figure><h5 id="修改文件权限"><a href="#修改文件权限" class="headerlink" title="修改文件权限"></a>修改文件权限</h5><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">chmod u+x,g+x,O+x 文件 修改文件的权限</span><br><span class="line">chomd 777 读写执行</span><br><span class="line"> 744 只读</span><br><span class="line"> 766 读写</span><br><span class="line"> 555 读执行</span><br></pre></td></tr></table></figure><h5 id="升级python3"><a href="#升级python3" class="headerlink" title="升级python3"></a>升级python3</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">原文地址:https://blog.csdn.net/jackfrued/article/details/79380979</span><br><span class="line"></span><br><span class="line">1.wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tar.xz</span><br><span class="line">2.xz -d Python-3.6.5.tar.xz</span><br><span class="line">3.tar -xvf Python-3.6.5.tar</span><br><span class="line">**4.yum install gcc</span><br><span class="line">5.cd Python-3.6.5</span><br><span class="line">6. ./configure --prefix=/usr/local/python36 --enable-optimizations</span><br><span class="line">7. 编译:make && make install (&&表示执行完前面的命令在执行后面的) 这步错了执行以下</span><br><span class="line">yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel</span><br><span class="line"></span><br><span class="line">8. ln -s /usr/local/python3.6/bin/python3 /usr/bin/python3</span><br></pre></td></tr></table></figure><h6 id="预习"><a href="#预习" class="headerlink" title="预习"></a>预习</h6><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">NginX Web服务器</span><br><span class="line">MySQL 关系型数据库 -持久化</span><br><span class="line">Redis 非关系型数据库</span><br><span class="line"></span><br><span class="line">防火墙 iptables/firewall</span><br><span class="line"></span><br><span class="line">[] -第二大的元素找出来</span><br><span class="line">['','',''] -重复次数排前三的找出来</span><br></pre></td></tr></table></figure><h6 id="pip"><a href="#pip" class="headerlink" title="pip"></a>pip</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">pip3 install pycodestyle python代码规范检查</span><br><span class="line"></span><br><span class="line">升级pip:</span><br><span class="line"> [root@izm5eifctth7468z9e6fz0z ~]# pip3 install --upgrade pip</span><br><span class="line"> </span><br><span class="line"> jupyter notebook</span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"> sys.argv python接收系统传给的参数包括系统本身</span><br></pre></td></tr></table></figure><h4 id="linux-安装软件"><a href="#linux-安装软件" class="headerlink" title="linux 安装软件"></a>linux 安装软件</h4><h6 id="包管理工具"><a href="#包管理工具" class="headerlink" title="包管理工具"></a>包管理工具</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">yum yellowdog updater modified</span><br><span class="line">rpm redhat package manager</span><br></pre></td></tr></table></figure><h6 id="yum的使用"><a href="#yum的使用" class="headerlink" title="yum的使用"></a>yum的使用</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">yum list installed 检查安装了哪些软件</span><br><span class="line"> yum search nginx 看看是否有安装资源</span><br><span class="line"> yum makecache</span><br></pre></td></tr></table></figure><h6 id="常用的web架构"><a href="#常用的web架构" class="headerlink" title="常用的web架构"></a>常用的web架构</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">LAMP = Linux + Apache + MySQL + PHP</span><br><span class="line"> Linux + Nginx + MySQL + Python</span><br></pre></td></tr></table></figure><h6 id="nginx配置"><a href="#nginx配置" class="headerlink" title="nginx配置"></a>nginx配置</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">iptables -L -n 查看端口状态</span><br><span class="line"></span><br><span class="line">nginx:首页位置</span><br><span class="line"> /usr/share/nginx/html.</span><br><span class="line"> </span><br><span class="line">编辑配置文件</span><br><span class="line"> /etc/nginx/nginx.conf.</span><br><span class="line"> </span><br><span class="line">nginx -s stop 停了</span><br><span class="line"></span><br><span class="line">启动</span><br><span class="line">nginx</span><br><span class="line"></span><br><span class="line">Nginx的启动(start),停止(stop)命令</span><br><span class="line">查看Nginx的版本号:nginx -V</span><br><span class="line"></span><br><span class="line">启动Nginx:start nginx</span><br><span class="line"></span><br><span class="line">快速停止或关闭Nginx:nginx -s stop</span><br><span class="line"></span><br><span class="line">正常停止或关闭Nginx:nginx -s quit</span><br></pre></td></tr></table></figure><h6 id="sftp操作"><a href="#sftp操作" class="headerlink" title="sftp操作"></a>sftp操作</h6><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line">命令:sftp root@ip </span><br><span class="line"></span><br><span class="line">lizhonglindeMacBook-Pro:~ lizhonglin$ sftp [email protected] </span><br><span class="line">[email protected]'s password: </span><br><span class="line">Permission denied, please try again.</span><br><span class="line">[email protected]'s password: </span><br><span class="line">Connected to 47.104.205.141.</span><br><span class="line"><span class="meta">sftp></span><span class="bash"> ls</span></span><br><span class="line">Python-3.6.5 Python-3.6.5.tar abc homework01.py </span><br><span class="line">homework02.py homework03.py homework04.py homewrok03.py </span><br><span class="line">in.html index.html redis-3.2.11 redis-3.2.11.tar </span><br><span class="line">two.py </span><br><span class="line"><span class="meta">sftp></span><span class="bash"> <span class="built_in">cd</span> /usr/share/html</span></span><br><span class="line">Couldn't stat remote file: No such file or directory</span><br><span class="line"><span class="meta">sftp></span><span class="bash"> <span class="built_in">cd</span> /usr/share/nginx/html</span></span><br><span class="line"><span class="meta">sftp></span><span class="bash"> ls</span></span><br><span class="line">404.html 50x.html index.html nginx-logo.png poweredby.png </span><br><span class="line"><span class="meta">sftp></span><span class="bash"> get 上传</span></span><br><span class="line">put 上传</span><br><span class="line"></span><br><span class="line">查看进程</span><br><span class="line">ps -ef </span><br><span class="line">ps -aux </span><br><span class="line"></span><br><span class="line">查看网络状态并且能看见进程号</span><br><span class="line">netstat -nap </span><br><span class="line"></span><br><span class="line">杀进程</span><br><span class="line">kill 进程号</span><br><span class="line"></span><br><span class="line">yum配置</span><br><span class="line"> /etc/yum.repos.d/</span><br><span class="line">拷贝其他两个文件</span><br><span class="line"> </span><br><span class="line">修改后用</span><br><span class="line"> yum makecache</span><br></pre></td></tr></table></figure><h6 id="rpm"><a href="#rpm" class="headerlink" title="rpm"></a>rpm</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">rpm -ivh 安装 </span><br><span class="line">rpm -e 移除</span><br><span class="line"></span><br><span class="line">rpm -qa | grep 包 查询软件是否安装过</span><br><span class="line"></span><br><span class="line">rpm -qa | grep jdk | xargs rpm -e 查询后再删除(xargs:前面的搜索结果当成参数使用)</span><br></pre></td></tr></table></figure><h6 id="安装MySQL"><a href="#安装MySQL" class="headerlink" title="安装MySQL"></a>安装MySQL</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">Mariadb:</span><br><span class="line">yum install mariadb-server mariadb 安装服务器和客户端</span><br><span class="line"></span><br><span class="line">systemctl start mariadb 7以下低版本的是 service 服务名 start</span><br><span class="line"> stop 停服务 chkconfig </span><br><span class="line"> restart</span><br><span class="line"> </span><br><span class="line">systemctl status mariadb 查看服务是否启动</span><br><span class="line"></span><br><span class="line">[root@izm5eifctth7468z9e6fz0z ~]# mysql -u root -p 连接mysql</span><br><span class="line"></span><br><span class="line">firewall-cmd --add-port=80/tcp --permanent --zone=public 配置防火墙</span><br><span class="line"></span><br><span class="line">设置开机自启:</span><br><span class="line"></span><br><span class="line">system enable mariadb 开机自启</span><br><span class="line"></span><br><span class="line">system disenble mariadb 取消开机自启</span><br></pre></td></tr></table></figure><h6 id="redis安装"><a href="#redis安装" class="headerlink" title="redis安装"></a>redis安装</h6><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line">解压文件</span><br><span class="line"></span><br><span class="line">make</span><br><span class="line">make install</span><br><span class="line"></span><br><span class="line">redis.conf 先备份到商机目录 原文件不要动</span><br><span class="line"></span><br><span class="line">61行 改成自己的内网地址 </span><br><span class="line"></span><br><span class="line">80行 port 端口号 可以修改或者不该 6379 merz</span><br><span class="line"></span><br><span class="line">480行 require 480 requirepass 密码</span><br><span class="line"></span><br><span class="line">redis-server myredis.conf 启动服务</span><br><span class="line">ctrl+c 结束</span><br><span class="line">kill 进程号 没存盘\</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">在后台运行</span><br><span class="line"></span><br><span class="line">redis-server myredis.conf > myredis.log &</span><br><span class="line"></span><br><span class="line">jobs fg %1 %后台编号</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">[root@izm5eifctth7468z9e6fz0z ~]# redis-server myredis.conf</span><br><span class="line"> _._</span><br><span class="line"> _.-``__ ''-._</span><br><span class="line"> _.-`` `. `_. ''-._ Redis 3.2.11 (00000000/0) 64 bit</span><br><span class="line"> .-`` .-```. ```\/ _.,_ ''-._</span><br><span class="line"> ( ' , .-` | `, ) Running in standalone mode</span><br><span class="line"> |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379</span><br><span class="line"> | `-._ `._ / _.-' | PID: 11259</span><br><span class="line"> `-._ `-._ `-./ _.-' _.-'</span><br><span class="line"> |`-._`-._ `-.__.-' _.-'_.-'|</span><br><span class="line"> | `-._`-._ _.-'_.-' | http://redis.io</span><br><span class="line"> `-._ `-._`-.__.-'_.-' _.-'</span><br><span class="line"> |`-._`-._ `-.__.-' _.-'_.-'|</span><br><span class="line"> | `-._`-._ _.-'_.-' |</span><br><span class="line"> `-._ `-._`-.__.-'_.-' _.-'</span><br><span class="line"> `-._ `-.__.-' _.-'</span><br><span class="line"> `-._ _.-'</span><br><span class="line"> `-.__.-'</span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line">连接服务器:</span><br><span class="line"></span><br><span class="line">[root@izm5eifctth7468z9e6fz0z ~]# redis-cli -h 172.31.219.49 -p 6379</span><br><span class="line"></span><br><span class="line">172.31.219.49:6379> auth 密码</span><br></pre></td></tr></table></figure><h6 id="免安装的软件"><a href="#免安装的软件" class="headerlink" title="免安装的软件"></a>免安装的软件</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">1.export $PATH= 只能一次有效</span><br><span class="line"></span><br><span class="line">2.修改环境变量 .bash_profile</span><br><span class="line">3.修改变量别名 .bashrc</span><br><span class="line"></span><br><span class="line">4.运行:</span><br><span class="line">python3 -m IPython</span><br></pre></td></tr></table></figure><h6 id="firewall-使用方法"><a href="#firewall-使用方法" class="headerlink" title="firewall 使用方法"></a>firewall 使用方法</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br></pre></td><td class="code"><pre><span class="line">centos7下Firewall使用详解</span><br><span class="line">安装它,只需</span><br><span class="line"></span><br><span class="line"># yum install firewalld</span><br><span class="line">如果需要图形界面的话,则再安装</span><br><span class="line"># yum install firewall-config</span><br><span class="line"></span><br><span class="line">一、介绍</span><br><span class="line"></span><br><span class="line">防火墙守护 firewalld 服务引入了一个信任级别的概念来管理与之相关联的连接与接口。它支持 ipv4 与 ipv6,并支持网桥,采用 firewall-cmd (command) 或 firewall-config (gui) 来动态的管理 kernel netfilter 的临时或永久的接口规则,并实时生效而无需重启服务。</span><br><span class="line"></span><br><span class="line">Firewall 能将不同的网络连接归类到不同的信任级别,Zone 提供了以下几个级别</span><br><span class="line"></span><br><span class="line">drop: 丢弃所有进入的包,而不给出任何响应</span><br><span class="line">block: 拒绝所有外部发起的连接,允许内部发起的连接</span><br><span class="line">public: 允许指定的进入连接</span><br><span class="line">external: 同上,对伪装的进入连接,一般用于路由转发</span><br><span class="line">dmz: 允许受限制的进入连接</span><br><span class="line">work: 允许受信任的计算机被限制的进入连接,类似 workgroup</span><br><span class="line">home: 同上,类似 homegroup</span><br><span class="line">internal: 同上,范围针对所有互联网用户</span><br><span class="line">trusted: 信任所有连接</span><br><span class="line"></span><br><span class="line">二、使用方法</span><br><span class="line"></span><br><span class="line"># systemctl start firewalld # 启动,</span><br><span class="line"># systemctl enable firewalld # 开机启动</span><br><span class="line"># systemctl stop firewalld # 关闭</span><br><span class="line"># systemctl disable firewalld # 取消开机启动</span><br><span class="line">具体的规则管理,可以使用 firewall-cmd,具体的使用方法可以</span><br><span class="line"></span><br><span class="line">$ firewall-cmd --help</span><br><span class="line">1. 查看规则</span><br><span class="line"></span><br><span class="line">查看运行状态</span><br><span class="line">$ firewall-cmd --state</span><br><span class="line">查看已被激活的 Zone 信息</span><br><span class="line">$ firewall-cmd --get-active-zones</span><br><span class="line">public</span><br><span class="line">interfaces: eth0 eth1</span><br><span class="line">查看指定接口的 Zone 信息</span><br><span class="line">$ firewall-cmd --get-zone-of-interface=eth0</span><br><span class="line">public</span><br><span class="line">查看指定级别的接口</span><br><span class="line">$ firewall-cmd --zone=public --list-interfaces</span><br><span class="line">eth0</span><br><span class="line">查看指定级别的所有信息,譬如 public</span><br><span class="line">$ firewall-cmd --zone=public --list-all</span><br><span class="line">public (default, active)</span><br><span class="line">interfaces: eth0</span><br><span class="line">sources:</span><br><span class="line">services: dhcpv6-client http ssh</span><br><span class="line">ports:</span><br><span class="line">masquerade: no</span><br><span class="line">forward-ports:</span><br><span class="line">icmp-blocks:</span><br><span class="line">rich rules:</span><br><span class="line">查看所有级别被允许的信息</span><br><span class="line">$ firewall-cmd --get-service</span><br><span class="line">查看重启后所有 Zones 级别中被允许的服务,即永久放行的服务</span><br><span class="line">$ firewall-cmd --get-service --permanent</span><br><span class="line"></span><br><span class="line">2. 管理规则</span><br><span class="line"></span><br><span class="line"># firewall-cmd --panic-on # 丢弃</span><br><span class="line"># firewall-cmd --panic-off # 取消丢弃</span><br><span class="line">$ firewall-cmd --query-panic # 查看丢弃状态</span><br><span class="line"># firewall-cmd --reload # 更新规则,不重启服务</span><br><span class="line"># firewall-cmd --complete-reload # 更新规则,重启服务</span><br><span class="line">添加某接口至某信任等级,譬如添加 eth0 至 public,再永久生效</span><br><span class="line"></span><br><span class="line"># firewall-cmd --zone=public --add-interface=eth0 --permanent</span><br><span class="line">设置 public 为默认的信任级别</span><br><span class="line"></span><br><span class="line"># firewall-cmd --set-default-zone=public</span><br><span class="line">a. 管理端口</span><br><span class="line">列出 dmz 级别的被允许的进入端口</span><br><span class="line"></span><br><span class="line"># firewall-cmd --zome=dmz --list-ports</span><br><span class="line">允许 tcp 端口 8080 至 dmz 级别</span><br><span class="line"></span><br><span class="line"># firewall-cmd --zone=dmz --add-port=8080/tcp</span><br><span class="line">允许某范围的 udp 端口至 public 级别,并永久生效</span><br><span class="line"></span><br><span class="line"># firewall-cmd --zome=public --add-port=5060-5059/udp --permanent</span><br><span class="line">b. 管理服务</span><br><span class="line">添加 smtp 服务至 work zone</span><br><span class="line"></span><br><span class="line"># firewall-cmd --zone=work --add-service=smtp</span><br><span class="line">移除 work zone 中的 smtp 服务</span><br><span class="line"></span><br><span class="line"># firewall-cmd --zone=work --remove-service=smtp</span><br><span class="line">c. 配置 ip 地址伪装</span><br><span class="line">查看</span><br><span class="line"></span><br><span class="line"># firewall-cmd --zone=external --query-masquerade</span><br><span class="line">打开伪装</span><br><span class="line"></span><br><span class="line"># firewall-cmd --zone=external --add-masquerade</span><br><span class="line">关闭伪装</span><br><span class="line"></span><br><span class="line"># firewall-cmd --zone=external --remove-masquerade</span><br><span class="line">d. 端口转发</span><br><span class="line">要打开端口转发,则需要先</span><br><span class="line"></span><br><span class="line"># firewall-cmd --zone=external --add-masquerade</span><br><span class="line">然后转发 tcp 22 端口至 3753</span><br><span class="line"></span><br><span class="line"># firewall-cmd --zone=external --add-forward-port=port=22:proto=tcp:toport=3753</span><br><span class="line">转发 22 端口数据至另一个 ip 的相同端口上</span><br><span class="line"></span><br><span class="line"># firewall-cmd --zone=external --add-forward-port=port=22:proto=tcp:toaddr=192.168.1.100</span><br><span class="line">转发 22 端口数据至另一 ip 的 2055 端口上</span><br><span class="line"></span><br><span class="line"># firewall-cmd --zone=external --add-forward-port=port=22:proto=tcp:toport=2055:toaddr=192.168.1.100</span><br><span class="line">以上都是一些常用方法,更多高级方法,请参考:</span><br><span class="line">https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Security_Guide/sec-Using_Firewalls.html</span><br><span class="line">https://fedoraproject.org/wiki/FirewallD</span><br></pre></td></tr></table></figure><h6 id="jupyter-配置文件链接"><a href="#jupyter-配置文件链接" class="headerlink" title="jupyter 配置文件链接"></a>jupyter 配置文件链接</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/Users/lizhonglin/.jupyter/jupyter_notebook_config.py</span><br></pre></td></tr></table></figure>]]></content>
<tags>
<tag> CentOS </tag>
</tags>
</entry>
<entry>
<title>Python中的SQL注射攻击</title>
<link href="/2018/05/17/Python%E4%B8%AD%E7%9A%84SQL%E6%B3%A8%E5%B0%84%E6%94%BB%E5%87%BB/"/>
<url>/2018/05/17/Python%E4%B8%AD%E7%9A%84SQL%E6%B3%A8%E5%B0%84%E6%94%BB%E5%87%BB/</url>
<content type="html"><![CDATA[<h5 id="SQL注射攻击"><a href="#SQL注射攻击" class="headerlink" title="SQL注射攻击"></a>SQL注射攻击</h5><p> 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。 [1] 比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击.</p><h6 id="演示一下什么是sql注入"><a href="#演示一下什么是sql注入" class="headerlink" title="演示一下什么是sql注入"></a>演示一下什么是sql注入</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">-- 创建用户表</span><br><span class="line">create table tb_user</span><br><span class="line">(</span><br><span class="line">username varchar(20) not null,</span><br><span class="line">userpass varchar(20) not null</span><br><span class="line">);</span><br><span class="line"></span><br><span class="line">-- 插入用户账号</span><br><span class="line">insert into tb_user values ('admin','1q23');</span><br></pre></td></tr></table></figure><h6 id="Python-代码"><a href="#Python-代码" class="headerlink" title="Python 代码"></a>Python 代码</h6><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> pymysql</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">main</span><span class="params">()</span>:</span></span><br><span class="line"> config ={</span><br><span class="line"> <span class="string">'host'</span> : <span class="string">'localhost'</span>,</span><br><span class="line"> <span class="string">'user'</span> : <span class="string">'root'</span>,</span><br><span class="line"> <span class="string">'passwd'</span> :<span class="string">'123456'</span>,</span><br><span class="line"> <span class="string">'db'</span> : <span class="string">'hrs'</span>,</span><br><span class="line"> <span class="string">'charset'</span> : <span class="string">'utf8'</span>,</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">#连接数据库</span></span><br><span class="line"> conn = pymysql.connect(**config)</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> <span class="keyword">with</span> conn.cursor() <span class="keyword">as</span> cursor:</span><br><span class="line"> user = input(<span class="string">'请输入用户名:'</span>)</span><br><span class="line"> passwd = input(<span class="string">'请输入密码:'</span>)</span><br><span class="line"> <span class="comment">#写sql语句尽量不要使用这种方法,容易被SQL注射攻击</span></span><br><span class="line"> <span class="comment">#查询用户名密码是否与数据库匹配</span></span><br><span class="line"> sql = <span class="string">"select 'x' from tb_user where username='%s' and userpass='%s'"</span> %(user,passwd)</span><br><span class="line"> <span class="comment">#判断是否有内容</span></span><br><span class="line"> <span class="keyword">if</span> cursor.execute(sql)><span class="number">0</span>:</span><br><span class="line"> print(<span class="string">'登录成功'</span>)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> print(<span class="string">'用户名或密码不正确'</span>)</span><br><span class="line"> <span class="keyword">finally</span>:</span><br><span class="line"> conn.close()</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> main()</span><br></pre></td></tr></table></figure><h6 id="如何绕过登录验证"><a href="#如何绕过登录验证" class="headerlink" title="如何绕过登录验证"></a>如何绕过登录验证</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">请输入用户名:admin</span><br><span class="line">请输入密码:' or '1'='1 或者 a' or '2'>'1 ##就能绕过密码检测登录成功.</span><br><span class="line">登录成功</span><br></pre></td></tr></table></figure><h6 id="Python写代码如何避免问题"><a href="#Python写代码如何避免问题" class="headerlink" title="Python写代码如何避免问题"></a>Python写代码如何避免问题</h6><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">##代码可以改造为这样就能避免SQL注射攻击:</span></span><br><span class="line"><span class="keyword">import</span> pymysql</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">main</span><span class="params">()</span>:</span></span><br><span class="line"> config ={</span><br><span class="line"> <span class="string">'host'</span> : <span class="string">'localhost'</span>,</span><br><span class="line"> <span class="string">'user'</span> : <span class="string">'root'</span>,</span><br><span class="line"> <span class="string">'passwd'</span> :<span class="string">'123456'</span>,</span><br><span class="line"> <span class="string">'db'</span> : <span class="string">'hrs'</span>,</span><br><span class="line"> <span class="string">'charset'</span> : <span class="string">'utf8'</span>,</span><br><span class="line"> <span class="string">'cursorclass'</span> : pymysql.cursors.DictCursor</span><br><span class="line"> }</span><br><span class="line"> conn = pymysql.connect(**config)</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> <span class="keyword">with</span> conn.cursor() <span class="keyword">as</span> cursor:</span><br><span class="line"> user = input(<span class="string">'请输入用户名:'</span>)</span><br><span class="line"> passwd = input(<span class="string">'请输入密码:'</span>)</span><br><span class="line"> <span class="comment"># sql = 'select "x" from tb_user where username="%s" and userpass="%s"' %(user,passwd)</span></span><br><span class="line"> <span class="comment"># sql = "select 'x' from tb_user where username='%s' and userpass='%s'" %(user,passwd)</span></span><br><span class="line"> <span class="comment"># if cursor.execute(sql)>0:</span></span><br><span class="line"> <span class="comment"># print('登录成功')</span></span><br><span class="line"> <span class="comment"># else:</span></span><br><span class="line"> <span class="comment"># print('用户名或密码不正确')</span></span><br><span class="line"> <span class="keyword">if</span> cursor.execute(</span><br><span class="line"> <span class="string">'select 1 from tb_user where username=%s and userpass=%s'</span>,(user,passwd)):</span><br><span class="line"> print(<span class="string">'登录成功'</span>)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> print(<span class="string">'用户名或密码不正确'</span>)</span><br><span class="line"> <span class="keyword">finally</span>:</span><br><span class="line"> conn.close()</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> main()</span><br></pre></td></tr></table></figure>]]></content>
<tags>
<tag> sql注射 </tag>
</tags>
</entry>
<entry>
<title>阿里云连接mysql报错解决</title>
<link href="/2018/05/14/%E9%98%BF%E9%87%8C%E4%BA%91%E8%BF%9E%E6%8E%A5mysql%E6%8A%A5%E9%94%99%E8%A7%A3%E5%86%B3/"/>
<url>/2018/05/14/%E9%98%BF%E9%87%8C%E4%BA%91%E8%BF%9E%E6%8E%A5mysql%E6%8A%A5%E9%94%99%E8%A7%A3%E5%86%B3/</url>
<content type="html"><![CDATA[<h4 id="连接报错2003"><a href="#连接报错2003" class="headerlink" title="连接报错2003"></a>连接报错2003</h4><h5 id="先检查linux系统的防火墙是否开启"><a href="#先检查linux系统的防火墙是否开启" class="headerlink" title="先检查linux系统的防火墙是否开启"></a>先检查linux系统的防火墙是否开启</h5><p>1.查看防火墙运行状态</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[root@izm5eifctth7468z9e6fz0z ~]# firewall-cmd --state</span><br><span class="line">running</span><br></pre></td></tr></table></figure><p>2.如果显示running就表示系统防火墙已经开启</p><p>这样的话需要给防火墙打开数据库的3306端口</p><p>以3306端口为例打开端口的命令为:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">firewall-cmd --add-port=3306/tcp --permanent --zone=public</span><br></pre></td></tr></table></figure><h5 id="检查阿里云是否打开数据库对应的端口"><a href="#检查阿里云是否打开数据库对应的端口" class="headerlink" title="检查阿里云是否打开数据库对应的端口"></a>检查阿里云是否打开数据库对应的端口</h5><p>登录阿里云官网 —-进入实例—安全组规则 —入方向—设置如下:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">授权策略协议类型端口范围授权类型授权对象 描述 优先级</span><br><span class="line">允许 自定义 TCP 3306/3306 地址段访问 0.0.0.0/0 1</span><br></pre></td></tr></table></figure><h4 id="navicat连接阿里云服务器报1130错误的解决方法"><a href="#navicat连接阿里云服务器报1130错误的解决方法" class="headerlink" title="navicat连接阿里云服务器报1130错误的解决方法"></a>navicat连接阿里云服务器报1130错误的解决方法</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">今天使用阿里云服务器,用Navicat连接阿里云服务器,连接过程中报1130错误,</span><br><span class="line"></span><br><span class="line">ERROR 1130: Host '192.168.1.3' is not allowed to connect to thisMySQL server </span><br><span class="line"></span><br><span class="line">解决方法: </span><br><span class="line"></span><br><span class="line">1。改表法。可能是你的帐号不允许从远程登陆,只能在localhost。这个时候只要在localhost的那台电脑,登入mysql后,更改"mysql" 数据库里的 "user" 表里的 "host"项,从"localhost"改称"%" </span><br><span class="line"></span><br><span class="line">或者服务器操作熟练地话直接写数据库授权</span><br><span class="line"></span><br><span class="line">grant all privileges on 数据库名.* to 用户名@'%' identified by '用户密码';</span><br></pre></td></tr></table></figure>]]></content>
<tags>
<tag> MySQL错误2003 1130 </tag>
</tags>
</entry>
<entry>
<title>Github生成ssh密钥</title>
<link href="/2018/05/13/Github%E7%94%9F%E6%88%90ssh%E5%AF%86%E9%92%A5/"/>
<url>/2018/05/13/Github%E7%94%9F%E6%88%90ssh%E5%AF%86%E9%92%A5/</url>
<content type="html"><![CDATA[<h2 id="Github配置密钥"><a href="#Github配置密钥" class="headerlink" title="Github配置密钥"></a>Github配置密钥</h2><p>我们在githob创建项目后,本地使用git 克隆代码 需要在githob配置密钥,才可以</p><p>步骤:</p><p>下载git,进行安装,安装好后。点击桌面,右键,选择》》git bash</p><p>在弹出的黑框口里面输入</p><p>ssh-keygen -t rsa -C 你的邮箱</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">比如 :ssh-keygen -t rsa -C "[email protected]"</span><br></pre></td></tr></table></figure><p>然后一直回车,就行了</p><p>最后得到如图</p><p><img src="/2018/05/13/Github生成ssh密钥/Users/lizhonglin/Desktop/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202018-05-12%20%E4%B8%8B%E5%8D%8812.52.40.png" alt="幕快照 2018-05-12 下午12.52.4"></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">它会生成一个 id _rsa.pub 文件,看上面截图,它有 保存路径的地址说明,按照保存路径找到文件,打开,复制里面的内容</span><br></pre></td></tr></table></figure><h3 id="在登陆自己的github"><a href="#在登陆自己的github" class="headerlink" title="在登陆自己的github"></a>在登陆自己的github</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">如下图:</span><br><span class="line">点击settings》》sshkey》》new ssh key(右上)</span><br><span class="line">在页面随便填入一个title,然后key里面,把刚才复制的那个文本信息拷贝进去</span><br></pre></td></tr></table></figure><p><img src="/2018/05/13/Github生成ssh密钥/var/folders/v9/jcddlqfx4tg9c57c6xvt8gyr0000gn/T/abnerworks.Typora/image-201805121257098.png" alt="mage-20180512125709"></p><p><img src="/2018/05/13/Github生成ssh密钥/var/folders/v9/jcddlqfx4tg9c57c6xvt8gyr0000gn/T/abnerworks.Typora/image-201805121259324.png" alt="mage-20180512125932"></p><p>点击add ssh key ,没有提示错误,就ok了。如果出现问题,可能是你的key没有复制完成导致</p>]]></content>
<tags>
<tag> Git SSH </tag>
</tags>
</entry>
<entry>
<title>Hexo安装教程</title>
<link href="/2018/05/13/Hexo%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/"/>
<url>/2018/05/13/Hexo%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/</url>
<content type="html"><![CDATA[<h2 id="什么是-Hexo?"><a href="#什么是-Hexo?" class="headerlink" title="什么是 Hexo?"></a>什么是 Hexo?</h2><p>Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 <a href="http://daringfireball.net/projects/markdown/" target="_blank" rel="noopener">Markdown</a>(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页。</p><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><p>安装 Hexo 只需几分钟时间,若您在安装过程中遇到问题或无法找到解决方式,请<a href="https://github.com/hexojs/hexo/issues" target="_blank" rel="noopener">提交问题</a>,我会尽力解决您的问题。</p><h3 id="安装前提"><a href="#安装前提" class="headerlink" title="安装前提"></a>安装前提</h3><p>安装 Hexo 相当简单。然而在安装前,您必须检查电脑中是否已安装下列应用程序:</p><ul><li><a href="http://nodejs.org/" target="_blank" rel="noopener">Node.js</a></li><li><a href="http://git-scm.com/" target="_blank" rel="noopener">Git</a></li></ul><p>如果您的电脑中已经安装上述必备程序,那么恭喜您!接下来只需要使用 npm 即可完成 Hexo 的安装。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install -g hexo-cli</span><br></pre></td></tr></table></figure><p>如果您的电脑中尚未安装所需要的程序,请根据以下安装指示完成安装。</p><blockquote><p>Mac 用户</p><p>您在编译时可能会遇到问题,请先到 App Store 安装 Xcode,Xcode 完成后,启动并进入 <strong>Preferences -> Download -> Command Line Tools -> Install</strong> 安装命令行工具。</p></blockquote><h3 id="安装-Git"><a href="#安装-Git" class="headerlink" title="安装 Git"></a>安装 Git</h3><ul><li>Windows:下载并安装 <a href="https://git-scm.com/download/win" target="_blank" rel="noopener">git</a>.</li><li>Mac:使用 <a href="http://mxcl.github.com/homebrew/" target="_blank" rel="noopener">Homebrew</a>, <a href="http://www.macports.org/" target="_blank" rel="noopener">MacPorts</a> :<code>brew install git</code>;或下载 <a href="http://sourceforge.net/projects/git-osx-installer/" target="_blank" rel="noopener">安装程序</a> 安装。</li><li>Linux (Ubuntu, Debian):<code>sudo apt-get install git-core</code></li><li>Linux (Fedora, Red Hat, CentOS):<code>sudo yum install git-core</code></li></ul><blockquote><p>Windows 用户</p><p>由于众所周知的原因,从上面的链接下载git for windows最好挂上一个代理,否则下载速度十分缓慢。也可以参考<a href="https://github.com/waylau/git-for-win" target="_blank" rel="noopener">这个页面</a>,收录了存储于百度云的下载地址。</p></blockquote><h3 id="安装-Node-js"><a href="#安装-Node-js" class="headerlink" title="安装 Node.js"></a>安装 Node.js</h3><p>安装 Node.js 的最佳方式是使用 <a href="https://github.com/creationix/nvm" target="_blank" rel="noopener">nvm</a>。</p><p>cURL:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl https://raw.github.com/creationix/nvm/master/install.sh | sh</span><br></pre></td></tr></table></figure><p>Wget:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ wget -qO- https://raw.github.com/creationix/nvm/master/install.sh | sh</span><br></pre></td></tr></table></figure><p>安装完成后,重启终端并执行下列命令即可安装 Node.js。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ nvm install stable</span><br></pre></td></tr></table></figure><p>或者您也可以下载 <a href="http://nodejs.org/" target="_blank" rel="noopener">安装程序</a> 来安装。</p><blockquote><p>Windows 用户</p><p>对于windows用户来说,建议使用安装程序进行安装。安装时,请勾选<strong>Add to PATH</strong>选项。<br>另外,您也可以使用<strong>Git Bash</strong>,这是git for windows自带的一组程序,提供了Linux风格的shell,在该环境下,您可以直接用上面提到的命令来安装Node.js。打开它的方法很简单,在任意位置单击右键,选择“Git Bash Here”即可。由于Hexo的很多操作都涉及到命令行,您可以考虑始终使用<strong>Git Bash</strong>来进行操作。</p></blockquote><h3 id="安装-Hexo"><a href="#安装-Hexo" class="headerlink" title="安装 Hexo"></a>安装 Hexo</h3><p>所有必备的应用程序安装完成后,即可使用 npm 安装 Hexo。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install -g hexo-cli</span><br></pre></td></tr></table></figure>]]></content>
<tags>
<tag> Hexo </tag>
</tags>
</entry>
<entry>
<title>Hello World</title>
<link href="/2018/05/13/hello-world/"/>
<url>/2018/05/13/hello-world/</url>
<content type="html"><![CDATA[<p>Welcome to <a href="https://hexo.io/" target="_blank" rel="noopener">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/" target="_blank" rel="noopener">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="https://hexo.io/docs/troubleshooting.html" target="_blank" rel="noopener">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues" target="_blank" rel="noopener">GitHub</a>.</p><h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo new <span class="string">"My New Post"</span></span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/writing.html" target="_blank" rel="noopener">Writing</a></p><h3 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/server.html" target="_blank" rel="noopener">Server</a></p><h3 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo generate</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/generating.html" target="_blank" rel="noopener">Generating</a></p><h3 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo deploy</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/deployment.html" target="_blank" rel="noopener">Deployment</a></p>]]></content>
</entry>
</search>