-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
1499 lines (1425 loc) · 771 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
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>Git简单上手</title>
<url>/posts/b041f741/</url>
<content><![CDATA[<h1 id="Git的使用学习"><a href="#Git的使用学习" class="headerlink" title="Git的使用学习"></a>Git的使用学习</h1><h2 id="什么是版本控制"><a href="#什么是版本控制" class="headerlink" title="什么是版本控制"></a>什么是版本控制</h2><p>版本控制(Revision control)是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史,方便查看更改历史记录,备份以便恢复以前的版本的软件工程技术。</p>
<ul>
<li>实现跨区域多人协同开发</li>
<li>追踪和记载一个或者多个文件的历史记录</li>
<li>组织和保护你的源代码和文档</li>
<li>统计工作量</li>
<li>并行开发、提高开发效率</li>
<li>跟踪记录整个软件的开发过程</li>
<li>减轻开发人员的负担,节省时间,同时降低人为错误</li>
</ul>
<p>简单说就是用于管理多人协同开发项目的技术。</p>
<p>没有进行版本控制或者版本控制本身缺乏正确的流程管理,在软件开发过程中将会引入很多问题,如软件代码的一致性、软件内容的冗余、软件过程的事物性、软件开发过程中的并发性、软件源代码的安全性,以及软件的整合等问题。</p>
<a id="more"></a>
<h2 id="Git配置"><a href="#Git配置" class="headerlink" title="Git配置"></a>Git配置</h2><p>所有的配置文件,其实都保存在本地!</p>
<p>查看配置 git config -l</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> git config -l</span></span><br><span class="line">diff.astextplain.textconv=astextplain</span><br><span class="line">filter.lfs.clean=git-lfs clean -- %f</span><br><span class="line">filter.lfs.smudge=git-lfs smudge -- %f</span><br><span class="line">filter.lfs.process=git-lfs filter-process</span><br><span class="line">filter.lfs.required=true</span><br><span class="line">http.sslbackend=openssl</span><br><span class="line">http.sslcainfo=d:/Git/mingw64/ssl/certs/ca-bundle.crt</span><br><span class="line">core.autocrlf=true</span><br><span class="line">core.fscache=true</span><br><span class="line">core.symlinks=false</span><br><span class="line">pull.rebase=false</span><br><span class="line">credential.helper=manager-core</span><br><span class="line">credential.https://dev.azure.com.usehttppath=true</span><br><span class="line">init.defaultbranch=master</span><br><span class="line">[email protected]</span><br><span class="line">user.name=88Fanchen</span><br><span class="line">http.sslverify=true</span><br><span class="line">core.repositoryformatversion=0</span><br><span class="line">core.filemode=false</span><br><span class="line">core.bare=false</span><br><span class="line">core.logallrefupdates=true</span><br><span class="line">core.symlinks=false</span><br><span class="line">core.ignorecase=true</span><br></pre></td></tr></table></figure>
<p>查看不同级别的配置文件:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash">查看系统config</span></span><br><span class="line">git config --system --list</span><br><span class="line"> </span><br><span class="line"><span class="meta">#</span><span class="bash">查看当前用户(global)配置</span></span><br><span class="line">git config --global --list</span><br></pre></td></tr></table></figure>
<p><strong>Git相关的配置文件:</strong></p>
<p>1)、Git\etc\gitconfig :Git 安装目录下的 gitconfig –system 系统级</p>
<p>2)、C:\Users\Administrator\ .gitconfig 只适用于当前登录用户的配置 –global 全局</p>
<h2 id="设置用户名与邮箱(用户标识,必要)"><a href="#设置用户名与邮箱(用户标识,必要)" class="headerlink" title="设置用户名与邮箱(用户标识,必要)"></a>设置用户名与邮箱(用户标识,必要)</h2><p>当你安装Git后首先要做的事情是设置你的用户名称和e-mail地址。这是非常重要的,因为每次Git提交都会使用该信息。它被永远的嵌入到了你的提交中:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> git config --global --list</span></span><br><span class="line">[email protected]</span><br><span class="line">user.name=88Fanchen</span><br><span class="line">http.sslverify=true</span><br></pre></td></tr></table></figure>
<p>只需要做一次这个设置,如果你传递了–global 选项,因为Git将总是会使用该信息来处理你在系统中所做的一切操作。如果你希望在一个特定的项目中使用不同的名称或e-mail地址,你可以在该项目中运行该命令而不要–global选项。总之–global为全局配置,不加为某个项目的特定配置。</p>
<h2 id="三个区域"><a href="#三个区域" class="headerlink" title="三个区域"></a>三个区域</h2><p>Git本地有三个工作区域:工作目录(Working Directory)、暂存区(Stage/Index)、资源库(Repository或Git Directory)。如果在加上远程的git仓库(Remote Directory)就可以分为四个工作区域。文件在这四个区域之间的转换关系如下:</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/5de702014658006f8f6f35a9de86e876.png"></p>
<ul>
<li>Workspace:工作区,就是你平时存放项目代码的地方</li>
<li>Index / Stage:暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息</li>
<li>Repository:仓库区(或本地仓库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本</li>
<li>Remote:远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换</li>
</ul>
<p>本地的三个区域确切的说应该是git仓库中HEAD指向的版本:</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/f65a1e0ee3feeee6c459bb2dea0dff90.png"></p>
<ul>
<li>Directory:使用Git管理的一个目录,也就是一个仓库,包含我们的工作空间和Git的管理空间。</li>
<li>WorkSpace:需要通过Git进行版本控制的目录和文件,这些目录和文件组成了工作空间。</li>
<li>.git:存放Git管理信息的目录,初始化仓库的时候自动创建。</li>
<li>Index/Stage:暂存区,或者叫待提交更新区,在提交进入repo之前,我们可以把所有的更新放在暂存区。</li>
<li>Local Repo:本地仓库,一个存放在本地的版本库;HEAD会只是当前的开发分支(branch)。</li>
<li>Stash:隐藏,是一个工作状态保存栈,用于保存/恢复WorkSpace中的临时状态。</li>
</ul>
<h2 id="工作流程"><a href="#工作流程" class="headerlink" title="工作流程"></a>工作流程</h2><p>git的工作流程一般是这样的:</p>
<p>1、在工作目录中添加、修改文件;</p>
<p>2、将需要进行版本管理的文件放入暂存区域;</p>
<p>3、将暂存区域的文件提交到git仓库。</p>
<p>因此,git管理的文件有三种状态:已修改(modified),已暂存(staged),已提交(committed)</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/d630b5bf29823b64080eac35312684c2.png"></p>
<h2 id="创建工作目录与常用指令"><a href="#创建工作目录与常用指令" class="headerlink" title="创建工作目录与常用指令"></a>创建工作目录与常用指令</h2><p>工作目录(WorkSpace)一般就是你希望Git帮助你管理的文件夹,可以是你项目的目录,也可以是一个空目录,建议不要有中文。</p>
<p>日常使用只要记住下图6个命令:</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/4a7dd26e69562bad80efc33fe5947146.png"></p>
<h2 id="本地仓库搭建"><a href="#本地仓库搭建" class="headerlink" title="本地仓库搭建"></a>本地仓库搭建</h2><p>创建本地仓库的方法有两种:一种是创建全新的仓库,另一种是克隆远程仓库。</p>
<p>1、创建全新的仓库,需要用GIT管理的项目的根目录执行:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 在当前目录新建一个Git代码库</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git init</span></span><br></pre></td></tr></table></figure>
<p>2、执行后可以看到,仅仅在项目目录多出了一个.git目录,关于版本等的所有信息都在这个目录里面。</p>
<h2 id="克隆远程仓库"><a href="#克隆远程仓库" class="headerlink" title="克隆远程仓库"></a>克隆远程仓库</h2><p>1、另一种方式是克隆远程目录,由于是将远程服务器上的仓库完全镜像一份至本地!</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 克隆一个项目和它的整个代码历史(版本信息)</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git <span class="built_in">clone</span> [url] <span class="comment"># https://gitee.com/kuangstudy/openclass.git</span></span></span><br></pre></td></tr></table></figure>
<h2 id="文件的四种状态"><a href="#文件的四种状态" class="headerlink" title="文件的四种状态"></a>文件的四种状态</h2><p>版本控制就是对文件的版本控制,要对文件进行修改、提交等操作,首先要知道文件当前在什么状态,不然可能会提交了现在还不想提交的文件,或者要提交的文件没提交上。</p>
<ul>
<li>Untracked: 未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过git add 状态变为Staged.</li>
<li>Unmodify: 文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改, 而变为Modified. 如果使用git rm移出版本库, 则成为Untracked文件</li>
<li>Modified: 文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过git add可进入暂存staged状态, 使用git checkout 则丢弃修改过, 返回到unmodify状态, 这个git checkout即从库中取出文件, 覆盖当前修改 !</li>
<li>Staged: 暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态. 执行git reset HEAD filename取消暂存, 文件状态为Modified</li>
</ul>
<h2 id="查看文件状态"><a href="#查看文件状态" class="headerlink" title="查看文件状态"></a>查看文件状态</h2><p>上面说文件有4种状态,通过如下命令可以查看到文件的状态:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash">查看指定文件状态</span></span><br><span class="line">git status [filename]</span><br><span class="line"><span class="meta">#</span><span class="bash">查看所有文件状态</span></span><br><span class="line">git status</span><br><span class="line"><span class="meta">#</span><span class="bash"> git add . 添加所有文件到暂存区</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> git commit -m <span class="string">"消息内容"</span> 提交暂存区中的内容到本地仓库 -m 提交信息</span></span><br></pre></td></tr></table></figure>
<h2 id="忽略文件"><a href="#忽略文件" class="headerlink" title="忽略文件"></a>忽略文件</h2><p>有些时候我们不想把某些文件纳入版本控制中,比如数据库文件,临时文件,设计文件等</p>
<p>在主目录下建立”.gitignore”文件,此文件有如下规则:</p>
<ol>
<li>忽略文件中的空行或以井号(#)开始的行将会被忽略。</li>
<li>可以使用Linux通配符。例如:星号(*)代表任意多个字符,问号(?)代表一个字符,方括号([abc])代表可选字符范围,大括号({string1,string2,…})代表可选的字符串等。</li>
<li>如果名称的最前面有一个感叹号(!),表示例外规则,将不被忽略。</li>
<li>如果名称的最前面是一个路径分隔符(/),表示要忽略的文件在此目录下,而子目录中的文件不忽略。</li>
<li>如果名称的最后面是一个路径分隔符(/),表示要忽略的是此目录下该名称的子目录,而非文件(默认文件或目录都忽略)。</li>
</ol>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash">为注释</span></span><br><span class="line">*.txt #忽略所有 .txt结尾的文件,这样的话上传就不会被选中!</span><br><span class="line">!lib.txt #但lib.txt除外</span><br><span class="line">/temp #仅忽略项目根目录下的TODO文件,不包括其它目录</span><br><span class="line">tempbuild/ #忽略build/目录下的所有文件</span><br><span class="line">doc/*.txt #会忽略 doc/notes.txt 但不包括 doc/server/arch.txt</span><br></pre></td></tr></table></figure>
<h2 id="使用码云"><a href="#使用码云" class="headerlink" title="使用码云"></a>使用码云</h2><p>1.设置本机绑定SSH公钥,实现免密码登录!(免密码登录,这一步挺重要的,码云是远程仓库,我们是平时工作在本地仓库!)</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 进入 C:\Users\Administrator\.ssh 目录</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 生成公钥</span></span><br><span class="line">ssh-keygen</span><br></pre></td></tr></table></figure>
<p>2.将公钥信息public key 添加到码云账户中即可!</p>
<h2 id="分支"><a href="#分支" class="headerlink" title="分支"></a>分支</h2><p>git分支中常用指令:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 列出所有本地分支</span></span><br><span class="line">git branch</span><br><span class="line"><span class="meta">#</span><span class="bash"> 列出所有远程分支</span></span><br><span class="line">git branch -r</span><br><span class="line"><span class="meta">#</span><span class="bash"> 新建一个分支,但依然停留在当前分支</span></span><br><span class="line">git branch [branch-name]</span><br><span class="line"><span class="meta">#</span><span class="bash"> 新建一个分支,并切换到该分支</span></span><br><span class="line">git checkout -b [branch]</span><br><span class="line"><span class="meta">#</span><span class="bash"> 合并指定分支到当前分支</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git merge [branch]</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 删除分支</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git branch -d [branch-name]</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 删除远程分支</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git push origin --delete [branch-name]$ git branch -dr [remote/branch]</span></span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>学习</category>
</categories>
<tags>
<tag>Git</tag>
</tags>
</entry>
<entry>
<title>PostgreSQL极速入门</title>
<url>/posts/1ee7efb0/</url>
<content><![CDATA[<h1 id="快速入门"><a href="#快速入门" class="headerlink" title="快速入门"></a>快速入门</h1><h2 id="数据类型"><a href="#数据类型" class="headerlink" title="数据类型"></a>数据类型</h2><p>数值类型由 2 字节、4 字节或 8 字节的整数以及 4 字节或 8 字节的浮点数和可选精度的十进制数组成。</p>
<p>下表列出了可用的数值类型。</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/da4fe6f66f42466e1783f8f8427766ee.png"></p>
<a id="more"></a>
<p><img src="https://pic.rmb.bdstatic.com/bjh/58b61e53c26f54b9dc16ec7a6eae8062.png"></p>
<h2 id="练习代码"><a href="#练习代码" class="headerlink" title="练习代码"></a>练习代码</h2><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="operator">/</span><span class="operator">/</span><span class="keyword">HAVING</span> 子句必须放置于 <span class="keyword">GROUP</span> <span class="keyword">BY</span> 子句后面,<span class="keyword">ORDER</span> <span class="keyword">BY</span> 子句前面</span><br><span class="line"><span class="keyword">SELECT</span></span><br><span class="line"><span class="keyword">FROM</span></span><br><span class="line"><span class="keyword">WHERE</span></span><br><span class="line"><span class="keyword">GROUP</span> <span class="keyword">BY</span></span><br><span class="line"><span class="keyword">HAVING</span></span><br><span class="line"><span class="keyword">ORDER</span> <span class="keyword">BY</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">CURRENT_TIMESTAMP</span>, <span class="built_in">CURRENT_ROLE</span>, <span class="built_in">CURRENT_USER</span>, <span class="built_in">CURRENT_CATALOG</span>, <span class="built_in">CURRENT_SCHEMA</span>;</span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> COMPANY <span class="keyword">WHERE</span> AGE <span class="keyword">IS</span> <span class="keyword">NOT</span> <span class="keyword">NULL</span>;</span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> COMPANY <span class="keyword">WHERE</span> NAME <span class="keyword">LIKE</span> <span class="string">'Pa%'</span>;</span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> COMPANY <span class="keyword">WHERE</span> AGE <span class="keyword">IN</span> ( <span class="number">25</span>, <span class="number">27</span> );</span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> COMPANY <span class="keyword">WHERE</span> AGE <span class="keyword">BETWEEN</span> <span class="number">20</span> <span class="keyword">AND</span> <span class="number">30</span>;</span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> company <span class="keyword">WHERE</span> <span class="keyword">EXISTS</span>(<span class="keyword">SELECT</span> ID <span class="keyword">from</span> company <span class="keyword">where</span> salary <span class="operator">>=</span> <span class="number">65000</span>);</span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> company <span class="keyword">WHERE</span> ID <span class="keyword">in</span> (<span class="keyword">SELECT</span> ID <span class="keyword">from</span> company <span class="keyword">where</span> salary <span class="operator">>=</span> <span class="number">65000</span>);</span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> COMPANY <span class="keyword">WHERE</span> AGE::text <span class="keyword">LIKE</span> <span class="string">'2%'</span>;<span class="operator">/</span><span class="operator">/</span>类型转换</span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> COMPANY <span class="keyword">WHERE</span> salary::<span class="type">varchar</span> <span class="keyword">LIKE</span> <span class="string">'1___0'</span>;</span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">from</span> company limit <span class="number">3</span> <span class="keyword">offset</span> <span class="number">3</span>;</span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> company <span class="keyword">ORDER</span> <span class="keyword">BY</span> age <span class="keyword">ASC</span>, salary <span class="keyword">DESC</span>;</span><br><span class="line"><span class="keyword">SELECT</span> NAME, <span class="built_in">SUM</span>(SALARY) <span class="keyword">FROM</span> COMPANY <span class="keyword">GROUP</span> <span class="keyword">BY</span> NAME;<span class="operator">/</span><span class="operator">/</span>数据存在重复的时候</span><br><span class="line"><span class="keyword">With</span> CTE <span class="keyword">AS</span></span><br><span class="line">(<span class="keyword">Select</span></span><br><span class="line"> ID</span><br><span class="line">, NAME</span><br><span class="line">, AGE</span><br><span class="line">, ADDRESS</span><br><span class="line">, SALARY</span><br><span class="line"><span class="keyword">FROM</span> COMPANY )</span><br><span class="line"><span class="keyword">Select</span> <span class="operator">*</span> <span class="keyword">From</span> CTE;<span class="operator">/</span><span class="operator">/</span><span class="keyword">WITH</span> 子句提供了一种编写辅助语句的方法,以便在更大的查询中使用</span><br><span class="line"><span class="keyword">WITH</span> moved <span class="keyword">AS</span> (<span class="keyword">DELETE</span> <span class="keyword">FROM</span> company <span class="keyword">WHERE</span> salary <span class="operator"><=</span> <span class="number">20000</span> RETURNING <span class="operator">*</span>)</span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">from</span> moved</span><br><span class="line"><span class="keyword">WITH</span> <span class="keyword">RECURSIVE</span> t(n) <span class="keyword">AS</span> (<span class="operator">/</span><span class="operator">/</span>可用于递归 还有疑问</span><br><span class="line"> <span class="keyword">VALUES</span> (<span class="number">0</span>)</span><br><span class="line"> <span class="keyword">UNION</span> <span class="keyword">ALL</span></span><br><span class="line"> <span class="keyword">SELECT</span> SALARY <span class="keyword">FROM</span> COMPANY <span class="keyword">WHERE</span> SALARY <span class="operator">></span> <span class="number">20000</span></span><br><span class="line">)</span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">sum</span>(n) <span class="keyword">FROM</span> t;</span><br><span class="line"><span class="keyword">SELECT</span> name <span class="keyword">FROM</span> COMPANY <span class="keyword">GROUP</span> <span class="keyword">BY</span> name <span class="keyword">HAVING</span> <span class="built_in">count</span>(name) <span class="operator">></span> <span class="number">2</span>;</span><br><span class="line"><span class="operator">/</span><span class="operator">/</span><span class="keyword">DISTINCT</span> 关键字与 <span class="keyword">SELECT</span> 语句一起使用,用于去除重复记录,只获取唯一的记录。</span><br><span class="line"><span class="keyword">SELECT</span> name,age,address,salary,dept <span class="keyword">FROM</span> company <span class="keyword">as</span> c <span class="keyword">LEFT</span> <span class="keyword">JOIN</span> department <span class="keyword">as</span> d <span class="keyword">ON</span> c.id <span class="operator">=</span> d.emp_id <span class="operator">/</span><span class="operator">/</span>左外连接</span><br><span class="line"><span class="operator">/</span><span class="operator">/</span><span class="keyword">UNION</span> 操作符合并两个或多个 <span class="keyword">SELECT</span> 语句的结果</span><br><span class="line"><span class="keyword">SELECT</span> name,age,address,salary,dept <span class="keyword">FROM</span> company <span class="keyword">as</span> c <span class="keyword">LEFT</span> <span class="keyword">JOIN</span> department <span class="keyword">as</span> d <span class="keyword">ON</span> c.id <span class="operator">=</span> d.emp_id <span class="keyword">WHERE</span> age <span class="operator"><</span> <span class="number">25</span></span><br><span class="line"><span class="keyword">UNION</span></span><br><span class="line"><span class="keyword">SELECT</span> name,age,address,salary,dept <span class="keyword">FROM</span> company <span class="keyword">as</span> c <span class="keyword">LEFT</span> <span class="keyword">JOIN</span> department <span class="keyword">as</span> d <span class="keyword">ON</span> c.id <span class="operator">=</span> d.emp_id <span class="keyword">WHERE</span> age <span class="operator">></span> <span class="number">30</span></span><br><span class="line"><span class="keyword">select</span> name,age,address,salary,dept <span class="keyword">from</span> company <span class="keyword">LEFT</span> <span class="keyword">JOIN</span> department <span class="keyword">ON</span> company.id <span class="operator">=</span> department.emp_id <span class="keyword">WHERE</span> dept <span class="keyword">is</span> <span class="keyword">not</span> <span class="keyword">null</span></span><br><span class="line">PostgreSQL 触发器可以在下面几种情况下触发:</span><br><span class="line">在执行操作之前(在检查约束并尝试插入、更新或删除之前)。</span><br><span class="line">在执行操作之后(在检查约束并插入、更新或删除完成之后)。</span><br><span class="line">更新操作(在对一个视图进行插入、更新、删除时)。</span><br><span class="line">触发器的 <span class="keyword">FOR</span> <span class="keyword">EACH</span> <span class="type">ROW</span> 属性是可选的,如果选中,当操作修改时每行调用一次;相反,选中 <span class="keyword">FOR</span> <span class="keyword">EACH</span> STATEMENT,不管修改了多少行,每个语句标记的触发器执行一次。</span><br><span class="line">索引不应该使用在较小的表上。</span><br><span class="line">索引不应该使用在有频繁的大批量的更新或插入操作的表上。</span><br><span class="line">索引不应该使用在含有大量的 <span class="keyword">NULL</span> 值的列上。</span><br><span class="line">索引不应该使用在频繁操作的列上。</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> company <span class="keyword">ADD</span> <span class="keyword">CONSTRAINT</span> AgeCheck <span class="keyword">CHECK</span>(age <span class="operator">></span> <span class="number">18</span>)</span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> company("id", "name", age, address, salary) <span class="keyword">VALUES</span> (<span class="number">10</span>, <span class="string">'fanchen'</span>, <span class="number">18</span>, <span class="string">'Anhui'</span>, <span class="number">20000</span>)</span><br><span class="line"><span class="operator">></span> 错误: 关系 "company" 的新列违反了检查约束 "agecheck"</span><br><span class="line">DETAIL: 失败, 行包含(<span class="number">10</span>, fanchen, <span class="number">18</span>, Anhui, <span class="number">20000</span>)</span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> company("id", "name", age, address, salary) <span class="keyword">VALUES</span> (<span class="number">10</span>, <span class="string">'fanchen'</span>, <span class="number">19</span>, <span class="string">'Anhui'</span>, <span class="number">20000</span>)</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> table_name <span class="keyword">DROP</span> <span class="keyword">CONSTRAINT</span> 约束名; <span class="operator">/</span><span class="operator">/</span>删除约束</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> company <span class="keyword">DROP</span> <span class="keyword">CONSTRAINT</span> agecheck</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> company <span class="keyword">DROP</span> <span class="keyword">CONSTRAINT</span> agecheck <span class="operator">></span> OK</span><br><span class="line"><span class="keyword">TRUNCATE</span> <span class="keyword">TABLE</span> 用于删除表的数据,但不删除表结构。</span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">VIEW</span> company_dept <span class="keyword">AS</span> <span class="keyword">SELECT</span></span><br><span class="line">"name",</span><br><span class="line">age,</span><br><span class="line">address,</span><br><span class="line">salary,</span><br><span class="line">dept </span><br><span class="line"><span class="keyword">FROM</span></span><br><span class="line"> company</span><br><span class="line"> <span class="keyword">LEFT</span> <span class="keyword">JOIN</span> department <span class="keyword">ON</span> company."id" <span class="operator">=</span> department.emp_id</span><br><span class="line"><span class="operator">/</span><span class="operator">/</span>视图会随着来源表数据的更新而更新</span><br><span class="line"><span class="keyword">DROP</span> <span class="keyword">VIEW</span> view_name;</span><br><span class="line">ACID</span><br><span class="line">原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。</span><br><span class="line">一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。</span><br><span class="line">隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。</span><br><span class="line">持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。</span><br><span class="line"><span class="keyword">BEGIN</span>;</span><br><span class="line">或者</span><br><span class="line"><span class="keyword">BEGIN</span> TRANSACTION;</span><br><span class="line"></span><br><span class="line"><span class="keyword">COMMIT</span>;</span><br><span class="line">或者</span><br><span class="line"><span class="keyword">END</span> TRANSACTION;</span><br><span class="line"></span><br><span class="line"><span class="keyword">ROLLBACK</span>;</span><br><span class="line"></span><br><span class="line">数据库中有两种基本的锁:排它锁(Exclusive Locks)和共享锁(Share Locks)。</span><br><span class="line">如果数据对象加上排它锁,则其他的事务不能对它读取和修改。</span><br><span class="line">如果加上共享锁,则该数据库对象可以被其他事务读取,但不能修改。</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line">LOCK <span class="keyword">TABLE</span> company <span class="keyword">IN</span> ACCESS SHARE MODE<span class="operator">/</span><span class="operator">/</span>别人可以查到,但是没有提交事务之前的数据未更新</span><br><span class="line">LOCK <span class="keyword">TABLE</span> company1 <span class="keyword">IN</span> ACCESS EXCLUSIVE MODE;<span class="operator">/</span><span class="operator">/</span>事务完成别人才能查到数据</span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> company <span class="keyword">WHERE</span> "id" <span class="keyword">IN</span> (<span class="keyword">SELECT</span> "id" <span class="keyword">FROM</span> company <span class="keyword">WHERE</span> salary <span class="operator"><</span> <span class="number">20000</span>)<span class="operator">/</span><span class="operator">/</span>子查询</span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> COMPANY_BKP <span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> COMPANY <span class="keyword">WHERE</span> ID <span class="keyword">IN</span> (<span class="keyword">SELECT</span> ID <span class="keyword">FROM</span> COMPANY);<span class="operator">/</span><span class="operator">/</span>把整个 COMPANY 表复制到 COMPANY_BKP下</span><br><span class="line"><span class="operator">/</span><span class="operator">/</span>所有 AGE 大于 <span class="number">27</span> 的客户的 SALARY 更新为原来的 <span class="number">0.50</span> 倍</span><br><span class="line"><span class="keyword">UPDATE</span> COMPANY <span class="keyword">SET</span> SALARY <span class="operator">=</span> SALARY <span class="operator">*</span> <span class="number">0.50</span> <span class="keyword">WHERE</span> AGE <span class="keyword">IN</span> (<span class="keyword">SELECT</span> AGE <span class="keyword">FROM</span> COMPANY_BKP <span class="keyword">WHERE</span> AGE <span class="operator">>=</span> <span class="number">27</span> );</span><br><span class="line"><span class="operator">/</span><span class="operator">/</span>删除 COMPANY 表中所有 AGE 大于或等于 <span class="number">27</span> 的客户记录</span><br><span class="line"><span class="keyword">DELETE</span> <span class="keyword">FROM</span> COMPANY <span class="keyword">WHERE</span> AGE <span class="keyword">IN</span> (<span class="keyword">SELECT</span> AGE <span class="keyword">FROM</span> COMPANY_BKP <span class="keyword">WHERE</span> AGE <span class="operator">></span> <span class="number">27</span> );</span><br><span class="line">PostgreSQL 使用序列来标识字段的自增长,数据类型有 smallserial、serial 和 bigserial 。这些属性类似于 MySQL 数据库支持的 AUTO_INCREMENT 属性。</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>学习</category>
</categories>
<tags>
<tag>SQL</tag>
</tags>
</entry>
<entry>
<title>selenium自动化操作问卷星</title>
<url>/posts/f027b801/</url>
<content><![CDATA[<font color=#999AAA >
问卷星的自动化操作
</font>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p><font color=#999AAA >身边的很多同学需要填写问卷星,有很多需要刷任务的操作,等等类似场景,可以使用selenium实现</font></p>
<p><font color=#999AAA >以下是本篇文章正文内容,下面案例可供参考</p>
<h1 id="一、selenium是什么?"><a href="#一、selenium是什么?" class="headerlink" title="一、selenium是什么?"></a>一、selenium是什么?</h1><p><em>Selenium 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本。</em></p>
<a id="more"></a>
<h1 id="二、代码实现"><a href="#二、代码实现" class="headerlink" title="二、代码实现"></a>二、代码实现</h1><p><font color=#999AAA >参照了其他同学的代码实现了自动化的操作。直接上代码吧!</font></p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> selenium <span class="keyword">import</span> webdriver</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">import</span> random</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">run</span>():</span></span><br><span class="line"> <span class="comment"># 创建一个浏览器对象</span></span><br><span class="line"> browser = webdriver.Edge(executable_path=<span class="string">'msedgedriver.exe'</span>)</span><br><span class="line"> <span class="comment"># 请求该地址</span></span><br><span class="line"> browser.get(<span class="string">"https://www.wjx.cn/jq/80378706.aspx"</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 问题1的点击</span></span><br><span class="line"> randomId = random.randint(<span class="number">1</span>, <span class="number">2</span>) <span class="comment"># 随机数 随机点击按钮</span></span><br><span class="line"> js = <span class="string">"document.getElementById(\"q1_"</span> + <span class="built_in">str</span>(randomId) + <span class="string">"\").click()"</span></span><br><span class="line"> <span class="comment"># 使用js实现点击的效果</span></span><br><span class="line"> browser.execute_script(js)</span><br><span class="line"> <span class="comment"># 延时 太快会被检测是脚本</span></span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 问题2</span></span><br><span class="line"> randomId = random.randint(<span class="number">1</span>, <span class="number">4</span>) <span class="comment"># 随机数,四个多选框 随机点击</span></span><br><span class="line"> js = <span class="string">"document.getElementById(\"q2_"</span> + <span class="built_in">str</span>(randomId) + <span class="string">"\").click()"</span></span><br><span class="line"> <span class="comment"># 拼接字符串的方式 js找到对应id 点击按钮</span></span><br><span class="line"> browser.execute_script(js)</span><br><span class="line"> <span class="comment"># 延时</span></span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 问题3</span></span><br><span class="line"> block = [<span class="string">"商学院"</span>, <span class="string">"计科院"</span>, <span class="string">"电气院"</span>] <span class="comment"># 随机输入内容</span></span><br><span class="line"> randomId = random.randint(<span class="number">0</span>, <span class="number">2</span>) <span class="comment"># 随机数</span></span><br><span class="line"> <span class="comment"># 输入内容</span></span><br><span class="line"> browser.find_element_by_id(<span class="string">"q3"</span>).send_keys(block[randomId])</span><br><span class="line"> <span class="comment"># 延时</span></span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 问题4</span></span><br><span class="line"> block = [<span class="string">"会计"</span>, <span class="string">"网工"</span>, <span class="string">"电气"</span>] <span class="comment"># 随机输入内容</span></span><br><span class="line"> browser.find_element_by_id(<span class="string">"q4"</span>).send_keys(block[randomId])</span><br><span class="line"> <span class="comment"># 延时</span></span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 问题5</span></span><br><span class="line"> randomId = random.randint(<span class="number">1</span>, <span class="number">5</span>) <span class="comment"># 随机数</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, randomId + <span class="number">1</span>): <span class="comment"># 循环 实现多选效果</span></span><br><span class="line"> randomId1 = random.randint(<span class="number">1</span>, <span class="number">5</span>)</span><br><span class="line"> <span class="comment"># 两种js实现方式</span></span><br><span class="line"> js = <span class="string">"document.getElementById(\"q5_"</span> + <span class="built_in">str</span>(randomId1) + <span class="string">"\").checked = true"</span></span><br><span class="line"> browser.execute_script(js)</span><br><span class="line"> js = <span class="string">"document.getElementById(\"q5_"</span> + <span class="built_in">str</span>(randomId1) + <span class="string">"\").click()"</span></span><br><span class="line"> browser.execute_script(js)</span><br><span class="line"> <span class="comment"># 延时</span></span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 问题6</span></span><br><span class="line"> randomId = random.randint(<span class="number">1</span>, <span class="number">3</span>) <span class="comment"># 参照问题5</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, randomId + <span class="number">1</span>):</span><br><span class="line"> randomId1 = random.randint(<span class="number">1</span>, <span class="number">3</span>)</span><br><span class="line"> js = <span class="string">"document.getElementById(\"q6_"</span> + <span class="built_in">str</span>(randomId1) + <span class="string">"\").checked = true"</span></span><br><span class="line"> browser.execute_script(js)</span><br><span class="line"> js = <span class="string">"document.getElementById(\"q6_"</span> + <span class="built_in">str</span>(randomId1) + <span class="string">"\").click()"</span></span><br><span class="line"> browser.execute_script(js)</span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 问题7</span></span><br><span class="line"> randomId = random.randint(<span class="number">1</span>, <span class="number">3</span>) <span class="comment"># 参照问题5</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, randomId + <span class="number">1</span>):</span><br><span class="line"> randomId1 = random.randint(<span class="number">1</span>, <span class="number">3</span>)</span><br><span class="line"> js = <span class="string">"document.getElementById(\"q7_"</span> + <span class="built_in">str</span>(randomId1) + <span class="string">"\").checked = true"</span></span><br><span class="line"> browser.execute_script(js)</span><br><span class="line"> js = <span class="string">"document.getElementById(\"q7_"</span> + <span class="built_in">str</span>(randomId1) + <span class="string">"\").click()"</span></span><br><span class="line"> browser.execute_script(js)</span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 问题8</span></span><br><span class="line"> randomId = random.randint(<span class="number">1</span>, <span class="number">2</span>) <span class="comment"># 单选</span></span><br><span class="line"> js = <span class="string">"document.getElementById(\"q8_"</span> + <span class="built_in">str</span>(randomId) + <span class="string">"\").click()"</span></span><br><span class="line"> browser.execute_script(js)</span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 问题9</span></span><br><span class="line"> randomId = random.randint(<span class="number">1</span>, <span class="number">2</span>) <span class="comment"># 单选</span></span><br><span class="line"> js = <span class="string">"document.getElementById(\"q9_"</span> + <span class="built_in">str</span>(randomId) + <span class="string">"\").click()"</span></span><br><span class="line"> browser.execute_script(js)</span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 问题10</span></span><br><span class="line"> randomId = random.randint(<span class="number">1</span>, <span class="number">3</span>) <span class="comment"># 单选</span></span><br><span class="line"> js = <span class="string">"document.getElementById(\"q10_"</span> + <span class="built_in">str</span>(randomId) + <span class="string">"\").click()"</span></span><br><span class="line"> browser.execute_script(js)</span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 问题12</span></span><br><span class="line"> <span class="keyword">if</span> randomId == <span class="number">2</span>:</span><br><span class="line"> randomId2 = random.randint(<span class="number">1</span>, <span class="number">6</span>) <span class="comment"># 多选</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, randomId2 + <span class="number">1</span>): <span class="comment"># 循环实现</span></span><br><span class="line"> randomId1 = random.randint(<span class="number">1</span>, <span class="number">6</span>)</span><br><span class="line"> <span class="comment"># 两种js点击方法</span></span><br><span class="line"> js = <span class="string">"document.getElementById(\"q12_"</span> + <span class="built_in">str</span>(randomId1) + <span class="string">"\").checked = true"</span></span><br><span class="line"> browser.execute_script(js)</span><br><span class="line"> js = <span class="string">"document.getElementById(\"q12_"</span> + <span class="built_in">str</span>(randomId1) + <span class="string">"\").click()"</span></span><br><span class="line"> browser.execute_script(js)</span><br><span class="line"> <span class="comment"># 延时</span></span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line"> <span class="comment"># 问题11</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> randomId2 = random.randint(<span class="number">1</span>, <span class="number">7</span>) <span class="comment"># 参照上一个</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, randomId2 + <span class="number">1</span>):</span><br><span class="line"> randomId1 = random.randint(<span class="number">1</span>, <span class="number">7</span>)</span><br><span class="line"> js = <span class="string">"document.getElementById(\"q11_"</span> + <span class="built_in">str</span>(randomId1) + <span class="string">"\").checked = true"</span></span><br><span class="line"> browser.execute_script(js)</span><br><span class="line"> js = <span class="string">"document.getElementById(\"q11_"</span> + <span class="built_in">str</span>(randomId1) + <span class="string">"\").click()"</span></span><br><span class="line"> browser.execute_script(js)</span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 问题13</span></span><br><span class="line"> randomId = random.randint(<span class="number">1</span>, <span class="number">3</span>) <span class="comment"># 单选</span></span><br><span class="line"> js = <span class="string">"document.getElementById(\"q13_"</span> + <span class="built_in">str</span>(randomId) + <span class="string">"\").click()"</span></span><br><span class="line"> browser.execute_script(js)</span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 问题14</span></span><br><span class="line"> block = [<span class="string">"线上教学太生硬"</span>, <span class="string">"线上教学不太好"</span>, <span class="string">"没有不足之处,挺好的"</span>] <span class="comment"># 随机输入</span></span><br><span class="line"> randomId = random.randint(<span class="number">0</span>, <span class="number">2</span>)</span><br><span class="line"> browser.find_element_by_id(<span class="string">"q14"</span>).send_keys(block[randomId])</span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 问题15</span></span><br><span class="line"> block = [<span class="string">"希望作业能多一点"</span>, <span class="string">"如果可以,希望老师能讲课讲清楚一些"</span>, <span class="string">"建议取消线上考试"</span>] <span class="comment"># 随机输入</span></span><br><span class="line"> randomId = random.randint(<span class="number">0</span>, <span class="number">2</span>)</span><br><span class="line"> browser.find_element_by_id(<span class="string">"q15"</span>).send_keys(block[randomId])</span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># submit</span></span><br><span class="line"> js = <span class="string">"document.getElementById(\"submit_button\").click()"</span> <span class="comment"># 点击提交按钮</span></span><br><span class="line"> browser.execute_script(js)</span><br><span class="line"></span><br><span class="line"> browser.quit() <span class="comment"># 运行完毕自动关闭浏览器</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 class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> run()</span><br><span class="line"> time.sleep(<span class="number">10</span>) <span class="comment"># 避免提交过快 会出现验证</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>以上就是今天要讲的内容,本文仅仅简单介绍了selenium的使用,selenium还可以帮我们做很多事情,比如模拟登录,爬取某宝的宝贝数据等等。以后我们再见!<br><strong>注:案例仅供学习</strong></p>
]]></content>
<categories>
<category>爬虫学习</category>
</categories>
<tags>
<tag>Python</tag>
<tag>问卷星</tag>
</tags>
</entry>
<entry>
<title>python实现抖音无水印下载</title>
<url>/posts/106c0da3/</url>
<content><![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>使用抖音的分享链接对其进行无水印的下载</p>
<p>对分享链接的网页进行分析,找到跳转的地址,在地址中找到url,请求对应的地址。</p>
<p>对得到的json文件进行分析,找到对应key下的数据下载链接,将其中的关键字替换,playwm替换成play即是完整的下载链接。</p>
<h1 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h1><p>下面附上完整代码:</p>
<a id="more"></a>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> re</span><br><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><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">DouyinDownload</span>:</span></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.headers = {</span><br><span class="line"> <span class="string">'User-Agent'</span>: <span class="string">'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1 Edg/88.0.4324.96'</span></span><br><span class="line"> }</span><br><span class="line"> self.windows_headers = {</span><br><span class="line"> <span class="string">'User-Agent'</span>: <span class="string">'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56'</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">check_url</span>(<span class="params">self, url</span>):</span></span><br><span class="line"> response = requests.get(url=url, headers=self.windows_headers, allow_redirects=<span class="literal">False</span>)</span><br><span class="line"> <span class="keyword">if</span> response.headers.get(<span class="string">'location'</span>):</span><br><span class="line"> <span class="keyword">return</span> response.headers.get(<span class="string">'location'</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><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">download</span>(<span class="params">self, url</span>):</span></span><br><span class="line"> response = requests.get(url=url, headers=self.windows_headers).json()</span><br><span class="line"> v_title = response[<span class="string">'item_list'</span>][<span class="number">0</span>][<span class="string">'share_info'</span>][<span class="string">'share_title'</span>]</span><br><span class="line"> download_url = response[<span class="string">'item_list'</span>][<span class="number">0</span>][<span class="string">'video'</span>][<span class="string">'play_addr'</span>][<span class="string">'url_list'</span>][<span class="number">0</span>].replace(<span class="string">"playwm"</span>, <span class="string">"play"</span>)</span><br><span class="line"> path = <span class="string">'F:\Spider\douyin'</span></span><br><span class="line"> data = requests.get(url=download_url, headers=self.headers).content</span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(path + <span class="string">'/{}.mp4'</span>.<span class="built_in">format</span>(v_title), <span class="string">'wb'</span>) <span class="keyword">as</span> video:</span><br><span class="line"> video.write(data)</span><br><span class="line"> print(<span class="string">"视频名:{}\n状态: 下载完成\n地址:{}"</span>.<span class="built_in">format</span>(v_title, path))</span><br><span class="line"> open_status = <span class="built_in">input</span>(<span class="string">"是否打开? y/n\n"</span>)</span><br><span class="line"> <span class="keyword">if</span> open_status == <span class="string">'y'</span> <span class="keyword">or</span> <span class="string">'Y'</span>:</span><br><span class="line"> os.startfile(path)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">pass</span></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"> share_url = <span class="built_in">input</span>(<span class="string">"请输入抖音分享链接:"</span>)</span><br><span class="line"> share_url = re.findall(<span class="string">r'https://v.douyin.com/.*?/'</span>, share_url)[<span class="number">0</span>]</span><br><span class="line"> location = self.check_url(share_url)</span><br><span class="line"> v_id = re.findall(<span class="string">'/share/video/(\d*)'</span>, location)[<span class="number">0</span>]</span><br><span class="line"> download_url = <span class="string">'https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids={}'</span>.<span class="built_in">format</span>(v_id)</span><br><span class="line"> self.download(download_url)</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"> dy = DouyinDownload()</span><br><span class="line"> dy.run()</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h1 id="运行截图"><a href="#运行截图" class="headerlink" title="运行截图"></a>运行截图</h1><p><img src="https://pic.rmb.bdstatic.com/bjh/3353e3f73d55e89186bf6729b7a22fb1.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/58304b8d5ec0ab43a9623b1de78658f1.png"></p>
]]></content>
<categories>
<category>爬虫学习</category>
</categories>
<tags>
<tag>Python</tag>
<tag>抖音</tag>
<tag>破解分析</tag>
</tags>
</entry>
<entry>
<title>企业微信api实时给私人微信推送数据</title>
<url>/posts/5bb6de70/</url>
<content><![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><blockquote>
<p>有些场景下需要给自己的微信推送数据,达到通知的效果。这里的实现有很多,比如server酱等相关第三方平台,但是会随着腾讯的相关协议波动,并且有时候简短的消息需要跳转相关网页查看详情,有些许的不便,于是今天带来一种解决的办法,也就是替代品。结合服务器能做到不错的效果,也可以与合作的同学实现数据共享。</p>
</blockquote>
<p><img src="https://pic.rmb.bdstatic.com/bjh/d9045d4db80e047cf9f31de3a6347bae.png"></p>
<a id="more"></a>
<p><a href="http://sc.ftqq.com/3.version">server酱首页链接</a></p>
<p>使用效果:</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/22bea99e5506523f9bd0f361982dcaa8.png"></p>
<p><strong>很明显的可以看出来,毕竟是第三方平台,不便于自己使用。</strong></p>
<p>而使用企业微信的api我们可以给自己私人推送一些自己想要的数据或者是通知。也可以拉入自己小组的其他朋友,以实现数据共享。</p>
<h1 id="实现步骤"><a href="#实现步骤" class="headerlink" title="实现步骤"></a>实现步骤</h1><h2 id="注册企业微信"><a href="#注册企业微信" class="headerlink" title="注册企业微信"></a>注册企业微信</h2><p><a href="https://work.weixin.qq.com/wework_admin/register_wx?from=myhome_baidu">企业微信注册</a></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/dba1f5c9859df1005b19d350eff72350.png"></p>
<p>注册后需要用到一些参数:</p>
<ol>
<li>企业ID</li>
<li>应用id</li>
<li>应用密匙</li>
</ol>
<p><img src="https://pic.rmb.bdstatic.com/bjh/ff0e5299249a17f7f3ad9a45fd1a2491.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/6fe604541a80a82f1fcfe499d4fa0860.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/1a0570ec7a80811c3368b7e7b868e1e3.png"></p>
<h2 id="访问接口"><a href="#访问接口" class="headerlink" title="访问接口"></a>访问接口</h2><p><img src="https://pic.rmb.bdstatic.com/bjh/555990f5dc80b1fc016572b07e24b1e0.png"></p>
<p>根据官方的文档我们可以清晰的看到使用步骤,这里只做部分的说明和实现。</p>
<h3 id="接口定义"><a href="#接口定义" class="headerlink" title="接口定义"></a>接口定义</h3><p>应用支持推送文本、图片、视频、文件、图文等类型。</p>
<p><strong>请求方式:</strong>POST(<strong>HTTPS</strong>)<br><strong>请求地址:</strong> <a href="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN">https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN</a></p>
<p><strong>参数说明:</strong></p>
<table>
<thead>
<tr>
<th>参数</th>
<th>是否必须</th>
<th>备注</th>
</tr>
</thead>
<tbody><tr>
<td>access_token</td>
<td>是</td>
<td>接口凭证(有时效性)</td>
</tr>
</tbody></table>
<h3 id="消息类型"><a href="#消息类型" class="headerlink" title="消息类型"></a>消息类型</h3><h4 id="文本消息"><a href="#文本消息" class="headerlink" title="文本消息"></a>文本消息</h4><p><strong>post请求data示例:</strong></p>
<figure class="highlight json"><table><tr><td class="code"><pre><span class="line">{</span><br><span class="line"> <span class="attr">"touser"</span> : <span class="string">"UserID1|UserID2|UserID3"</span>,</span><br><span class="line"> <span class="attr">"toparty"</span> : <span class="string">"PartyID1|PartyID2"</span>,</span><br><span class="line"> <span class="attr">"totag"</span> : <span class="string">"TagID1 | TagID2"</span>,</span><br><span class="line"> <span class="attr">"msgtype"</span> : <span class="string">"text"</span>,</span><br><span class="line"> <span class="attr">"agentid"</span> : <span class="number">1</span>,</span><br><span class="line"> <span class="attr">"text"</span> : {</span><br><span class="line"> <span class="attr">"content"</span> : <span class="string">"你的快递已到,请携带工卡前往邮件中心领取。\n出发前可查看<a href=\"http://work.weixin.qq.com\">邮件中心视频实况</a>,聪明避开排队。"</span></span><br><span class="line"> },</span><br><span class="line"> <span class="attr">"safe"</span>:<span class="number">0</span>,</span><br><span class="line"> <span class="attr">"enable_id_trans"</span>: <span class="number">0</span>,</span><br><span class="line"> <span class="attr">"enable_duplicate_check"</span>: <span class="number">0</span>,</span><br><span class="line"> <span class="attr">"duplicate_check_interval"</span>: <span class="number">1800</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>这里我们可以看到content中是支持a标签的,换行用转义过的\n,大概效果如下:</p>
<p><img src="https://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_msg$5bc63c26.png"></p>
<p>请求参数含义:</p>
<table>
<thead>
<tr>
<th><strong>参数</strong></th>
<th><strong>是否必须</strong></th>
<th><strong>参数说明</strong></th>
</tr>
</thead>
<tbody><tr>
<td>touser</td>
<td>否</td>
<td>成员ID列表(特殊情况:指定为@all,则向关注该企业应用的全部成员发送)</td>
</tr>
<tr>
<td>toparty</td>
<td>否</td>
<td>部门ID列表</td>
</tr>
<tr>
<td>totag</td>
<td>否</td>
<td>标签ID列表</td>
</tr>
<tr>
<td>msgtype</td>
<td>是</td>
<td>消息类型</td>
</tr>
<tr>
<td>agentid</td>
<td>是</td>
<td>企业应用的id, int型</td>
</tr>
<tr>
<td>content</td>
<td>是</td>
<td>消息内容,最长不超过2048个字节,超过将截断<strong>(支持id转译)</strong></td>
</tr>
<tr>
<td>safe</td>
<td>否</td>
<td>表示是否是保密消息,0表示可对外分享,1表示不能分享且内容显示水印,默认为0</td>
</tr>
<tr>
<td>enable_duplicate_check</td>
<td>否</td>
<td>表示是否开启重复消息检查,0表示否,1表示是,默认0</td>
</tr>
<tr>
<td>duplicate_check_interval</td>
<td>否</td>
<td>表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时</td>
</tr>
</tbody></table>
<blockquote>
<p>这里需要注意的是,<strong>touser、toparty、totag不能同时为空</strong></p>
</blockquote>
<h4 id="其他消息"><a href="#其他消息" class="headerlink" title="其他消息"></a>其他消息</h4><p>支持的消息类型有:</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/b946ad4893f25249b4f76266d4fe2103.png"></p>
<p><strong>文本卡片消息展现 :</strong></p>
<p><img src="http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/cardmsg.jpeg"></p>
<p><strong>图文消息展现:</strong></p>
<p><img src="https://p.qpic.cn/pic_wework/3478722865/7a7c92760b2bd396e3b856a660f43c8b7db11271bddb3f34/0"></p>
<p><strong>markdown示例效果:</strong></p>
<p><img src="http://p.qpic.cn/pic_wework/1114461239/dddbcdd097e5f308248cd7f99e0ebb336975267b9348c4ec/0"></p>
<p><strong>任务卡片消息展现 :</strong></p>
<p><img src="http://p.qpic.cn/pic_wework/80330653/7f798570abf8a20977345ff10631cb998beab632442acd3d/0"></p>
<p><strong>等等等等。</strong></p>
<p>值得注意的是部分消息普通微信无法查看,例如markdown类型,需要使用企业微信才可以查看,失去了我们图求的便利性,故放弃。</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/b021370fa9f2976048af868b5de1be13.png"></p>
<h1 id="实例"><a href="#实例" class="headerlink" title="实例"></a>实例</h1><p>这里放上编写的代码实例,简单调用了text类型的发送,这里的小米运动的实现可以参照之前的博文。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> json</span><br><span class="line"><span class="keyword">from</span> 小米运动.小米运动刷步 <span class="keyword">import</span> domain</span><br><span class="line"><span class="keyword">from</span> 爬虫基础.天气查询 <span class="keyword">import</span> get_weather</span><br><span class="line"></span><br><span class="line">corpid = <span class="string">'企业id'</span></span><br><span class="line">corpsecret = <span class="string">'应用密匙'</span></span><br><span class="line">token_url = <span class="string">'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={}&corpsecret={}'</span>.<span class="built_in">format</span>(corpid, corpsecret)</span><br><span class="line">common_headers = {</span><br><span class="line"> <span class="string">'user-agent'</span>: <span class="string">'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.63'</span></span><br><span class="line">}</span><br><span class="line">ACCESS_TOKEN = requests.get(url=token_url, headers=common_headers).json().get(<span class="string">'access_token'</span>)</span><br><span class="line">vx_api = <span class="string">'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={}'</span>.<span class="built_in">format</span>(ACCESS_TOKEN)</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">send_message</span>(<span class="params">message, text_type</span>):</span></span><br><span class="line"> data = {</span><br><span class="line"> <span class="string">"touser"</span>: <span class="string">'@all'</span>,</span><br><span class="line"> <span class="string">"msgtype"</span>: text_type,</span><br><span class="line"> <span class="string">"agentid"</span>: <span class="string">'应用id'</span>,</span><br><span class="line"> text_type: {<span class="string">'content'</span>: message}</span><br><span class="line"> }</span><br><span class="line"> data = <span class="built_in">bytes</span>(json.dumps(data), <span class="string">'utf-8'</span>)</span><br><span class="line"> result = requests.post(url=vx_api, headers=common_headers, data=data).text</span><br><span class="line"> print(result)</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"> weather = get_weather(<span class="string">'无为'</span>)</span><br><span class="line"> send_message(weather, <span class="string">'text'</span>)</span><br><span class="line"> res = domain(user=小米账号, pwd=<span class="string">"密码"</span>, step=步数)</span><br><span class="line"> send_message(message=res, text_type=<span class="string">'text'</span>)</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h1 id="运行结果"><a href="#运行结果" class="headerlink" title="运行结果"></a>运行结果</h1><p><img src="https://pic.rmb.bdstatic.com/bjh/2457fee706d57c8bb095e26b9cac734b.png"></p>
<p><strong>根据微信企业微信的api文档,我们可以做很多的事情,例如定时任务,收到指定关键字回复消息等,可以根据服务器完美的融合。</strong></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/cd058e678c42a14282576f5a135dfce4.png"></p>
<p>具体请参照<strong>企业微信官网开发文档</strong>:</p>
<p><a href="https://open.work.weixin.qq.com/api/doc/90000/90135/90236">官方开发文档</a></p>
<h1 id="注意事项"><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h1><p>有时候可能根据api返回的json错误码说明,仍然不知道自己的参数在哪里出错,此时可以在接口请求url里加上debug=1参数。</p>
<p>然后根据返回的实例,在微信的错误码查询工具中根据hint码值查看相关错误。</p>
<p><a href="https://open.work.weixin.qq.com/devtool/query">错误码查询工具</a></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/a8c7869308676b9a6027345ab4c9f55d.png"></p>
]]></content>
<categories>
<category>爬虫学习</category>
</categories>
<tags>
<tag>Python</tag>
<tag>微信消息推送</tag>
</tags>
</entry>
<entry>
<title>分析模板资源网站并使用python进行下载</title>
<url>/posts/378704c3/</url>
<content><![CDATA[<font color=#999AAA >
侵权删除。
</font>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p><strong>今天准备在网上找一个web模板,用来做Echarts的数据可视化。寻找模板的过程中像往常一样,遇到了很多的收费网站,一般都是月费年费类型的。然后我就遇到了下面这个网站:</strong><br><img src="https://img-blog.csdnimg.cn/20210104223121512.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
<a id="more"></a>
<p>在我下载的过程中简单分析了一下,是否可以抓包的方式,获取对应的下载链接,下面<strong>进入我们的正文分析环节。</strong></p>
<p><font color=#999AAA >以下是本篇文章正文内容</p>
<h1 id="一、页面分析"><a href="#一、页面分析" class="headerlink" title="一、页面分析"></a>一、页面分析</h1><p><img src="https://img-blog.csdnimg.cn/20210104223458871.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>发现下载模板的a标签中没有存在相应的href属性,一般下载链接都不会放在这,应该是通过js进行的控制。于是我看了一下下载好模板对应的url链接,对其进行分析后发现,<strong>几个url大致相同,只有两个参数发生了变化,就是对应的压缩文件名,和对应的sid。</strong><br><img src="https://img-blog.csdnimg.cn/20210104223908796.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br><strong>我们可以发现 第一个压缩包名字就是在线预览url中,index.html之前的参数,所以我们直接取页面中href属性值就可以,sid页面上则贴心的给我们显示出来了,就是素材编号,猜测sid的s就是素材的缩写,hhh</strong><br>再看看我们点击下载按钮后的抓包工具里,出现了一个异步请求,又是cookie又是token的校验。<br><img src="https://img-blog.csdnimg.cn/20210104224225721.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>最后返回了一个json数据,里面果然存放的就是下载链接等信息。<br><img src="https://img-blog.csdnimg.cn/20210104224438444.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>到这里我们的分析基本已经结束了,拿到了下载链接后,打开浏览器的隐私窗口对其进行访问,果然不用登陆就直接下载了对应的模板压缩包,接下来进行我们的<strong>代码编写</strong>。</p>
<h1 id="二、编写代码"><a href="#二、编写代码" class="headerlink" title="二、编写代码"></a>二、编写代码</h1><p>代码很简短,这次<strong>主要是锻炼我们的网页分析和抓包思路。</strong></p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">from</span> fake_useragent <span class="keyword">import</span> UserAgent</span><br><span class="line"><span class="keyword">from</span> lxml <span class="keyword">import</span> etree</span><br><span class="line"></span><br><span class="line"><span class="comment"># ip代理池</span></span><br><span class="line">proxy_pool = [{<span class="string">'http'</span>: <span class="string">'http://175.42.122.247:9999'</span>}, {<span class="string">'http'</span>: <span class="string">'http://115.53.37.35:9999'</span>},</span><br><span class="line"> {<span class="string">'http'</span>: <span class="string">'http://115.221.242.62:9999'</span>}, {<span class="string">'http'</span>: <span class="string">'http://175.42.129.10:9999'</span>}]</span><br><span class="line"><span class="comment"># 机型伪装头</span></span><br><span class="line">headers = {</span><br><span class="line"> <span class="string">'user-agent'</span>: UserAgent().random</span><br><span class="line">}</span><br><span class="line"><span class="comment"># 下载地址的基础模板</span></span><br><span class="line">base_url = <span class="string">'http://down.kangjingept.com/cssthemes6/{}.zip?sid={}'</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"><span class="function"><span class="keyword">def</span> <span class="title">get_zip</span>(<span class="params">url</span>):</span></span><br><span class="line"> <span class="comment"># 请求url中就包含了我们的sid 懒得去xpath解析了 直接分割字符串吧</span></span><br><span class="line"> sid = url.split(<span class="string">'/'</span>)[-<span class="number">1</span>].split(<span class="string">'.'</span>)[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># 请求网页地址 再用etree解析对象</span></span><br><span class="line"> response = requests.get(url=url, headers=headers, proxies=random.choice(proxy_pool)).text</span><br><span class="line"> data = etree.HTML(response)</span><br><span class="line"> <span class="comment"># 压缩包的名字 取a标签中的href属性值</span></span><br><span class="line"> zip_name = data.xpath(<span class="string">'//div[@class="btn_box"]/a[1]/@href'</span>)[<span class="number">0</span>].split(<span class="string">'/'</span>)[-<span class="number">2</span>]</span><br><span class="line"> <span class="comment"># 又找了一个中文的文件名 方便浏览</span></span><br><span class="line"> file_name = data.xpath(<span class="string">'/html/body/div[8]/h1/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># 拼接url</span></span><br><span class="line"> zip_url = base_url.<span class="built_in">format</span>(zip_name, sid)</span><br><span class="line"> <span class="comment"># 获取压缩包的内容</span></span><br><span class="line"> zip_content = requests.get(url=zip_url, headers=headers).content</span><br><span class="line"> <span class="comment"># 二进制格式写入</span></span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">'./{}.zip'</span>.<span class="built_in">format</span>(file_name), <span class="string">'wb'</span>) <span class="keyword">as</span> z:</span><br><span class="line"> z.write(zip_content)</span><br><span class="line"> print(<span class="string">'文件{}.zip 下载完毕!!!'</span>.<span class="built_in">format</span>(file_name))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 键盘粘贴对应的链接</span></span><br><span class="line">input_url = <span class="built_in">input</span>(<span class="string">'请输入对应的链接:'</span>)</span><br><span class="line">get_zip(input_url)</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h1 id="结果演示"><a href="#结果演示" class="headerlink" title="结果演示"></a>结果演示</h1><p><img src="https://img-blog.csdnimg.cn/20210104225555275.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br><img src="https://img-blog.csdnimg.cn/20210104225615458.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
]]></content>
<categories>
<category>爬虫学习</category>
</categories>
<tags>
<tag>Python</tag>
<tag>破解分析</tag>
<tag>下载</tag>
</tags>
</entry>
<entry>
<title>前后端分离CRUD基于vue+springboot</title>
<url>/posts/9590b4fb/</url>
<content><![CDATA[<h1 id="前后端分离下的CRUD实现(回顾)"><a href="#前后端分离下的CRUD实现(回顾)" class="headerlink" title="前后端分离下的CRUD实现(回顾)"></a>前后端分离下的CRUD实现(回顾)</h1><h2 id="Vue(前端)"><a href="#Vue(前端)" class="headerlink" title="Vue(前端)"></a>Vue(前端)</h2><p><img src="https://img-blog.csdnimg.cn/20210119223712686.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70" alt="页面样式"></p>
<a id="more"></a>
<p>使用饿了么框架</p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">template</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span>></span></span><br><span class="line"> <span class="comment"><!-- 面包屑导航 --></span></span><br><span class="line"> <span class="tag"><<span class="name">el-breadcrumb</span> <span class="attr">separator-class</span>=<span class="string">"el-icon-arrow-right"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-breadcrumb-item</span> <span class="attr">:to</span>=<span class="string">"{ path: '/home' }"</span>></span>首页<span class="tag"></<span class="name">el-breadcrumb-item</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-breadcrumb-item</span>></span>权限管理<span class="tag"></<span class="name">el-breadcrumb-item</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-breadcrumb-item</span>></span>用户列表<span class="tag"></<span class="name">el-breadcrumb-item</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-breadcrumb</span>></span></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="tag"><<span class="name">el-card</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-row</span> <span class="attr">:gutter</span>=<span class="string">"25"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-col</span> <span class="attr">:span</span>=<span class="string">"10"</span>></span></span><br><span class="line"> <span class="comment"><!-- 搜索添加 --></span></span><br><span class="line"> <span class="tag"><<span class="name">el-input</span> <span class="attr">placeholder</span>=<span class="string">"请输入搜索内容"</span> <span class="attr">v-model</span>=<span class="string">"queryInfo.query"</span> <span class="attr">clearable</span> @<span class="attr">clear</span>=<span class="string">"getUserList"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-button</span> <span class="attr">slot</span>=<span class="string">"append"</span> <span class="attr">icon</span>=<span class="string">"el-icon-search"</span> @<span class="attr">click</span>=<span class="string">"getUserList"</span>></span><span class="tag"></<span class="name">el-button</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-input</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-col</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-col</span> <span class="attr">:span</span>=<span class="string">"4"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-button</span> <span class="attr">type</span>=<span class="string">"primary"</span> @<span class="attr">click</span>=<span class="string">"addDialogVisible = true"</span>></span>添加用户<span class="tag"></<span class="name">el-button</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-col</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-row</span>></span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"><!-- 用户列表 border 边框 stripe 隔行变色 --></span></span><br><span class="line"> <span class="tag"><<span class="name">el-table</span> <span class="attr">:data</span>=<span class="string">"userlist"</span> <span class="attr">border</span> <span class="attr">stripe</span> <span class="attr">class</span>=<span class="string">"table-margin"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-table-column</span> <span class="attr">type</span>=<span class="string">"index"</span>></span><span class="tag"></<span class="name">el-table-column</span>></span><span class="comment"><!--索引列--></span></span><br><span class="line"> <span class="tag"><<span class="name">el-table-column</span> <span class="attr">label</span>=<span class="string">"姓名"</span> <span class="attr">prop</span>=<span class="string">"username"</span>></span><span class="tag"></<span class="name">el-table-column</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-table-column</span> <span class="attr">label</span>=<span class="string">"邮箱"</span> <span class="attr">prop</span>=<span class="string">"email"</span>></span><span class="tag"></<span class="name">el-table-column</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-table-column</span> <span class="attr">label</span>=<span class="string">"密码(md5加密)"</span> <span class="attr">prop</span>=<span class="string">"password"</span>></span><span class="tag"></<span class="name">el-table-column</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-table-column</span> <span class="attr">label</span>=<span class="string">"角色"</span> <span class="attr">prop</span>=<span class="string">"role"</span>></span><span class="tag"></<span class="name">el-table-column</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-table-column</span> <span class="attr">label</span>=<span class="string">"状态"</span> <span class="attr">prop</span>=<span class="string">"state"</span>></span></span><br><span class="line"> <span class="comment"><!--作用域插槽 scope.row 存储了当前行的信息 --></span></span><br><span class="line"> <span class="tag"><<span class="name">template</span> <span class="attr">slot-scope</span>=<span class="string">"scope"</span>></span><span class="comment"><!--数据模板--></span></span><br><span class="line"> <span class="tag"><<span class="name">el-switch</span> <span class="attr">v-model</span>=<span class="string">"scope.row.state"</span> @<span class="attr">change</span>=<span class="string">"userStateChanged(scope.row)"</span>></span><span class="tag"></<span class="name">el-switch</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">template</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-table-column</span>></span></span><br><span class="line"> <span class="comment"><!--自定义插槽--></span></span><br><span class="line"> <span class="tag"><<span class="name">el-table-column</span> <span class="attr">label</span>=<span class="string">"操作"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">template</span> <span class="attr">slot-scope</span>=<span class="string">"scope"</span>></span></span><br><span class="line"> <span class="comment"><!-- 修改 --></span></span><br><span class="line"> <span class="tag"><<span class="name">el-button</span> <span class="attr">type</span>=<span class="string">"primary"</span> <span class="attr">icon</span>=<span class="string">"el-icon-edit"</span> <span class="attr">size</span>=<span class="string">"mini"</span> @<span class="attr">click</span>=<span class="string">"showUpdateDialog(scope.row.id)"</span>></span><span class="tag"></<span class="name">el-button</span>></span></span><br><span class="line"> <span class="comment"><!-- 删除 --></span></span><br><span class="line"> <span class="tag"><<span class="name">el-button</span> <span class="attr">type</span>=<span class="string">"danger"</span> <span class="attr">icon</span>=<span class="string">"el-icon-delete"</span> <span class="attr">size</span>=<span class="string">"mini"</span> @<span class="attr">click</span>=<span class="string">"deleteUser(scope.row.id)"</span>></span><span class="tag"></<span class="name">el-button</span>></span></span><br><span class="line"> <span class="comment"><!-- 权限 --></span></span><br><span class="line"> <span class="tag"><<span class="name">el-tooltip</span> <span class="attr">effect</span>=<span class="string">"dark"</span> <span class="attr">content</span>=<span class="string">"分配权限"</span> <span class="attr">placement</span>=<span class="string">"top-start"</span> <span class="attr">:enterable</span>=<span class="string">"false"</span>></span><span class="comment"><!--文字提示 enterable 隐藏--></span></span><br><span class="line"> <span class="tag"><<span class="name">el-button</span> <span class="attr">type</span>=<span class="string">"warning"</span> <span class="attr">icon</span>=<span class="string">"el-icon-setting"</span> <span class="attr">size</span>=<span class="string">"mini"</span>></span><span class="tag"></<span class="name">el-button</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-tooltip</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">template</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-table-column</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-table</span>></span></span><br><span class="line"> </span><br><span class="line"> <span class="tag"><<span class="name">div</span>></span></span><br><span class="line"> <span class="comment"><!-- 分页 size-change 每页最大数变化 current-change 页数变化 layout 功能组件--></span></span><br><span class="line"> <el-pagination</span><br><span class="line"> @size-change="handleSizeChange"</span><br><span class="line"> @current-change="handleCurrentChange"</span><br><span class="line"> :current-page="queryInfo.pageNum"</span><br><span class="line"> :page-sizes="[2, 5, 100]"</span><br><span class="line"> :page-size="queryInfo.pageSize"</span><br><span class="line"> layout="total, sizes, prev, pager, next, jumper"</span><br><span class="line"> :total="total"</span><br><span class="line"> ><span class="tag"></<span class="name">el-pagination</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">el-card</span>></span></span><br><span class="line"> <span class="comment"><!-- 新增用户 --></span></span><br><span class="line"> <span class="tag"><<span class="name">el-dialog</span> <span class="attr">title</span>=<span class="string">"添加用户"</span> <span class="attr">:visible.sync</span>=<span class="string">"addDialogVisible"</span> <span class="attr">width</span>=<span class="string">"50%"</span> @<span class="attr">close</span>=<span class="string">"addDialogClosed"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-form</span> <span class="attr">:model</span>=<span class="string">"addForm"</span> <span class="attr">:rules</span>=<span class="string">"rules"</span> <span class="attr">ref</span>=<span class="string">"addFormRef"</span> <span class="attr">label-width</span>=<span class="string">"70px"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-form-item</span> <span class="attr">label</span>=<span class="string">"用户名"</span> <span class="attr">prop</span>=<span class="string">"username"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-input</span> <span class="attr">v-model</span>=<span class="string">"addForm.username"</span>></span><span class="tag"></<span class="name">el-input</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-form-item</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-form-item</span> <span class="attr">label</span>=<span class="string">"密码"</span> <span class="attr">prop</span>=<span class="string">"password"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-input</span> <span class="attr">v-model</span>=<span class="string">"addForm.password"</span>></span><span class="tag"></<span class="name">el-input</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-form-item</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-form-item</span> <span class="attr">label</span>=<span class="string">"邮箱"</span> <span class="attr">prop</span>=<span class="string">"email"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-input</span> <span class="attr">v-model</span>=<span class="string">"addForm.email"</span>></span><span class="tag"></<span class="name">el-input</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-form-item</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-form</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">span</span> <span class="attr">slot</span>=<span class="string">"footer"</span> <span class="attr">class</span>=<span class="string">"dialog-footer"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-button</span> @<span class="attr">click</span>=<span class="string">"addDialogVisible = false"</span>></span>取消<span class="tag"></<span class="name">el-button</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-button</span> <span class="attr">type</span>=<span class="string">"primary"</span> @<span class="attr">click</span>=<span class="string">"addUser"</span>></span>添加<span class="tag"></<span class="name">el-button</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">span</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-dialog</span>></span></span><br><span class="line"> </span><br><span class="line"> <span class="tag"><<span class="name">el-dialog</span> <span class="attr">title</span>=<span class="string">"修改用户"</span> <span class="attr">:visible.sync</span>=<span class="string">"updateDialogVisible"</span> <span class="attr">width</span>=<span class="string">"50%"</span> @<span class="attr">close</span>=<span class="string">"updateDialogClosed"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-form</span> <span class="attr">:model</span>=<span class="string">"updateForm"</span> <span class="attr">:rules</span>=<span class="string">"rules"</span> <span class="attr">ref</span>=<span class="string">"updateFormRef"</span> <span class="attr">label-width</span>=<span class="string">"70px"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-form-item</span> <span class="attr">label</span>=<span class="string">"用户名"</span> <span class="attr">prop</span>=<span class="string">"username"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-input</span> <span class="attr">v-model</span>=<span class="string">"updateForm.username"</span>></span><span class="tag"></<span class="name">el-input</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-form-item</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-form-item</span> <span class="attr">label</span>=<span class="string">"密码"</span> <span class="attr">prop</span>=<span class="string">"password"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-input</span> <span class="attr">v-model</span>=<span class="string">"updateForm.password"</span>></span><span class="tag"></<span class="name">el-input</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-form-item</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-form-item</span> <span class="attr">label</span>=<span class="string">"邮箱"</span> <span class="attr">prop</span>=<span class="string">"email"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-input</span> <span class="attr">v-model</span>=<span class="string">"updateForm.email"</span>></span><span class="tag"></<span class="name">el-input</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-form-item</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-form</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">span</span> <span class="attr">slot</span>=<span class="string">"footer"</span> <span class="attr">class</span>=<span class="string">"dialog-footer"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-button</span> @<span class="attr">click</span>=<span class="string">"updateDialogVisible = false"</span>></span>取消<span class="tag"></<span class="name">el-button</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-button</span> <span class="attr">type</span>=<span class="string">"primary"</span> @<span class="attr">click</span>=<span class="string">"updateUser"</span>></span>修改<span class="tag"></<span class="name">el-button</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">span</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">el-dialog</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">template</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="name">script</span>></span></span><br><span class="line"><span class="javascript"> <span class="keyword">export</span> <span class="keyword">default</span>{</span></span><br><span class="line"><span class="javascript"> <span class="function"><span class="title">created</span>(<span class="params"></span>)</span> {</span></span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.getUserList();</span></span><br><span class="line"> },</span><br><span class="line"><span class="javascript"> <span class="function"><span class="title">data</span>(<span class="params"></span>)</span> {</span></span><br><span class="line"><span class="javascript"> <span class="keyword">return</span> {</span></span><br><span class="line"><span class="javascript"> <span class="comment">// 请求数据</span></span></span><br><span class="line"> queryInfo: {</span><br><span class="line"><span class="javascript"> query: <span class="string">""</span>,</span></span><br><span class="line"> pageNum: 1,</span><br><span class="line"> pageSize: 5</span><br><span class="line"> },</span><br><span class="line"><span class="javascript"> userlist: [],<span class="comment">// 用户列表</span></span></span><br><span class="line"><span class="javascript"> total: <span class="number">0</span>, <span class="comment">// 最大数据记录</span></span></span><br><span class="line"><span class="javascript"> addDialogVisible: <span class="literal">false</span>,</span></span><br><span class="line"> addForm:{</span><br><span class="line"><span class="javascript"> username:<span class="string">''</span>,</span></span><br><span class="line"><span class="javascript"> password:<span class="string">''</span>,</span></span><br><span class="line"><span class="javascript"> email:<span class="string">''</span>,</span></span><br><span class="line"> },</span><br><span class="line"> updateForm:{</span><br><span class="line"> </span><br><span class="line"> },</span><br><span class="line"><span class="javascript"> updateDialogVisible: <span class="literal">false</span>,</span></span><br><span class="line"> rules:{</span><br><span class="line"><span class="javascript"> <span class="comment">//校验用户名</span></span></span><br><span class="line"> username:[</span><br><span class="line"><span class="javascript"> { <span class="attr">required</span>: <span class="literal">true</span>, <span class="attr">message</span>: <span class="string">'请输入用户名'</span>, <span class="attr">trigger</span>: <span class="string">'blur'</span> },</span></span><br><span class="line"><span class="javascript"> { <span class="attr">min</span>: <span class="number">4</span>, <span class="attr">max</span>: <span class="number">12</span>, <span class="attr">message</span>: <span class="string">'长度在 4 ~ 12 个字符'</span>, <span class="attr">trigger</span>: <span class="string">'blur'</span> }</span></span><br><span class="line"> ],</span><br><span class="line"><span class="javascript"> <span class="comment">//校验密码</span></span></span><br><span class="line"> password:[</span><br><span class="line"><span class="javascript"> { <span class="attr">required</span>: <span class="literal">true</span>, <span class="attr">message</span>: <span class="string">'请输入密码'</span>, <span class="attr">trigger</span>: <span class="string">'blur'</span> },</span></span><br><span class="line"><span class="javascript"> { <span class="attr">min</span>: <span class="number">6</span>, <span class="attr">max</span>: <span class="number">12</span>, <span class="attr">message</span>: <span class="string">'长度在 6 ~ 12 个字符'</span>, <span class="attr">trigger</span>: <span class="string">'blur'</span> }</span></span><br><span class="line"> ],</span><br><span class="line"> email:[</span><br><span class="line"><span class="javascript"> { <span class="attr">required</span>: <span class="literal">true</span>, <span class="attr">message</span>: <span class="string">'请输入邮箱'</span>, <span class="attr">trigger</span>: <span class="string">'blur'</span> },</span></span><br><span class="line"><span class="javascript"> { <span class="attr">min</span>: <span class="number">5</span>, <span class="attr">max</span>: <span class="number">25</span>, <span class="attr">message</span>: <span class="string">'格式不正确'</span>, <span class="attr">trigger</span>: <span class="string">'blur'</span> }</span></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"> methods:{</span><br><span class="line"><span class="javascript"> <span class="keyword">async</span> <span class="function"><span class="title">getUserList</span>(<span class="params"></span>)</span> {</span></span><br><span class="line"><span class="javascript"> <span class="comment">// 调用get请求</span></span></span><br><span class="line"><span class="javascript"> <span class="keyword">const</span> { <span class="attr">data</span>: res } = <span class="keyword">await</span> <span class="built_in">this</span>.$http.get(<span class="string">"/allUser"</span>, {</span></span><br><span class="line"><span class="javascript"> params: <span class="built_in">this</span>.queryInfo</span></span><br><span class="line"> });</span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.userlist = res.data; <span class="comment">// 将返回数据赋值</span></span></span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.total = res.numbers; <span class="comment">// 总个数</span></span></span><br><span class="line"> },</span><br><span class="line"><span class="javascript"> <span class="comment">// 监听pageSize改变的事件</span></span></span><br><span class="line"><span class="javascript"> <span class="function"><span class="title">handleSizeChange</span>(<span class="params">newSize</span>)</span> {</span></span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.queryInfo.pageSize = newSize;</span></span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.getUserList(); <span class="comment">// 数据发生改变重新申请数据</span></span></span><br><span class="line"> },</span><br><span class="line"><span class="javascript"> <span class="comment">// 监听pageNum改变的事件</span></span></span><br><span class="line"><span class="javascript"> <span class="function"><span class="title">handleCurrentChange</span>(<span class="params">newPage</span>)</span> {</span></span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.queryInfo.pageNum = newPage;</span></span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.getUserList(); <span class="comment">// 数据发生改变重新申请数据</span></span></span><br><span class="line"> },</span><br><span class="line"><span class="javascript"> <span class="keyword">async</span> <span class="function"><span class="title">userStateChanged</span>(<span class="params">userinfo</span>)</span> {</span></span><br><span class="line"><span class="javascript"> <span class="keyword">const</span> { <span class="attr">data</span>: res } = <span class="keyword">await</span> <span class="built_in">this</span>.$http.get(</span></span><br><span class="line"><span class="javascript"> <span class="string">"/userState"</span>, {</span></span><br><span class="line"> params: {id:userinfo.id,state:userinfo.state}</span><br><span class="line"> }</span><br><span class="line"> );</span><br><span class="line"><span class="javascript"> <span class="keyword">if</span> (res != <span class="string">"success"</span>) {</span></span><br><span class="line"> userinfo.state = !userinfo.state;</span><br><span class="line"><span class="javascript"> <span class="keyword">return</span> <span class="built_in">this</span>.$message.error(<span class="string">"账号状态更新失败!"</span>);</span></span><br><span class="line"> }</span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.$message.success(<span class="string">"账号状态已更新!"</span>);</span></span><br><span class="line"> },</span><br><span class="line"><span class="javascript"> <span class="function"><span class="title">addDialogClosed</span>(<span class="params"></span>)</span>{</span></span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.$refs.addFormRef.resetFields();</span></span><br><span class="line"> },</span><br><span class="line"><span class="javascript"> <span class="function"><span class="title">addUser</span>(<span class="params"></span>)</span>{</span></span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.$refs.addFormRef.validate(<span class="keyword">async</span> vaild=>{</span></span><br><span class="line"><span class="javascript"> <span class="keyword">if</span>(!vaild){</span></span><br><span class="line"><span class="javascript"> <span class="keyword">return</span>;</span></span><br><span class="line"> }</span><br><span class="line"><span class="javascript"> <span class="keyword">const</span> {<span class="attr">data</span>:res} = <span class="keyword">await</span> <span class="built_in">this</span>.$http.post(<span class="string">"/addUser"</span>,<span class="built_in">this</span>.addForm);</span></span><br><span class="line"><span class="javascript"> <span class="keyword">if</span>(res!=<span class="string">"success"</span>){</span></span><br><span class="line"><span class="javascript"> <span class="keyword">return</span> <span class="built_in">this</span>.$message.error(<span class="string">"添加失败!"</span>);</span></span><br><span class="line"> }</span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.$message.success(<span class="string">"添加成功!"</span>);</span></span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.addDialogVisible = <span class="literal">false</span>;</span></span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.getUserList();</span></span><br><span class="line"> })</span><br><span class="line"> },</span><br><span class="line"><span class="javascript"> <span class="keyword">async</span> <span class="function"><span class="title">deleteUser</span>(<span class="params">id</span>)</span>{</span></span><br><span class="line"><span class="javascript"> <span class="keyword">const</span> confirmResult = <span class="keyword">await</span> <span class="built_in">this</span>.$confirm(<span class="string">'此操作将永久删除用户,是否继续?'</span>,<span class="string">'提示'</span>,{</span></span><br><span class="line"><span class="javascript"> confirmButtonText:<span class="string">'确定'</span>,</span></span><br><span class="line"><span class="javascript"> cancelButtonText:<span class="string">'取消'</span>,</span></span><br><span class="line"><span class="javascript"> type:<span class="string">'warning'</span></span></span><br><span class="line"><span class="javascript"> }).catch(<span class="function"><span class="params">err</span> =></span> err);</span></span><br><span class="line"><span class="javascript"> <span class="keyword">if</span>(confirmResult!=<span class="string">'confirm'</span>){</span></span><br><span class="line"><span class="javascript"> <span class="keyword">return</span> <span class="built_in">this</span>.$message.warning(<span class="string">"已取消删除!"</span>);</span></span><br><span class="line"> }</span><br><span class="line"><span class="javascript"> <span class="keyword">const</span> {<span class="attr">data</span>:res} = <span class="keyword">await</span> <span class="built_in">this</span>.$http.get(<span class="string">"/deleteUser"</span>,{</span></span><br><span class="line"> params: {id:id}</span><br><span class="line"> });</span><br><span class="line"><span class="javascript"> <span class="keyword">if</span>(res!=<span class="string">"success"</span>){</span></span><br><span class="line"><span class="javascript"> <span class="keyword">return</span> <span class="built_in">this</span>.$message.error(<span class="string">"删除失败!"</span>);</span></span><br><span class="line"> }</span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.$message.success(<span class="string">"删除成功!"</span>);</span></span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.getUserList();</span></span><br><span class="line"> },</span><br><span class="line"><span class="javascript"> <span class="keyword">async</span> <span class="function"><span class="title">showUpdateDialog</span>(<span class="params">id</span>)</span>{</span></span><br><span class="line"><span class="javascript"> <span class="keyword">const</span> {<span class="attr">data</span>:res} = <span class="keyword">await</span> <span class="built_in">this</span>.$http.get(<span class="string">"/getUpdateUser"</span>,{</span></span><br><span class="line"> params: {id:id}</span><br><span class="line"> });</span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.updateForm = res;</span></span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.updateDialogVisible = <span class="literal">true</span>;</span></span><br><span class="line"> },</span><br><span class="line"><span class="javascript"> <span class="function"><span class="title">updateDialogClosed</span>(<span class="params"></span>)</span>{</span></span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.$refs.updateFormRef.resetFields();</span></span><br><span class="line"> },</span><br><span class="line"><span class="javascript"> <span class="function"><span class="title">updateUser</span>(<span class="params"></span>)</span>{</span></span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.$refs.updateFormRef.validate(<span class="keyword">async</span> vaild=>{</span></span><br><span class="line"><span class="javascript"> <span class="keyword">if</span>(!vaild){</span></span><br><span class="line"><span class="javascript"> <span class="keyword">return</span>;</span></span><br><span class="line"> }</span><br><span class="line"><span class="javascript"> <span class="keyword">const</span> {<span class="attr">data</span>:res} = <span class="keyword">await</span> <span class="built_in">this</span>.$http.post(<span class="string">"/updateUser"</span>,<span class="built_in">this</span>.updateForm);</span></span><br><span class="line"><span class="javascript"> <span class="keyword">if</span>(res!=<span class="string">"success"</span>){</span></span><br><span class="line"><span class="javascript"> <span class="keyword">return</span> <span class="built_in">this</span>.$message.error(<span class="string">"更新失败!"</span>);</span></span><br><span class="line"> }</span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.$message.success(<span class="string">"更新成功!"</span>);</span></span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.updateDialogVisible = <span class="literal">false</span>;</span></span><br><span class="line"><span class="javascript"> <span class="built_in">this</span>.getUserList();</span></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 class="tag"></<span class="name">script</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="name">style</span> <span class="attr">lang</span>=<span class="string">"less"</span>></span></span><br><span class="line"><span class="css"> <span class="comment">/* 面包屑样式 */</span></span></span><br><span class="line"><span class="css"> <span class="selector-class">.el-breadcrumb</span>{</span></span><br><span class="line"> margin-bottom: 15px;</span><br><span class="line"> font-size: 16px;</span><br><span class="line"> }</span><br><span class="line"><span class="tag"></<span class="name">style</span>></span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>路由设置:</p>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> Vue <span class="keyword">from</span> <span class="string">'vue'</span></span><br><span class="line"><span class="keyword">import</span> VueRouter <span class="keyword">from</span> <span class="string">'vue-router'</span></span><br><span class="line"><span class="keyword">import</span> Login <span class="keyword">from</span> <span class="string">'../components/Login.vue'</span></span><br><span class="line"><span class="keyword">import</span> Home <span class="keyword">from</span> <span class="string">'../components/Home.vue'</span></span><br><span class="line"><span class="keyword">import</span> Welcome <span class="keyword">from</span> <span class="string">'../components/welcome.vue'</span></span><br><span class="line"><span class="keyword">import</span> UserList <span class="keyword">from</span> <span class="string">'../components/admin/UserList.vue'</span></span><br><span class="line"></span><br><span class="line">Vue.use(VueRouter)</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> routes = [</span><br><span class="line"> {</span><br><span class="line"> path: <span class="string">"/"</span>,</span><br><span class="line"> redirect: <span class="string">"/login"</span></span><br><span class="line"> },</span><br><span class="line"> {</span><br><span class="line"> path: <span class="string">"/login"</span>,</span><br><span class="line"> component: Login</span><br><span class="line"> },</span><br><span class="line"> {</span><br><span class="line"> path: <span class="string">"/home"</span>,</span><br><span class="line"> component: Home,</span><br><span class="line"> redirect: <span class="string">"/welcome"</span>,</span><br><span class="line"> children:[</span><br><span class="line"> {<span class="attr">path</span>: <span class="string">"/welcome"</span>,<span class="attr">component</span>: Welcome,},</span><br><span class="line"> {<span class="attr">path</span>: <span class="string">"/user"</span>,<span class="attr">component</span>: UserList,},</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 class="keyword">const</span> router = <span class="keyword">new</span> VueRouter({</span><br><span class="line"> routes</span><br><span class="line">})</span><br><span class="line"></span><br><span class="line"><span class="comment">// 挂载路由导航守卫</span></span><br><span class="line">router.beforeEach(<span class="function">(<span class="params">to, <span class="keyword">from</span>, next</span>) =></span> {</span><br><span class="line"> <span class="comment">// to:将要访问的路径</span></span><br><span class="line"> <span class="comment">// from:从哪里访问的路径</span></span><br><span class="line"> <span class="comment">// next:之后要做的任务,是一个函数</span></span><br><span class="line"> <span class="comment">// next()放行, next('/URL')强制跳转的路径。</span></span><br><span class="line"> <span class="keyword">if</span> (to.path == <span class="string">'/login'</span>) <span class="keyword">return</span> next();<span class="comment">// 访问路径为登录</span></span><br><span class="line"> <span class="comment">// 获取flag</span></span><br><span class="line"> <span class="keyword">const</span> userInfo = <span class="built_in">window</span>.sessionStorage.getItem(<span class="string">"user"</span>);<span class="comment">// session取值</span></span><br><span class="line"> <span class="keyword">if</span> (!userInfo) <span class="keyword">return</span> next(<span class="string">'/login'</span>);<span class="comment">// 没登录去登录</span></span><br><span class="line"> next();</span><br><span class="line">})</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> router</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> Vue <span class="keyword">from</span> <span class="string">'vue'</span></span><br><span class="line"><span class="keyword">import</span> App <span class="keyword">from</span> <span class="string">'./App.vue'</span></span><br><span class="line"><span class="keyword">import</span> router <span class="keyword">from</span> <span class="string">'./router'</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">'./plugins/element.js'</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">'./assets/css/global.css'</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">'./assets/font/iconfont.css'</span></span><br><span class="line"><span class="keyword">import</span> axios <span class="keyword">from</span> <span class="string">'axios'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//挂载axios</span></span><br><span class="line">Vue.prototype.$http = axios</span><br><span class="line"><span class="comment">//设置访问根路径</span></span><br><span class="line">axios.defaults.baseURL = <span class="string">"http://localhost:8081"</span></span><br><span class="line"></span><br><span class="line">Vue.config.productionTip = <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> Vue({</span><br><span class="line"> router,</span><br><span class="line"> render: <span class="function"><span class="params">h</span> =></span> h(App)</span><br><span class="line">}).$mount(<span class="string">'#app'</span>)</span><br></pre></td></tr></table></figure>
<h2 id="SpringBoot(后端)"><a href="#SpringBoot(后端)" class="headerlink" title="SpringBoot(后端)"></a>SpringBoot(后端)</h2><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">UserController</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Autowired</span></span><br><span class="line"> <span class="keyword">private</span> UserDao userDao;</span><br><span class="line"></span><br><span class="line"> <span class="meta">@GetMapping("/allUser")</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">getUserList</span><span class="params">(QueryInfo queryInfo)</span></span>{</span><br><span class="line"> <span class="keyword">int</span> numbers = userDao.getUserCounts(<span class="string">"%"</span> + queryInfo.getQuery() + <span class="string">"%"</span>);</span><br><span class="line"> <span class="keyword">int</span> pageStart = (queryInfo.getPageNum()-<span class="number">1</span>)*queryInfo.getPageSize();</span><br><span class="line"> List<User> users = userDao.getAllUser(<span class="string">"%"</span>+queryInfo.getQuery()+<span class="string">"%"</span>,pageStart,queryInfo.getPageSize());</span><br><span class="line"> HashMap<String, Object> res = <span class="keyword">new</span> HashMap<>();</span><br><span class="line"> res.put(<span class="string">"numbers"</span>,numbers);</span><br><span class="line"> res.put(<span class="string">"data"</span>,users);</span><br><span class="line"> <span class="keyword">return</span> JSON.toJSONString(res);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@GetMapping("/userState")</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">updateUserState</span><span class="params">(<span class="meta">@RequestParam("id")</span> Integer id,</span></span></span><br><span class="line"><span class="function"><span class="params"> <span class="meta">@RequestParam("state")</span> Boolean state)</span></span>{</span><br><span class="line"> <span class="keyword">int</span> i = userDao.updateState(id, state);</span><br><span class="line"> <span class="keyword">return</span> i ><span class="number">0</span>?<span class="string">"success"</span>:<span class="string">"error"</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@PostMapping("/addUser")</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">addUser</span><span class="params">(<span class="meta">@RequestBody</span> User user)</span></span>{</span><br><span class="line"> user.setRole(<span class="string">"普通用户"</span>);</span><br><span class="line"> user.setState(<span class="keyword">false</span>);</span><br><span class="line"> user.setPassword(MD5Utils.code(user.getPassword()));</span><br><span class="line"> <span class="keyword">int</span> i = userDao.addUser(user);</span><br><span class="line"> <span class="keyword">return</span> i><span class="number">0</span>?<span class="string">"success"</span>:<span class="string">"error"</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@GetMapping("/deleteUser")</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">deleteUser</span><span class="params">(<span class="keyword">int</span> id)</span></span>{</span><br><span class="line"> <span class="keyword">int</span> i = userDao.deleteUser(id);</span><br><span class="line"> <span class="keyword">return</span> i><span class="number">0</span>?<span class="string">"success"</span>:<span class="string">"error"</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@GetMapping("/getUpdateUser")</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">getUpdateUser</span><span class="params">(<span class="keyword">int</span> id)</span></span>{</span><br><span class="line"> User user = userDao.getUpdateUser(id);</span><br><span class="line"> <span class="keyword">return</span> JSON.toJSONString(user);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@PostMapping("/updateUser")</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">updateUser</span><span class="params">(<span class="meta">@RequestBody</span> User user)</span></span>{</span><br><span class="line"> user.setPassword(MD5Utils.code(user.getPassword()));</span><br><span class="line"> <span class="keyword">int</span> i = userDao.updateUser(user);</span><br><span class="line"> <span class="keyword">return</span> i><span class="number">0</span>?<span class="string">"success"</span>:<span class="string">"error"</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>UserMapper.xml</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="meta"><?xml version="1.0" encoding="UTF-8" ?></span></span><br><span class="line"><span class="meta"><!DOCTYPE <span class="meta-keyword">mapper</span></span></span><br><span class="line"><span class="meta"> <span class="meta-keyword">PUBLIC</span> <span class="meta-string">"-//mybatis.org//DTD Mapper 3.0//EN"</span></span></span><br><span class="line"><span class="meta"> <span class="meta-string">"http://mybatis.org/dtd/mybatis-3-mapper.dtd"</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="name">mapper</span> <span class="attr">namespace</span>=<span class="string">"com.fanchen.sport.dao.UserDao"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">select</span> <span class="attr">id</span>=<span class="string">"getUserByMessage"</span> <span class="attr">resultType</span>=<span class="string">"com.fanchen.sport.pojo.User"</span>></span></span><br><span class="line"> select * from easyuser where username = #{username} and state = 1</span><br><span class="line"> <span class="tag"></<span class="name">select</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">select</span> <span class="attr">id</span>=<span class="string">"getAllUser"</span> <span class="attr">resultType</span>=<span class="string">"com.fanchen.sport.pojo.User"</span>></span></span><br><span class="line"> SELECT * FROM easyuser</span><br><span class="line"> <span class="tag"><<span class="name">if</span> <span class="attr">test</span>=<span class="string">"username !=null "</span>></span></span><br><span class="line"> WHERE username like #{username}</span><br><span class="line"> <span class="tag"></<span class="name">if</span>></span></span><br><span class="line"> LIMIT #{pageStart},#{pageSize}</span><br><span class="line"> <span class="tag"></<span class="name">select</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">select</span> <span class="attr">id</span>=<span class="string">"getUserCounts"</span> <span class="attr">resultType</span>=<span class="string">"java.lang.Integer"</span>></span></span><br><span class="line"> SELECT count(*) FROM `easyuser`</span><br><span class="line"> <span class="tag"><<span class="name">if</span> <span class="attr">test</span>=<span class="string">"username !=null "</span>></span></span><br><span class="line"> WHERE username like #{username}</span><br><span class="line"> <span class="tag"></<span class="name">if</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">select</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">update</span> <span class="attr">id</span>=<span class="string">"updateState"</span>></span></span><br><span class="line"> UPDATE easyuser SET state = #{state} WHERE id = #{id}</span><br><span class="line"> <span class="tag"></<span class="name">update</span>></span></span><br><span class="line"> </span><br><span class="line"> <span class="tag"><<span class="name">insert</span> <span class="attr">id</span>=<span class="string">"addUser"</span>></span></span><br><span class="line"> insert into easyuser (username,password,email,role,state) values (#{username},#{password},#{email},#{role},#{state})</span><br><span class="line"> <span class="tag"></<span class="name">insert</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">delete</span> <span class="attr">id</span>=<span class="string">"deleteUser"</span>></span></span><br><span class="line"> delete from easyuser where id = #{id}</span><br><span class="line"> <span class="tag"></<span class="name">delete</span>></span></span><br><span class="line"> </span><br><span class="line"> <span class="tag"><<span class="name">select</span> <span class="attr">id</span>=<span class="string">"getUpdateUser"</span> <span class="attr">resultType</span>=<span class="string">"com.fanchen.sport.pojo.User"</span>></span></span><br><span class="line"> select * from easyuser where id = #{id}</span><br><span class="line"> <span class="tag"></<span class="name">select</span>></span></span><br><span class="line"> </span><br><span class="line"> <span class="tag"><<span class="name">update</span> <span class="attr">id</span>=<span class="string">"updateUser"</span>></span></span><br><span class="line"> update easyuser set username = #{username}, password = #{password},email = #{email} where id = #{id}</span><br><span class="line"> <span class="tag"></<span class="name">update</span>></span></span><br><span class="line"><span class="tag"></<span class="name">mapper</span>></span></span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>Web学习</category>
</categories>
<tags>
<tag>Java</tag>
<tag>Vue</tag>
<tag>前后端分离</tag>
</tags>
</entry>
<entry>
<title>常大教务成绩爬取</title>
<url>/posts/e6c4ccf7/</url>
<content><![CDATA[<h1 id="常州大学官网-教务成绩信息爬取"><a href="#常州大学官网-教务成绩信息爬取" class="headerlink" title="常州大学官网-教务成绩信息爬取"></a>常州大学官网-教务成绩信息爬取</h1><h2 id="遇到的问题"><a href="#遇到的问题" class="headerlink" title="遇到的问题"></a>遇到的问题</h2><ul>
<li>cookie问题 由requests下的session解决</li>
<li>lxml下的etree负责解析网页数据</li>
<li>封装账号信息post模拟登录</li>
<li>在页面中的隐含域下获取请求的参数值,如lt,execution</li>
</ul>
<a id="more"></a>
<h2 id="代码编写"><a href="#代码编写" class="headerlink" title="代码编写"></a>代码编写</h2><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">from</span> lxml <span class="keyword">import</span> etree</span><br><span class="line"></span><br><span class="line">login_url = <span class="string">'http://sso.cczu.edu.cn/sso/login?service=http%3A%2F%2Fs.cczu.edu.cn%2F'</span></span><br><span class="line">home_url = <span class="string">'http://219.230.159.132/web_cas/web_cas_login_jwgl.aspx'</span></span><br><span class="line">grade_url = <span class="string">'http://219.230.159.132/web_cjgl/cx_cj_xh.aspx'</span></span><br><span class="line">headers = {</span><br><span class="line"> <span class="string">'User-Agent'</span>: <span class="string">'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '</span></span><br><span class="line"> <span class="string">'Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66 '</span></span><br><span class="line">}</span><br><span class="line">session = requests.session()</span><br><span class="line">login_page_data = etree.HTML(session.get(url=login_url, headers=headers).content.decode())</span><br><span class="line">execution = login_page_data.xpath(<span class="string">'//input[@name="execution"]/@value'</span>)[<span class="number">0</span>]</span><br><span class="line">lt = login_page_data.xpath(<span class="string">'//input[@name="lt"]/@value'</span>)[<span class="number">0</span>]</span><br><span class="line">data = {</span><br><span class="line"> <span class="string">'username'</span>: <span class="string">'学号'</span>,</span><br><span class="line"> <span class="string">'password'</span>: <span class="string">'密码'</span>,</span><br><span class="line"> <span class="string">'lt'</span>: lt,</span><br><span class="line"> <span class="string">'execution'</span>: execution,</span><br><span class="line"> <span class="string">'_eventId'</span>: <span class="string">'submit'</span>,</span><br><span class="line"> <span class="string">'useVCode'</span>: <span class="string">'false'</span></span><br><span class="line">}</span><br><span class="line">session.post(url=login_url, data=data, headers=headers)</span><br><span class="line">session.get(url=home_url, headers=headers)</span><br><span class="line">grade_page = session.get(url=grade_url, headers=headers).content.decode()</span><br><span class="line">grade_data = etree.HTML(grade_page)</span><br><span class="line">trs = grade_data.xpath(<span class="string">'//table[@id="gvcj1"]/tr[@class="dg1-item"]'</span>)</span><br><span class="line"><span class="keyword">for</span> tr <span class="keyword">in</span> trs:</span><br><span class="line"> s_id = tr.xpath(<span class="string">'./td[1]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> s_name = tr.xpath(<span class="string">'./td[2]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> s_term = tr.xpath(<span class="string">'./td[3]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> s_subject = tr.xpath(<span class="string">'./td[4]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> s_type = tr.xpath(<span class="string">'./td[5]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> s_grade = tr.xpath(<span class="string">'./td[6]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> s_properties = tr.xpath(<span class="string">'./td[7]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> s_point = tr.xpath(<span class="string">'./td[8]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> s_time = tr.xpath(<span class="string">'./td[9]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> s_code = tr.xpath(<span class="string">'./td[10]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> s_hour = tr.xpath(<span class="string">'./td[11]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> print(<span class="string">' 学号:'</span> + s_id + <span class="string">'\n'</span>, <span class="string">'姓名:'</span> + s_name + <span class="string">'\n'</span>, <span class="string">'学期:'</span> + s_term + <span class="string">'\n'</span>, <span class="string">'科目:'</span> + s_subject + <span class="string">'\n'</span>,</span><br><span class="line"> <span class="string">'类别:'</span> + s_type + <span class="string">'\n'</span>, <span class="string">'学分:'</span> + s_grade + <span class="string">'\n'</span>, <span class="string">'分数:'</span> + s_properties + <span class="string">'\n'</span>,</span><br><span class="line"> <span class="string">'性质:'</span> + s_point + <span class="string">'\n'</span>, <span class="string">'绩点:'</span> + s_time + <span class="string">'\n'</span>,</span><br><span class="line"> <span class="string">'课程代码:'</span> + s_code + <span class="string">'\n'</span>, <span class="string">'课时:'</span> + s_hour + <span class="string">'\n'</span>)</span><br><span class="line"></span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>爬虫学习</category>
</categories>
<tags>
<tag>Python</tag>
<tag>教务系统</tag>
<tag>成绩查询</tag>
</tags>
</entry>
<entry>
<title>微信聊天记录数据库解密并导出</title>
<url>/posts/7de13740/</url>
<content><![CDATA[<h1 id="微信数据库解码"><a href="#微信数据库解码" class="headerlink" title="微信数据库解码"></a>微信数据库解码</h1><p><img src="https://pic.rmb.bdstatic.com/bjh/bfe8f02b3a0bcb12f69389140194efc5.png"></p>
<a id="more"></a>
<p>上图为导出后的聊天信息数据的表格文件,接下来请看我的操作步骤。</p>
<h2 id="工具准备"><a href="#工具准备" class="headerlink" title="工具准备"></a>工具准备</h2><ol>
<li>夜神模拟器 并安装微信</li>
<li>PC版微信 以及 你正在使用的有聊天记录的手机(Android IOS都可以)</li>
<li>SQLCipher 用来解密数据库</li>
</ol>
<h2 id="获取微信的数据库文件"><a href="#获取微信的数据库文件" class="headerlink" title="获取微信的数据库文件"></a>获取微信的数据库文件</h2><p>首先用正在使用的手机登陆微信,再登录PC版微信(两个设备需要在同一局域网下),然后使用备份与恢复。</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/23bd5fb3ff994c45111a1a8fd425bb1d.png"></p>
<p>然后选择备份连天记录到电脑。</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/3c921bdb7183459aa5827f345f971317.png"></p>
<p>在手机上确定,并可以指定聊天记录或者全部备份。</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/244a76ece3d858e8fadf77ecf1e87355.png"></p>
<p>这是保存在电脑上的备份数据文件,因为比较难于解密和分析,所以我们不做处理。接下来将聊天记录恢复到安卓模拟器中,再进行数据库的提取。</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/19ca7fc5cf2ec8da7fd62b5fb3bce215.png"></p>
<p>登录好模拟器上的微信后,选择恢复聊天记录到手机,并在模拟器上确认。恢复聊天记录完成后,打开文件管理器。</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/ea86ff2d3983193994c061051c5bdac4.png"></p>
<p>数据库文件在<strong>根目录/data/data/com.tencent.mm/MicroMsg</strong>中。加密的数据库文件在两个长名字文件夹之一中,优先选择<strong>修改日期最新</strong>的那个。</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/1a01fce9f73c6400b00b85d18d05dd64.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/7cd632942a41f87df4b7391b61e71f93.png"></p>
<h2 id="获取数据库密码"><a href="#获取数据库密码" class="headerlink" title="获取数据库密码"></a>获取数据库密码</h2><p>在下图的路径中找到对应的xml文件,其中有账号对应的UIN号。</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/2dd5ad072b0d65deb748319fe9ad97e5.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/8ed9911140cdea860509418012ff37bd.png"></p>
<p>在模拟器设置中查看自己的IMEI号。</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/1762bcfa593d9675137686277f87f2bb.png"></p>
<p>在加密网站中,将IMEI和UIN号进行拼接(<strong>保留负号</strong>),加密方式选择<strong>32位小</strong>。</p>
<p><a href="https://link.zhihu.com/?target=https://tool.chinaz.com/tools/md5.aspx">MD5在线加密/解密/破解 - 站长工具</a></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/c76dda4055f8b30e2001b55e0bcf8786.png"></p>
<h2 id="数据库处理"><a href="#数据库处理" class="headerlink" title="数据库处理"></a>数据库处理</h2><p>根据拿到的密码查看数据库。</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/79523907938a6f6318d818b9989bb4e5.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/f10b4d50439b4236899764df097623f6.png"></p>
<p>导出为表格文件。</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/cb7088579a9c22beb0e4e08b9a3510cd.png"></p>
<h2 id="密码不对的情况"><a href="#密码不对的情况" class="headerlink" title="密码不对的情况"></a>密码不对的情况</h2><p>如果出现这样的情况说明你的密码不对。</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/6a17ff1af5205835e77b51b31fac58ae.png"></p>
<p>可以尝试使用MD5加密 1234567890ABCDEF + UIN生成的前七位字符试一下。</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/80f2edfa24b314dc804ce9fe4574df0b.png"></p>
<h2 id="聊天数据整理"><a href="#聊天数据整理" class="headerlink" title="聊天数据整理"></a>聊天数据整理</h2><p>使用python的jieba分词等,对csv文件进行数据清洗,因为太简单就不附上代码了,下面直接放上成品图。</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/82b8d74eab4559b4a485b3a49291c3d3.png"></p>
]]></content>
<categories>
<category>学习</category>
</categories>
<tags>
<tag>Python</tag>
</tags>
</entry>
<entry>
<title>微博个人主页的信息爬取</title>
<url>/posts/989be291/</url>
<content><![CDATA[<h2 id="微博个人主页的信息爬取"><a href="#微博个人主页的信息爬取" class="headerlink" title="微博个人主页的信息爬取"></a>微博个人主页的信息爬取</h2><p><strong>闲话少说,先进入分析过程。</strong><br><strong>因为相对而言移动端的界面会比较好爬取,所以今天我们爬取移动端微博的页面,如下:</strong><br><img src="https://img-blog.csdnimg.cn/20210103162026854.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
<a id="more"></a>
<p>这里是前后端分离异步加载的数据,所以我们去抓包工具下寻找对应的接口地址:<br><img src="https://img-blog.csdnimg.cn/20210103162328461.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>很明显可以看到crads下对应了多条数据,而其中的mblog下存放着对应微博的相关数据:<br><img src="https://img-blog.csdnimg.cn/20210103162516499.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>不要着急现在就去解析界面数据,先去看看下一页的加载,怎样去请求下一条数据:<br><img src="https://img-blog.csdnimg.cn/20210103162816242.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>对比看到多出了一个since_id的数据,发现这个数据的来源是上一条json数据中的:<br><img src="https://img-blog.csdnimg.cn/20210103163205858.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>到这里我们的分析就结束了,接下来进行代码的编写。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">from</span> urllib.parse <span class="keyword">import</span> urlencode</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"></span><br><span class="line"><span class="comment"># 个人微博内容循环爬取,基于强大的requests库</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 伪装头</span></span><br><span class="line">headers = {</span><br><span class="line"> <span class="string">"Host"</span>: <span class="string">"m.weibo.cn"</span>,</span><br><span class="line"> <span class="string">"Referer"</span>: <span class="string">"https://m.weibo.cn/u/6816603335"</span>,</span><br><span class="line"> <span class="string">"user-agent"</span>: <span class="string">"Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, "</span></span><br><span class="line"> <span class="string">"like Gecko) Chrome/87.0.4280.88 Mobile Safari/537.36 Edg/87.0.664.66 "</span>,</span><br><span class="line"> <span class="string">"X-Requested-With"</span>: <span class="string">"XMXLHttpRequest"</span></span><br><span class="line">}</span><br><span class="line"><span class="comment"># 接口链接模板</span></span><br><span class="line">base_url = <span class="string">'https://m.weibo.cn/api/container/getIndex?'</span></span><br><span class="line"><span class="comment"># ip代理池</span></span><br><span class="line">proxy_pool = [{<span class="string">'HTTP'</span>: <span class="string">'27.206.178.75:9000'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'175.42.122.226:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'175.42.158.31:9999'</span>},</span><br><span class="line"> {<span class="string">'HTTP'</span>: <span class="string">'175.44.109.38:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'42.238.91.46:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'175.42.158.146:9999'</span>},</span><br><span class="line"> {<span class="string">'HTTP'</span>: <span class="string">'123.160.69.171:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'115.221.240.115:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'183.166.110.5:9999'</span>},</span><br><span class="line"> {<span class="string">'HTTP'</span>: <span class="string">'125.121.123.115:8888'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'117.64.237.222:1133'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'182.87.39.163:9000'</span>},</span><br><span class="line"> {<span class="string">'HTTP'</span>: <span class="string">'120.79.184.148:8118'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'122.234.24.178:9000'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'175.42.158.74:9999'</span>}]</span><br><span class="line"><span class="comment"># 预定义字典</span></span><br><span class="line">weibo = {}</span><br></pre></td></tr></table></figure>
<p>接下来我们进行函数的编写,封装两个函数,用来请求数据 和 解析数据。<br>请求参数如下:<br><img src="https://img-blog.csdnimg.cn/20210103163707214.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 对链接的请求函数</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_page</span>(<span class="params">since_id=<span class="literal">None</span></span>):</span></span><br><span class="line"> <span class="comment"># 爬取用户的参数</span></span><br><span class="line"> params = {</span><br><span class="line"> <span class="string">'uid'</span>: <span class="string">'2946150412'</span>,</span><br><span class="line"> <span class="string">'luicode'</span>: <span class="string">'10000011'</span>,</span><br><span class="line"> <span class="string">'lfid'</span>: <span class="string">'231093_-_selffollowed'</span>,</span><br><span class="line"> <span class="string">'type'</span>: <span class="string">'uid'</span>,</span><br><span class="line"> <span class="string">'value'</span>: <span class="string">'2946150412'</span>,</span><br><span class="line"> <span class="string">'containerid'</span>: <span class="string">'1076032946150412'</span>,</span><br><span class="line"> <span class="string">'since_id'</span>: since_id</span><br><span class="line"> }</span><br><span class="line"> <span class="comment"># url拼接</span></span><br><span class="line"> url = base_url + urlencode(params)</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> <span class="comment"># 对拼接字符串进行访问</span></span><br><span class="line"> response = requests.get(url=url, headers=headers, proxies=random.choice(proxy_pool))</span><br><span class="line"> <span class="keyword">if</span> response.status_code == <span class="number">200</span>:</span><br><span class="line"> <span class="comment"># 响应成功后,将返回的json数据解析,返回json和其中的since_id</span></span><br><span class="line"> <span class="comment"># since_id是为了循环爬取下一条</span></span><br><span class="line"> json = response.json()</span><br><span class="line"> next_since_id = json.get(<span class="string">'data'</span>).get(<span class="string">'cardlistInfo'</span>).get(<span class="string">'since_id'</span>)</span><br><span class="line"> <span class="keyword">return</span> json, next_since_id</span><br><span class="line"> <span class="keyword">except</span> requests.ConnectionError <span class="keyword">as</span> e:</span><br><span class="line"> <span class="comment"># 失败 控制台抛出异常</span></span><br><span class="line"> print(<span class="string">"错误:"</span>, e.args)</span><br></pre></td></tr></table></figure>
<p>上面的函数会返回一个json对象和since_id的数据,json对象用来解析微博的对应信息,since_id为我们的下次爬取提供参数</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 解析传回来的json</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">parse_page</span>(<span class="params">json</span>):</span></span><br><span class="line"> <span class="comment"># 部分card属性下,存放着mblog,即是对应的微博内容</span></span><br><span class="line"> cards = json.get(<span class="string">'data'</span>).get(<span class="string">'cards'</span>)</span><br><span class="line"> <span class="keyword">for</span> card <span class="keyword">in</span> cards:</span><br><span class="line"> mblog = card.get(<span class="string">'mblog'</span>)</span><br><span class="line"> <span class="comment"># 循环遍历,获取对应的每一条数据,有mblog属性再解析</span></span><br><span class="line"> <span class="keyword">if</span> mblog:</span><br><span class="line"> <span class="comment"># 发布微博的来源</span></span><br><span class="line"> weibo[<span class="string">'source'</span>] = mblog[<span class="string">'source'</span>]</span><br><span class="line"> <span class="comment"># 创建时间</span></span><br><span class="line"> weibo[<span class="string">'created_at'</span>] = mblog[<span class="string">'created_at'</span>]</span><br><span class="line"> <span class="comment"># 文本内容</span></span><br><span class="line"> weibo[<span class="string">'raw_text'</span>] = mblog[<span class="string">'raw_text'</span>]</span><br><span class="line"> <span class="comment"># 图片</span></span><br><span class="line"> weibo[<span class="string">'original_pic'</span>] = mblog.get(<span class="string">'original_pic'</span>)</span><br><span class="line"> <span class="comment"># 图床的相关处理</span></span><br><span class="line"> pics = []</span><br><span class="line"> p = mblog.get(<span class="string">'pics'</span>)</span><br><span class="line"> <span class="keyword">if</span> p:</span><br><span class="line"> <span class="keyword">for</span> pic <span class="keyword">in</span> p:</span><br><span class="line"> pics.append(pic[<span class="string">'url'</span>])</span><br><span class="line"> weibo[<span class="string">'pics'</span>] = <span class="string">' , '</span>.join(pics)</span><br><span class="line"> <span class="comment"># 提交</span></span><br><span class="line"> <span class="keyword">yield</span> weibo</span><br></pre></td></tr></table></figure>
<p>最后封装一个函数调用上面的两个方法,并做到循环请求和解析的效果。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 调用封装好的函数并进行持久化存储</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">domain</span>():</span></span><br><span class="line"> <span class="keyword">global</span> return_data</span><br><span class="line"> <span class="comment"># 循环请求数据接口,200次已经很多了,获取不到对应的since_id时,程序会报错停止</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">200</span>):</span><br><span class="line"> <span class="comment"># 由于第一页没有since_id参数,这里特殊处理</span></span><br><span class="line"> <span class="keyword">if</span> i == <span class="number">0</span>:</span><br><span class="line"> print(<span class="string">"正在爬取第{}页...."</span>.<span class="built_in">format</span>(i + <span class="number">1</span>))</span><br><span class="line"> <span class="comment"># 第一个接口没有since_id参数 传值为空</span></span><br><span class="line"> return_data = get_page()</span><br><span class="line"> <span class="comment"># 下面的语句参照else中的注释</span></span><br><span class="line"> results = parse_page(return_data[<span class="number">0</span>])</span><br><span class="line"> <span class="keyword">for</span> res <span class="keyword">in</span> results:</span><br><span class="line"> img = res.get(<span class="string">'original_pic'</span>)</span><br><span class="line"> pics = res.get(<span class="string">'pics'</span>)</span><br><span class="line"> <span class="keyword">if</span> img <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line"> img = <span class="string">"无"</span></span><br><span class="line"> <span class="keyword">if</span> pics <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line"> pics = <span class="string">"无"</span></span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">'test.txt'</span>, <span class="string">'a'</span>, encoding=<span class="string">'utf8'</span>) <span class="keyword">as</span> file:</span><br><span class="line"> file.write(<span class="string">'时间:'</span> + res[<span class="string">'created_at'</span>] + <span class="string">'\n'</span> + <span class="string">'来源:'</span> + res[<span class="string">'source'</span>] + <span class="string">'\n'</span></span><br><span class="line"> + <span class="string">'内容:'</span> + res[<span class="string">'raw_text'</span>] + <span class="string">'\n'</span> + <span class="string">'附图链接地址:'</span> + img + <span class="string">'\n'</span></span><br><span class="line"> + <span class="string">'图床:'</span> + pics + <span class="string">'\n'</span> + <span class="string">'\n'</span>)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> print(<span class="string">"正在爬取第{}页...."</span>.<span class="built_in">format</span>(i + <span class="number">1</span>))</span><br><span class="line"> <span class="comment"># 传入返回的第二个值since_id</span></span><br><span class="line"> return_data = get_page(return_data[<span class="number">1</span>])</span><br><span class="line"> <span class="comment"># 传入解析的第一个值json对象</span></span><br><span class="line"> results = parse_page(return_data[<span class="number">0</span>])</span><br><span class="line"> <span class="comment"># 遍历提交的结果</span></span><br><span class="line"> <span class="keyword">for</span> res <span class="keyword">in</span> results:</span><br><span class="line"> <span class="comment"># 对照片和图床进行非空判断</span></span><br><span class="line"> img = res.get(<span class="string">'original_pic'</span>)</span><br><span class="line"> pics = res.get(<span class="string">'pics'</span>)</span><br><span class="line"> <span class="keyword">if</span> img <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line"> img = <span class="string">"无"</span></span><br><span class="line"> <span class="keyword">if</span> pics <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line"> pics = <span class="string">"无"</span></span><br><span class="line"> <span class="comment"># 持久化存储用文本实现</span></span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">'test.txt'</span>, <span class="string">'a'</span>, encoding=<span class="string">'utf8'</span>) <span class="keyword">as</span> file:</span><br><span class="line"> file.write(<span class="string">'时间:'</span> + res[<span class="string">'created_at'</span>] + <span class="string">'\n'</span> + <span class="string">'来源:'</span> + res[<span class="string">'source'</span>] + <span class="string">'\n'</span></span><br><span class="line"> + <span class="string">'内容:'</span> + res[<span class="string">'raw_text'</span>] + <span class="string">'\n'</span> + <span class="string">'附图链接地址:'</span> + img + <span class="string">'\n'</span></span><br><span class="line"> + <span class="string">'图床:'</span> + pics + <span class="string">'\n'</span> + <span class="string">'\n'</span>)</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>运行结果如下:<br><img src="https://img-blog.csdnimg.cn/20210103164347188.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>最后看一下我们的结果文件:<br><img src="https://img-blog.csdnimg.cn/20210103164430693.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br><img src="https://img-blog.csdnimg.cn/20210103164453243.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>可以看到最早的2015年的微博也获取到了,对应的图片链接也是可以访问没有问题的。<br><strong>注:案例仅供学习</strong></p>
]]></content>
<categories>
<category>爬虫学习</category>
</categories>
<tags>
<tag>Python</tag>
<tag>微博</tag>
</tags>
</entry>
<entry>
<title>按日期爬取b站弹幕二</title>
<url>/posts/24b45e76/</url>
<content><![CDATA[<font color=#999AAA >
上次的b站爬取需要手动输入日期等信息,这次直接在程序内根据时间差进行爬取,直接放上完整代码。
</font>
<h1 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h1><p>上次的分析链接在此:<a href="https://blog.csdn.net/HandsomeFishman/article/details/112171386">b站弹幕爬取分析</a><br><font color=#999AAA >直接附上完整代码:</font></p>
<a id="more"></a>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">from</span> lxml <span class="keyword">import</span> etree</span><br><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">from</span> wordcloud <span class="keyword">import</span> WordCloud</span><br><span class="line"><span class="keyword">import</span> jieba</span><br><span class="line"><span class="keyword">import</span> datetime</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">BarrageSpider</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span>(<span class="params">self, bv</span>):</span></span><br><span class="line"> <span class="comment"># 需要一个bv号,在接下来的代码中进行替换操作</span></span><br><span class="line"> self.bv = bv</span><br><span class="line"> self.video_name = <span class="literal">None</span></span><br><span class="line"> <span class="comment"># 不需要登录的弹幕接口地址 只能爬取部分弹幕</span></span><br><span class="line"> self.barrage_url = <span class="string">'https://comment.bilibili.com/{}.xml'</span></span><br><span class="line"> <span class="comment"># 需要登陆的弹幕接口地址 根据日期进行分类 需要循环爬取 最后归总数据</span></span><br><span class="line"> self.date_url = <span class="string">'https://api.bilibili.com/x/v2/dm/history?type=1&oid={}&date={}'</span> <span class="comment"># 2021-01-01</span></span><br><span class="line"> <span class="comment"># 点击按钮弹出日历的数据接口,这里我们用来作索引</span></span><br><span class="line"> self.index_url = <span class="string">'https://api.bilibili.com/x/v2/dm/history/index?type=1&oid={}&month={}'</span> <span class="comment"># 2021-01</span></span><br><span class="line"> <span class="comment"># 在抓包工具中找的一个简洁的请求,里面有我们需要的oid或者是cid</span></span><br><span class="line"> self.bv_url = <span class="string">'https://api.bilibili.com/x/player/pagelist?bvid='</span> + bv + <span class="string">'&jsonp=jsonp'</span></span><br><span class="line"> <span class="comment"># 视频时间获取</span></span><br><span class="line"> self.video_url = <span class="string">'https://www.bilibili.com/video/{}'</span>.<span class="built_in">format</span>(bv)</span><br><span class="line"> <span class="comment"># 不需要登录接口的伪装头</span></span><br><span class="line"> self.comment = {</span><br><span class="line"> <span class="string">'referer'</span>: <span class="string">'https://www.bilibili.com/'</span>,</span><br><span class="line"> <span class="string">'user-agent'</span>: <span class="string">'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '</span></span><br><span class="line"> <span class="string">'Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66 '</span></span><br><span class="line"> }</span><br><span class="line"> <span class="comment"># 需要登录的伪装头 因为需要登录 ip代理已经没有意义了 这里就不再使用IP代理</span></span><br><span class="line"> self.date_headers = {</span><br><span class="line"> <span class="string">"referer"</span>: <span class="string">"https://www.bilibili.com/"</span>,</span><br><span class="line"> <span class="string">"origin"</span>: <span class="string">"https://www.bilibili.com"</span>,</span><br><span class="line"> <span class="string">"cookie"</span>: <span class="string">"你的cookie 爬很久远的视频 会被封ip 后面接收到的都是空结果"</span>,</span><br><span class="line"> <span class="string">"user-agent"</span>: <span class="string">"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "</span></span><br><span class="line"> <span class="string">"Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66 "</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 从接口返回的json中获取到我们的cid 注: cid = oid</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">get_cid</span>(<span class="params">self</span>):</span></span><br><span class="line"> <span class="comment"># 定位到数据data中下面的cid</span></span><br><span class="line"> <span class="keyword">return</span> requests.get(url=self.bv_url, headers=self.comment).json()[<span class="string">'data'</span>][<span class="number">0</span>][<span class="string">'cid'</span>]</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">get_video_time</span>(<span class="params">self</span>):</span></span><br><span class="line"> time_data = requests.get(url=self.video_url, headers=self.comment).text</span><br><span class="line"> video_page = etree.HTML(time_data)</span><br><span class="line"> v_time = video_page.xpath(<span class="string">'//div[@class="video-data"]/span[3]/text()'</span>)[<span class="number">0</span>].split(<span class="string">' '</span>)[<span class="number">0</span>]</span><br><span class="line"> self.video_name = video_page.xpath(<span class="string">'//h1[@class="video-title"]/span/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">return</span> v_time</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 解析不需要登录的接口 返回类型是xml文件</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">parse_url</span>(<span class="params">self</span>):</span></span><br><span class="line"> <span class="comment"># 获取指定视频的cid/oid</span></span><br><span class="line"> cid = self.get_cid()</span><br><span class="line"> <span class="comment"># 对页面进行伪装请求,这里注意不要转换成text,使用二进制</span></span><br><span class="line"> response = requests.get(url=self.barrage_url.<span class="built_in">format</span>(cid), headers=self.comment).content</span><br><span class="line"> <span class="comment"># etree解析</span></span><br><span class="line"> data = etree.HTML(response)</span><br><span class="line"> <span class="comment"># 定位到所有的d元素</span></span><br><span class="line"> barrage_list = data.xpath(<span class="string">'//d'</span>)</span><br><span class="line"> <span class="keyword">for</span> barrage <span class="keyword">in</span> barrage_list:</span><br><span class="line"> <span class="comment"># 获取d元素的p属性值</span></span><br><span class="line"> info = barrage.xpath(<span class="string">'./@p'</span>)[<span class="number">0</span>].split(<span class="string">','</span>)</span><br><span class="line"> <span class="comment"># 获取弹幕内容</span></span><br><span class="line"> content = barrage.xpath(<span class="string">'./text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> item = {<span class="string">'出现时间'</span>: info[<span class="number">0</span>], <span class="string">'弹幕模式'</span>: info[<span class="number">1</span>], <span class="string">'字体大小'</span>: info[<span class="number">2</span>], <span class="string">'颜色'</span>: info[<span class="number">3</span>], <span class="string">'发送时间'</span>: info[<span class="number">4</span>], <span class="string">'弹幕池'</span>: info[<span class="number">5</span>],</span><br><span class="line"> <span class="string">'用户ID'</span>: info[<span class="number">6</span>], <span class="string">'rowID'</span>: info[<span class="number">7</span>], <span class="string">'内容'</span>: content}</span><br><span class="line"> <span class="comment"># 因为这只是一部分弹幕 所以就没有进行持久化存储 没有必要</span></span><br><span class="line"> print(item)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 循环爬取所有弹幕 需要传入month的数据 根据视频发布的日期到现在的所有月份</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">parse_date_url</span>(<span class="params">self, month</span>):</span></span><br><span class="line"> print(<span class="string">'正在爬取{}月份的数据'</span>.<span class="built_in">format</span>(month))</span><br><span class="line"> <span class="comment"># 存放爬到的数据</span></span><br><span class="line"> result = []</span><br><span class="line"> <span class="comment"># 获取视频的oid</span></span><br><span class="line"> oid = self.get_cid()</span><br><span class="line"> <span class="comment"># 获取日期索引</span></span><br><span class="line"> date_by_month = requests.get(url=self.index_url.<span class="built_in">format</span>(oid, month), headers=self.date_headers).json().get(</span><br><span class="line"> <span class="string">'data'</span>)</span><br><span class="line"> <span class="comment"># 根据日期索引循环请求</span></span><br><span class="line"> <span class="keyword">if</span> date_by_month:</span><br><span class="line"> <span class="keyword">for</span> day <span class="keyword">in</span> date_by_month:</span><br><span class="line"> print(<span class="string">'{}月份数据下的{}'</span>.<span class="built_in">format</span>(month, day))</span><br><span class="line"> <span class="comment"># 注意还是二进制文件</span></span><br><span class="line"> date_page = requests.get(url=self.date_url.<span class="built_in">format</span>(oid, day), headers=self.date_headers).content</span><br><span class="line"> date_data = etree.HTML(date_page)</span><br><span class="line"> <span class="comment"># 解析到到所有的d元素</span></span><br><span class="line"> barrage_list = date_data.xpath(<span class="string">'//d'</span>)</span><br><span class="line"> <span class="comment"># 循环解析数据</span></span><br><span class="line"> <span class="keyword">for</span> barrage <span class="keyword">in</span> barrage_list:</span><br><span class="line"> <span class="comment"># 获取d元素的p属性值</span></span><br><span class="line"> things = barrage.xpath(<span class="string">'./@p'</span>)[<span class="number">0</span>].split(<span class="string">','</span>)</span><br><span class="line"> <span class="comment"># 获取弹幕内容 并去掉所有空格</span></span><br><span class="line"> content = barrage.xpath(<span class="string">'./text()'</span>)[<span class="number">0</span>].replace(<span class="string">" "</span>, <span class="string">""</span>)</span><br><span class="line"> item = {<span class="string">'出现时间'</span>: things[<span class="number">0</span>], <span class="string">'弹幕模式'</span>: things[<span class="number">1</span>], <span class="string">'字体大小'</span>: things[<span class="number">2</span>], <span class="string">'颜色'</span>: things[<span class="number">3</span>], <span class="string">'发送时间'</span>: things[<span class="number">4</span>],</span><br><span class="line"> <span class="string">'弹幕池'</span>: things[<span class="number">5</span>],</span><br><span class="line"> <span class="string">'用户ID'</span>: things[<span class="number">6</span>], <span class="string">'rowID'</span>: things[<span class="number">7</span>], <span class="string">'内容'</span>: content}</span><br><span class="line"> result.append(item)</span><br><span class="line"> <span class="comment"># 返回封装好的数据</span></span><br><span class="line"> <span class="keyword">return</span> result</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_month</span>(<span class="params">self</span>):</span></span><br><span class="line"> start_day = datetime.datetime.strptime(self.get_video_time(), <span class="string">'%Y-%m-%d'</span>)</span><br><span class="line"> end_day = datetime.date.today()</span><br><span class="line"> months = (end_day.year - start_day.year) * <span class="number">12</span> + end_day.month - start_day.month</span><br><span class="line"> m_list = []</span><br><span class="line"> <span class="keyword">for</span> mon <span class="keyword">in</span> <span class="built_in">range</span>(start_day.month - <span class="number">1</span>, start_day.month + months):</span><br><span class="line"> <span class="keyword">if</span> (mon % <span class="number">12</span> + <span class="number">1</span>) < <span class="number">10</span>:</span><br><span class="line"> m_list.append(<span class="string">'{}-0{}'</span>.<span class="built_in">format</span>(start_day.year + mon // <span class="number">12</span>, mon % <span class="number">12</span> + <span class="number">1</span>))</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> m_list.append(<span class="string">'{}-{}'</span>.<span class="built_in">format</span>(start_day.year + mon // <span class="number">12</span>, mon % <span class="number">12</span> + <span class="number">1</span>))</span><br><span class="line"> <span class="keyword">return</span> m_list</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">wordCloud</span>(<span class="params">self</span>):</span></span><br><span class="line"> WordCloud(font_path=<span class="string">"C:/Windows/Fonts/simfang.ttf"</span>, background_color=<span class="string">'white'</span>, scale=<span class="number">16</span>).generate(<span class="string">" "</span>.join(</span><br><span class="line"> [c <span class="keyword">for</span> c <span class="keyword">in</span> jieba.cut(<span class="string">""</span>.join(<span class="built_in">str</span>((pd.read_csv(<span class="string">'{}弹幕池数据集.csv'</span>.<span class="built_in">format</span>(self.video_name))[<span class="string">'内容'</span>]).tolist()))) <span class="keyword">if</span></span><br><span class="line"> <span class="built_in">len</span>(c) > <span class="number">1</span>])).to_file(</span><br><span class="line"> <span class="string">"{}词云.png"</span>.<span class="built_in">format</span>(self.video_name))</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"># 输入指定的视频bv号</span></span><br><span class="line"> bv_id = <span class="built_in">input</span>(<span class="string">'输入视频对应的bv号:'</span>)</span><br><span class="line"> <span class="comment"># new一个对象</span></span><br><span class="line"> spider = BarrageSpider(bv_id)</span><br><span class="line"> spider.parse_month()</span><br><span class="line"> <span class="comment"># 请求今年1月和去年12月的数据 并合并数据</span></span><br><span class="line"> word_data = []</span><br><span class="line"> months = spider.parse_month()</span><br><span class="line"> <span class="comment"># 循环遍历爬取</span></span><br><span class="line"> <span class="keyword">for</span> month <span class="keyword">in</span> months:</span><br><span class="line"> word = spider.parse_date_url(month)</span><br><span class="line"> word_data.extend(word)</span><br><span class="line"> <span class="comment"># 数据格式化处理 并输出csv格式文件</span></span><br><span class="line"> data = pd.DataFrame(word_data)</span><br><span class="line"> data.drop_duplicates(subset=[<span class="string">'rowID'</span>], keep=<span class="string">'first'</span>)</span><br><span class="line"> <span class="comment"># 字符集编码需要为utf-8-sig 不然会乱码</span></span><br><span class="line"> data.to_csv(<span class="string">'{}弹幕池数据集.csv'</span>.<span class="built_in">format</span>(spider.video_name), index=<span class="literal">False</span>, encoding=<span class="string">'utf-8-sig'</span>)</span><br><span class="line"> <span class="comment"># # 生成词云</span></span><br><span class="line"> spider.wordCloud()</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h1 id="运行结果"><a href="#运行结果" class="headerlink" title="运行结果"></a>运行结果</h1><p><img src="https://img-blog.csdnimg.cn/2021010714345345.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br><img src="https://img-blog.csdnimg.cn/20210107143523237.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br><img src="https://img-blog.csdnimg.cn/20210107143558160.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>这里只有十八万行…是因为刚开始测试的时候忘记在月份前加0。代码里已经更正。<br>更正后 爬取了骚猪的视频:<br><img src="https://img-blog.csdnimg.cn/2021010717522992.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>视频上显示16万弹幕,实际则有67万,而且爬到19年后,获取的都为空数据,预测实际弹幕有100万左右。<br><img src="https://img-blog.csdnimg.cn/20210107175840869.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br><img src="https://img-blog.csdnimg.cn/20210107175851199.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
<p>可以通过多账号的方式爬取完整弹幕,这里就不做了。</p>
]]></content>
<categories>
<category>爬虫学习</category>
</categories>
<tags>
<tag>Python</tag>
<tag>B站</tag>
<tag>弹幕</tag>
</tags>
</entry>
<entry>
<title>数据结构-第三章-栈和队列</title>
<url>/posts/5116f53a/</url>
<content><![CDATA[<h1 id="栈的基本操作"><a href="#栈的基本操作" class="headerlink" title="栈的基本操作"></a>栈的基本操作</h1><p><img src="https://pic.rmb.bdstatic.com/bjh/15382f39117333117b6470477593053d.png"></p>
<a id="more"></a>
<h1 id="栈的顺序存储"><a href="#栈的顺序存储" class="headerlink" title="栈的顺序存储"></a>栈的顺序存储</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Maxsize 10</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data[Maxsize];</span><br><span class="line"> <span class="keyword">int</span> top;</span><br><span class="line">}SqStack;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">InitStack</span><span class="params">(SqStack& S)</span> </span>{</span><br><span class="line"> S.top = <span class="number">-1</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">isEmpty</span><span class="params">(SqStack S)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> S.top == <span class="number">-1</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">Push</span><span class="params">(SqStack& S, <span class="keyword">int</span> element)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (S.top == Maxsize - <span class="number">1</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"> S.data[++S.top] = element;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">Pop</span><span class="params">(SqStack& S)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (S.top == <span class="number">-1</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> S.data[S.top--];</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">GetTop</span><span class="params">(SqStack S)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (S.top == <span class="number">-1</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> S.data[S.top];</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">ShowStack</span><span class="params">(SqStack S)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i <= S.top; i++) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d "</span>, S.data[i]);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> SqStack S;</span><br><span class="line"> InitStack(S);</span><br><span class="line"> Push(S, <span class="number">1</span>);</span><br><span class="line"> Push(S, <span class="number">3</span>);</span><br><span class="line"> Push(S, <span class="number">5</span>);</span><br><span class="line"> Push(S, <span class="number">7</span>);</span><br><span class="line"> Push(S, <span class="number">9</span>);</span><br><span class="line"> <span class="keyword">if</span> (isEmpty(S)) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"空的\n"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"不是空的\n"</span>);</span><br><span class="line"> }</span><br><span class="line"> ShowStack(S);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"\n出栈的元素是:%d"</span>, Pop(S));</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"\n出栈的元素是:%d\n"</span>, Pop(S));</span><br><span class="line"> ShowStack(S);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/b3824ab532b7fbc47ce496678440bb4b.png"></p>
<p>另一种方式,初始化时top=0</p>
<figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Maxsize 10</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data[Maxsize];</span><br><span class="line"> <span class="keyword">int</span> top;</span><br><span class="line">}SqStack;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">InitStack</span><span class="params">(SqStack &S)</span> </span>{</span><br><span class="line"> S.top = <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">Push</span><span class="params">(SqStack &S, <span class="keyword">int</span> element)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (S.top == Maxsize)</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><span class="line"> S.data[S.top++] = element;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">Pop</span><span class="params">(SqStack &S)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (!S.data[<span class="number">0</span>])</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> S.data[--S.top];</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>共享栈</p>
<figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Maxsize 10</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data[Maxsize];</span><br><span class="line"> <span class="keyword">int</span> top0;</span><br><span class="line"> <span class="keyword">int</span> top1;</span><br><span class="line">}SqStack;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">InitStack</span><span class="params">(SqStack &S)</span> </span>{</span><br><span class="line"> S.top0 = <span class="number">-1</span>;</span><br><span class="line"> S.top1 = Maxsize;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>栈的链式存储</p>
<figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">LinkNode</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">LinkNode</span>* <span class="title">next</span>;</span></span><br><span class="line">}*LiStack;</span><br></pre></td></tr></table></figure>
<h1 id="队列的基本操作"><a href="#队列的基本操作" class="headerlink" title="队列的基本操作"></a>队列的基本操作</h1><p><img src="https://pic.rmb.bdstatic.com/bjh/76f11fdd5d493e9627900c9df7803820.png"></p>
<h1 id="队列的顺序实现"><a href="#队列的顺序实现" class="headerlink" title="队列的顺序实现"></a>队列的顺序实现</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Maxsize 10</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data[Maxsize];</span><br><span class="line"> <span class="keyword">int</span> front, rear;</span><br><span class="line">}SqQueue;</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">void</span> <span class="title">InitQueue</span><span class="params">(SqQueue &Q)</span> </span>{</span><br><span class="line"> Q.rear = Q.front = <span class="number">0</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"><span class="function"><span class="keyword">bool</span> <span class="title">isEmpty</span><span class="params">(SqQueue Q)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> Q.front == Q.rear;</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="function"><span class="keyword">bool</span> <span class="title">EnQueue</span><span class="params">(SqQueue &Q, <span class="keyword">int</span> element)</span> </span>{</span><br><span class="line"> <span class="comment">//判断队列是否已满</span></span><br><span class="line"> <span class="keyword">if</span> ((Q.rear + <span class="number">1</span>) % Maxsize == Q.front)</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><span class="line"> Q.data[Q.rear] = element;</span><br><span class="line"> Q.rear = (Q.rear + <span class="number">1</span>) % Maxsize;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</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"><span class="function"><span class="keyword">int</span> <span class="title">DeQueue</span><span class="params">(SqQueue &Q)</span> </span>{</span><br><span class="line"> <span class="comment">//判断队列是否为空</span></span><br><span class="line"> <span class="keyword">if</span> (Q.rear == Q.rear)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> element = Q.data[Q.front];</span><br><span class="line"> Q.front = (Q.front + <span class="number">1</span>) / Maxsize;</span><br><span class="line"> <span class="keyword">return</span> element;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">GetHead</span><span class="params">(SqQueue &Q)</span> </span>{</span><br><span class="line"> <span class="comment">//判断队列是否为空</span></span><br><span class="line"> <span class="keyword">if</span> (Q.rear == Q.front)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> Q.data[Q.front];</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h1 id="队列的链式实现"><a href="#队列的链式实现" class="headerlink" title="队列的链式实现"></a>队列的链式实现</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><malloc.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">LinkNode</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">LinkNode</span>* <span class="title">next</span>;</span></span><br><span class="line">}LinkNode;</span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> LinkNode* front, * rear;</span><br><span class="line">}LinkQueue;</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">void</span> <span class="title">InitQueue</span><span class="params">(LinkQueue &Q)</span> </span>{</span><br><span class="line"> Q.front = Q.rear = (LinkNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(LinkNode));</span><br><span class="line"> Q.front->next = <span class="literal">NULL</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"><span class="function"><span class="keyword">void</span> <span class="title">InitQueueNoHead</span><span class="params">(LinkQueue &Q)</span> </span>{</span><br><span class="line"> Q.front = Q.rear = <span class="literal">NULL</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"><span class="function"><span class="keyword">bool</span> <span class="title">isEmpty</span><span class="params">(LinkQueue Q)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> Q.front == Q.rear;</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="function"><span class="keyword">void</span> <span class="title">EnQueue</span><span class="params">(LinkQueue &Q, <span class="keyword">int</span> element)</span> </span>{</span><br><span class="line"> LinkNode* new_point = (LinkNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(LinkNode));</span><br><span class="line"> new_point->data = element;</span><br><span class="line"> new_point->next = <span class="literal">NULL</span>;</span><br><span class="line"> Q.rear->next = new_point;</span><br><span class="line"> Q.rear = new_point;</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="function"><span class="keyword">void</span> <span class="title">EnQueueNoHead</span><span class="params">(LinkQueue &Q, <span class="keyword">int</span> element)</span> </span>{</span><br><span class="line"> LinkNode* new_point = (LinkNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(LinkNode));</span><br><span class="line"> new_point->data = element;</span><br><span class="line"> new_point->next = <span class="literal">NULL</span>;</span><br><span class="line"> <span class="keyword">if</span> (Q.front == <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> Q.front = new_point;</span><br><span class="line"> Q.rear = new_point;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> Q.rear->next = new_point;</span><br><span class="line"> Q.rear = new_point;</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="function"><span class="keyword">void</span> <span class="title">DeQueue</span><span class="params">(LinkQueue &Q)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (Q.front == Q.rear)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"队列为空"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> LinkNode* point = Q.front->next;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"出队的元素是%d\n"</span>, point->data);</span><br><span class="line"> Q.front->next = point->next;</span><br><span class="line"> <span class="keyword">if</span> (Q.rear == point)</span><br><span class="line"> {</span><br><span class="line"> Q.rear = Q.front;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">free</span>(point);</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="function"><span class="keyword">void</span> <span class="title">DeQueueNoHead</span><span class="params">(LinkQueue &Q)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (Q.front = <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"队列为空"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> LinkNode* point = Q.front;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"出队的元素是%d\n"</span>, point->data);</span><br><span class="line"> Q.front = point->next;</span><br><span class="line"> <span class="keyword">if</span> (Q.rear == point)</span><br><span class="line"> {</span><br><span class="line"> Q.front = Q.rear = <span class="literal">NULL</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">free</span>(point);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">ShowQueue</span><span class="params">(LinkQueue Q)</span> </span>{</span><br><span class="line"> LinkNode* point = Q.front->next;</span><br><span class="line"> <span class="keyword">while</span> (point!= <span class="literal">NULL</span>) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d "</span>, point->data);</span><br><span class="line"> point = point->next;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line"> <span class="built_in">free</span>(point);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> LinkQueue Q;</span><br><span class="line"> InitQueue(Q);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i <= <span class="number">10</span>; i++)</span><br><span class="line"> {</span><br><span class="line"> EnQueue(Q, i);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (isEmpty(Q))</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"队列为空"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"队列不为空"</span>);</span><br><span class="line"> }</span><br><span class="line"> ShowQueue(Q);</span><br><span class="line"> DeQueue(Q);</span><br><span class="line"> DeQueue(Q);</span><br><span class="line"> DeQueue(Q);</span><br><span class="line"> EnQueue(Q, <span class="number">0</span>);</span><br><span class="line"> EnQueue(Q, <span class="number">1</span>);</span><br><span class="line"> EnQueue(Q, <span class="number">2</span>);</span><br><span class="line"> ShowQueue(Q);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/069590cce32148cc51763b80e2b86185.png"></p>
<h1 id="栈在括号匹配中的引用"><a href="#栈在括号匹配中的引用" class="headerlink" title="栈在括号匹配中的引用"></a>栈在括号匹配中的引用</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Maxsize 10</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">char</span> data[Maxsize];</span><br><span class="line"> <span class="keyword">int</span> top;</span><br><span class="line">}SqStack;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">InitStack</span><span class="params">(SqStack& S)</span> </span>{</span><br><span class="line"> S.top = <span class="number">-1</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">isEmpty</span><span class="params">(SqStack S)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> S.top == <span class="number">-1</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">Push</span><span class="params">(SqStack& S, <span class="keyword">char</span> element)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (S.top == Maxsize - <span class="number">1</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"> S.data[++S.top] = element;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">Pop</span><span class="params">(SqStack& S)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (S.top == <span class="number">-1</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> S.data[S.top--];</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">GetTop</span><span class="params">(SqStack S)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (S.top == <span class="number">-1</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> S.data[S.top];</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">ShowStack</span><span class="params">(SqStack S)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i <= S.top; i++) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d "</span>, S.data[i]);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">bracketCheck</span><span class="params">(<span class="keyword">char</span> str[], <span class="keyword">int</span> length)</span> </span>{</span><br><span class="line"> SqStack S;</span><br><span class="line"> InitStack(S);</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < length; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (str[i] == <span class="string">'('</span> || str[i] == <span class="string">'['</span> || str[i] == <span class="string">'{'</span>)</span><br><span class="line"> {</span><br><span class="line"> Push(S, str[i]);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (isEmpty(S))</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"栈为空"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">char</span> topElement = Pop(S);</span><br><span class="line"> <span class="keyword">if</span> (str[i] == <span class="string">')'</span> && topElement != <span class="string">'('</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"匹配不正确!"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (str[i] == <span class="string">']'</span> && topElement != <span class="string">'['</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"匹配不正确!"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (str[i] == <span class="string">'}'</span> && topElement != <span class="string">'{'</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"匹配不正确!"</span>);</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 class="keyword">if</span> (isEmpty(S))</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"匹配成功!"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"匹配失败!"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{ </span><br><span class="line"> <span class="keyword">char</span> str_char[] = { <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><br><span class="line"> bracketCheck(str_char, (<span class="keyword">sizeof</span>(str_char)/<span class="keyword">sizeof</span>(str_char[<span class="number">0</span>])));</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/eec0d16d0052e9bcb803c70320dd6d91.png"></p>
]]></content>
<categories>
<category>数据结构</category>
</categories>
<tags>
<tag>数据结构</tag>
<tag>考研</tag>
</tags>
</entry>
<entry>
<title>数据结构-第二章-线性表</title>
<url>/posts/e87c7b5c/</url>
<content><![CDATA[<h1 id="线性表的基本操作"><a href="#线性表的基本操作" class="headerlink" title="线性表的基本操作"></a>线性表的基本操作</h1><p><img src="https://pic.rmb.bdstatic.com/bjh/c95d369f9c7885afd120e7d149f8f658.png"></p>
<a id="more"></a>
<h1 id="顺序表的实现-静态分配"><a href="#顺序表的实现-静态分配" class="headerlink" title="顺序表的实现-静态分配"></a>顺序表的实现-静态分配</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Maxsize 10</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data[Maxsize];</span><br><span class="line"> <span class="keyword">int</span> length;</span><br><span class="line">}SqList;</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">void</span> <span class="title">InitList</span><span class="params">(SqList &L)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < Maxsize; i++)</span><br><span class="line"> {</span><br><span class="line"> L.data[i] = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> L.length = <span class="number">0</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"><span class="function"><span class="keyword">void</span> <span class="title">ListItem</span><span class="params">(SqList &L)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < Maxsize; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"data[%d]=%d\n"</span>, i, L.data[i]);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> SqList L;</span><br><span class="line"> InitList(L);</span><br><span class="line"> ListItem(L);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/94c8fbf0b6ca861e1ea9e344e6f2de99.png"></p>
<h1 id="顺序表的实现-动态分配"><a href="#顺序表的实现-动态分配" class="headerlink" title="顺序表的实现-动态分配"></a>顺序表的实现-动态分配</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><malloc.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> InitSize 15</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="comment">//动态分配 声明指针</span></span><br><span class="line"> <span class="keyword">int</span>* data;</span><br><span class="line"> <span class="keyword">int</span> MaxSize;</span><br><span class="line"> <span class="keyword">int</span> length;</span><br><span class="line">}SeqList;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">InitList</span><span class="params">(SeqList &L)</span> </span>{</span><br><span class="line"> <span class="comment">//申请一个长度15的数组</span></span><br><span class="line"> L.data = (<span class="keyword">int</span>*)<span class="built_in">malloc</span>(InitSize * <span class="keyword">sizeof</span>(<span class="keyword">int</span>));</span><br><span class="line"> L.length = <span class="number">0</span>;</span><br><span class="line"> L.MaxSize = InitSize;</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="function"><span class="keyword">void</span> <span class="title">IncreaseList</span><span class="params">(SeqList &L, <span class="keyword">int</span> size)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span>* data = L.data;</span><br><span class="line"> L.data = (<span class="keyword">int</span>*)<span class="built_in">malloc</span>((L.MaxSize + size) * <span class="keyword">sizeof</span>(<span class="keyword">int</span>));</span><br><span class="line"> L.length = <span class="number">0</span>;</span><br><span class="line"> L.MaxSize = L.MaxSize + size;</span><br><span class="line"> <span class="built_in">free</span>(data);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"现在的顺序表长度为:%d\n"</span>, L.MaxSize);</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="function"><span class="keyword">void</span> <span class="title">InitData</span><span class="params">(SeqList &L)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < L.MaxSize; i++)</span><br><span class="line"> {</span><br><span class="line"> L.data[i] = <span class="number">0</span>;</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="function"><span class="keyword">void</span> <span class="title">ListItem</span><span class="params">(SeqList &L)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < L.MaxSize; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"data[%d]=%d\n"</span>, i, L.data[i]);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> SeqList L;</span><br><span class="line"> InitList(L);</span><br><span class="line"> IncreaseList(L, <span class="number">5</span>);</span><br><span class="line"> InitData(L);</span><br><span class="line"> ListItem(L);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/33233d3848346589d8b6c9c9e580aa24.png"></p>
<h1 id="顺序表的插入"><a href="#顺序表的插入" class="headerlink" title="顺序表的插入"></a>顺序表的插入</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Maxsize 10</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data[Maxsize];</span><br><span class="line"> <span class="keyword">int</span> length;</span><br><span class="line">}SqList;</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">void</span> <span class="title">InitList</span><span class="params">(SqList& L)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < Maxsize; i++)</span><br><span class="line"> {</span><br><span class="line"> L.data[i] = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> L.length = <span class="number">0</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"><span class="function"><span class="keyword">void</span> <span class="title">InitData</span><span class="params">(SqList &L, <span class="keyword">int</span> size)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < size; i++)</span><br><span class="line"> {</span><br><span class="line"> L.data[i] = i;</span><br><span class="line"> }</span><br><span class="line"> L.length = size;</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="function"><span class="keyword">void</span> <span class="title">ListItem</span><span class="params">(SqList &L)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < L.length; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"data[%d]=%d\n"</span>, i, L.data[i]);</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="function"><span class="keyword">bool</span> <span class="title">ListInsert</span><span class="params">(SqList &L, <span class="keyword">int</span> index, <span class="keyword">int</span> element)</span> </span>{</span><br><span class="line"> <span class="comment">//插入位置的合法性判断</span></span><br><span class="line"> <span class="keyword">if</span> (index < <span class="number">1</span> || index > L.length+<span class="number">1</span>)</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><span class="line"> <span class="comment">//判断是否已满</span></span><br><span class="line"> <span class="keyword">if</span> (L.length >= Maxsize)</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><span class="line"> <span class="comment">//将插入位置后的数据全部后移</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = L.length; i >= index; i--)</span><br><span class="line"> {</span><br><span class="line"> L.data[i] = L.data[i - <span class="number">1</span>];</span><br><span class="line"> }</span><br><span class="line"> L.data[index<span class="number">-1</span>] = element;</span><br><span class="line"> L.length += <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> SqList L;</span><br><span class="line"> InitList(L);</span><br><span class="line"> InitData(L, <span class="number">7</span>);</span><br><span class="line"> <span class="keyword">if</span> (ListInsert(L, <span class="number">7</span>, <span class="number">99</span>))</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"插入成功!\n"</span>);</span><br><span class="line"> ListItem(L);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"插入失败!\n"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/48d551b65a1ef4e067acd7957e210106.png"></p>
<h1 id="顺序表的删除"><a href="#顺序表的删除" class="headerlink" title="顺序表的删除"></a>顺序表的删除</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Maxsize 10</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data[Maxsize];</span><br><span class="line"> <span class="keyword">int</span> length;</span><br><span class="line">}SqList;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">InitList</span><span class="params">(SqList& L)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < Maxsize; i++)</span><br><span class="line"> {</span><br><span class="line"> L.data[i] = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> L.length = <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">InitData</span><span class="params">(SqList &L, <span class="keyword">int</span> size)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < size; i++)</span><br><span class="line"> {</span><br><span class="line"> L.data[i] = i;</span><br><span class="line"> }</span><br><span class="line"> L.length = size;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">ListItem</span><span class="params">(SqList &L)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < <span class="number">10</span>; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"data[%d]=%d\n"</span>, i, L.data[i]);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">ListDelete</span><span class="params">(SqList &L, <span class="keyword">int</span> index)</span> </span>{</span><br><span class="line"> <span class="comment">//删除位置合法性判断</span></span><br><span class="line"> <span class="keyword">if</span> (index < <span class="number">1</span> || index > L.length) {</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 class="built_in">printf</span>(<span class="string">"正在删除的数据为:data[%d]=%d\n"</span>, index - <span class="number">1</span>, L.data[index - <span class="number">1</span>]);</span><br><span class="line"> <span class="comment">//逻辑删除元素</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = index; i < L.length; i++)</span><br><span class="line"> {</span><br><span class="line"> L.data[i - <span class="number">1</span>] = L.data[i];</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"正在赋值为:data[%d]=%d <= data[%d]=%d\n"</span>, i - <span class="number">1</span>, L.data[i - <span class="number">1</span>], i, L.data[i]);</span><br><span class="line"> }</span><br><span class="line"> L.data[L.length - <span class="number">1</span>] = <span class="number">0</span>;</span><br><span class="line"> L.length -= <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> SqList L;</span><br><span class="line"> InitList(L);</span><br><span class="line"> InitData(L, <span class="number">5</span>);</span><br><span class="line"> <span class="keyword">if</span> (ListDelete(L, <span class="number">2</span>))</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"删除成功!\n"</span>);</span><br><span class="line"> ListItem(L);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"删除失败!\n"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/c37e52ac3cd520ac594bb99e572c634c.png"></p>
<h1 id="顺序表的按位查找"><a href="#顺序表的按位查找" class="headerlink" title="顺序表的按位查找"></a>顺序表的按位查找</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Maxsize 10</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data[Maxsize];</span><br><span class="line"> <span class="keyword">int</span> length;</span><br><span class="line">}SqList;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">InitList</span><span class="params">(SqList& L)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < Maxsize; i++)</span><br><span class="line"> {</span><br><span class="line"> L.data[i] = i;</span><br><span class="line"> }</span><br><span class="line"> L.length = Maxsize;</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="function"><span class="keyword">void</span> <span class="title">getListItem</span><span class="params">(SqList &L, <span class="keyword">int</span> index)</span> </span>{</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"data[%d]=%d"</span>, index, L.data[index]);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> SqList L;</span><br><span class="line"> InitList(L);</span><br><span class="line"> getListItem(L, <span class="number">5</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/22cb223c8ecbcfd4025aa869f89fbc9f.png"></p>
<h1 id="顺序表的按值查找"><a href="#顺序表的按值查找" class="headerlink" title="顺序表的按值查找"></a>顺序表的按值查找</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Maxsize 10</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data[Maxsize];</span><br><span class="line"> <span class="keyword">int</span> length;</span><br><span class="line">}SqList;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">InitList</span><span class="params">(SqList& L)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < Maxsize; i++)</span><br><span class="line"> {</span><br><span class="line"> L.data[i] = i;</span><br><span class="line"> }</span><br><span class="line"> L.length = Maxsize;</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="function"><span class="keyword">void</span> <span class="title">getListItemByValue</span><span class="params">(SqList &L, <span class="keyword">int</span> value)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < L.length; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (L.data[i] == value) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"与%d匹配的有:data[%d]=%d"</span>, value, i, L.data[i]);</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 class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> SqList L;</span><br><span class="line"> InitList(L);</span><br><span class="line"> getListItemByValue(L, <span class="number">5</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/4437d14f2e26274d0882a24b9357432b.png"></p>
<h1 id="单链表的基本操作合集"><a href="#单链表的基本操作合集" class="headerlink" title="单链表的基本操作合集"></a>单链表的基本操作合集</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><malloc.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">//struct LNode {</span></span><br><span class="line"><span class="comment">// ElemType data;</span></span><br><span class="line"><span class="comment">// struct LNode* next;</span></span><br><span class="line"><span class="comment">//};</span></span><br><span class="line"><span class="comment">//typedef struct LNode LNode;</span></span><br><span class="line"><span class="comment">//typedef struct LNode* LinkList;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//等价定义</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">LNode</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">LNode</span>* <span class="title">next</span>;</span></span><br><span class="line">}LNode, *LinkList;</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">bool</span> <span class="title">InitListNoHead</span><span class="params">(LinkList &L)</span> </span>{</span><br><span class="line"> L = <span class="literal">NULL</span>;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</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"><span class="function"><span class="keyword">bool</span> <span class="title">InitList</span><span class="params">(LinkList &L)</span> </span>{</span><br><span class="line"> L = (LNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(LNode));</span><br><span class="line"> <span class="keyword">if</span> (L == <span class="literal">NULL</span>)</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><span class="line"> L->next = <span class="literal">NULL</span>;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</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"><span class="function"><span class="keyword">void</span> <span class="title">ListHeadInsert</span><span class="params">(LinkList &L, <span class="keyword">int</span> size)</span> </span>{</span><br><span class="line"> LNode* new_point;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < size; i++)</span><br><span class="line"> {</span><br><span class="line"> new_point = (LNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(LNode));</span><br><span class="line"> new_point->data = i + <span class="number">1</span>;</span><br><span class="line"> new_point->next = L->next;</span><br><span class="line"> L->next = new_point;</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="function"><span class="keyword">void</span> <span class="title">ListTailInsert</span><span class="params">(LinkList &L, <span class="keyword">int</span> size)</span> </span>{</span><br><span class="line"> LNode* new_point;</span><br><span class="line"> LNode* last_point = L;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < size; i++)</span><br><span class="line"> {</span><br><span class="line"> new_point = (LNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(LNode));</span><br><span class="line"> new_point->data = i + <span class="number">1</span>;</span><br><span class="line"> last_point->next = new_point;</span><br><span class="line"> last_point = new_point;</span><br><span class="line"> }</span><br><span class="line"> last_point->next = <span class="literal">NULL</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"><span class="function"><span class="keyword">void</span> <span class="title">ShowListLenght</span><span class="params">(LinkList &L)</span> </span>{</span><br><span class="line"> LNode* point = L->next;</span><br><span class="line"> <span class="keyword">int</span> num = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span> (point != <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> point = point->next;</span><br><span class="line"> num += <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"单链表长度为:%d\n"</span>, num);</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="function"><span class="keyword">void</span> <span class="title">ShowList</span><span class="params">(LinkList &L)</span> </span>{</span><br><span class="line"> LNode* point = L->next;</span><br><span class="line"> <span class="keyword">while</span> (point != <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>, point->data);</span><br><span class="line"> point = point->next;</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="function"><span class="keyword">bool</span> <span class="title">isEmpty</span><span class="params">(LinkList L)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> (L == <span class="literal">NULL</span> || L->next == <span class="literal">NULL</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"><span class="function"><span class="keyword">bool</span> <span class="title">InsertNextNode</span><span class="params">(LNode* point, <span class="keyword">int</span> element)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (point == <span class="literal">NULL</span>)</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><span class="line"> LNode* next_point = (LNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(LNode));</span><br><span class="line"> <span class="keyword">if</span> (next_point == <span class="literal">NULL</span>)</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><span class="line"> next_point->data = element;</span><br><span class="line"> next_point->next = point->next;</span><br><span class="line"> point->next = next_point;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</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"><span class="function"><span class="keyword">bool</span> <span class="title">LinkInsertNoHead</span><span class="params">(LinkList &L, <span class="keyword">int</span> index, <span class="keyword">int</span> element)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (index < <span class="number">1</span>)</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><span class="line"> <span class="keyword">if</span> (index == <span class="number">1</span>)</span><br><span class="line"> {</span><br><span class="line"> LNode* next_point = (LNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(LNode));</span><br><span class="line"> next_point->data = element;</span><br><span class="line"> next_point->next = L->next;</span><br><span class="line"> L = next_point;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> }</span><br><span class="line"> LNode* point = (LNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(LNode));</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">1</span>;</span><br><span class="line"> point = L;</span><br><span class="line"> <span class="keyword">while</span> (point != <span class="literal">NULL</span> && i < index)</span><br><span class="line"> {</span><br><span class="line"> point = point->next;</span><br><span class="line"> i += <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (point == <span class="literal">NULL</span>)</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><span class="line"> <span class="keyword">return</span> InsertNextNode(point, element);</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="function"><span class="keyword">bool</span> <span class="title">ListInsert</span><span class="params">(LinkList &L, <span class="keyword">int</span> index, <span class="keyword">int</span> element)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (index < <span class="number">1</span>)</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><span class="line"> LNode* point;</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line"> point = L;</span><br><span class="line"> <span class="keyword">while</span> (point != <span class="literal">NULL</span> && i < index - <span class="number">1</span>)</span><br><span class="line"> {</span><br><span class="line"> point = point->next;</span><br><span class="line"> i += <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (point == <span class="literal">NULL</span>)</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><span class="line"> <span class="keyword">return</span> InsertNextNode(point, element);</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="function"><span class="keyword">bool</span> <span class="title">InsertPriorNode</span><span class="params">(LNode* point, <span class="keyword">int</span> element)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (point == <span class="literal">NULL</span>)</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><span class="line"> LNode* prior_point = (LNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(LNode));</span><br><span class="line"> prior_point->next = point->next;</span><br><span class="line"> point->next = prior_point;</span><br><span class="line"> prior_point->data = point->data;</span><br><span class="line"> point->data = element;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</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"><span class="function"><span class="keyword">bool</span> <span class="title">InsertPriorNode</span><span class="params">(LNode* point, LNode* prior_point)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (point == <span class="literal">NULL</span> || prior_point == <span class="literal">NULL</span>)</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><span class="line"> prior_point->next = point->next;</span><br><span class="line"> point->next = prior_point;</span><br><span class="line"> <span class="keyword">int</span> temp = point->data;</span><br><span class="line"> point->data = prior_point->data;</span><br><span class="line"> prior_point->data = temp;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</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"><span class="function"><span class="keyword">bool</span> <span class="title">ListDelete</span><span class="params">(LinkList &L, <span class="keyword">int</span> index)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (index < <span class="number">1</span>)</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><span class="line"> LNode* point = L;</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span> (point != <span class="literal">NULL</span> && i < index - <span class="number">1</span>)</span><br><span class="line"> {</span><br><span class="line"> point = point->next;</span><br><span class="line"> i += <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (point->next == <span class="literal">NULL</span>)</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><span class="line"> LNode* delete_point = point->next;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"正在删除的是 %d\n"</span>, delete_point->data);</span><br><span class="line"> point->next = delete_point->next;</span><br><span class="line"> <span class="built_in">free</span>(delete_point);</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</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"><span class="function"><span class="keyword">bool</span> <span class="title">ListDelete</span><span class="params">(LNode* point)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (point == <span class="literal">NULL</span>)</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><span class="line"> LNode* temp_point = point->next;</span><br><span class="line"> point->data = temp_point->data;</span><br><span class="line"> point->next = temp_point->next;</span><br><span class="line"> <span class="built_in">free</span>(temp_point);</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">GetLNodeByIndex</span><span class="params">(LinkList L, <span class="keyword">int</span> index)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (index < <span class="number">1</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"输入有误\n"</span>);</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> LNode* point = L;</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span> (point != <span class="literal">NULL</span> && i < index)</span><br><span class="line"> {</span><br><span class="line"> point = point->next;</span><br><span class="line"> i += <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"单链表中第%d位的值为:%d"</span>, index, point->data);</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="function"><span class="keyword">void</span> <span class="title">GetLNodeByValue</span><span class="params">(LinkList &L, <span class="keyword">int</span> element)</span> </span>{</span><br><span class="line"> LNode* point = L;</span><br><span class="line"> <span class="keyword">int</span> index = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span> (point != <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (point->data == element)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"查询到单链表中第%d位为:%d\n"</span>, index, element);</span><br><span class="line"> }</span><br><span class="line"> point = point->next;</span><br><span class="line"> index += <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> LinkList L;</span><br><span class="line"> InitList(L);</span><br><span class="line"> ListTailInsert(L, <span class="number">10</span>);</span><br><span class="line"> ShowList(L);</span><br><span class="line"> ShowListLenght(L);</span><br><span class="line"> GetLNodeByValue(L, <span class="number">5</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>部分函数运行截图:</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/76e0896eff74e94d58d5099226032e81.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/edba85c3aaf54946f0296849f72262d9.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/77c032a9f7975fc0e4dd70915aecfd6b.png"></p>
<h1 id="双链表的基本操作"><a href="#双链表的基本操作" class="headerlink" title="双链表的基本操作"></a>双链表的基本操作</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><malloc.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">//基本定义</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">DNode</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">DNode</span>* <span class="title">next</span>, * <span class="title">prior</span>;</span></span><br><span class="line">}DNode,* DLinklist;</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">bool</span> <span class="title">InitDLinklist</span><span class="params">(DLinklist &L)</span> </span>{</span><br><span class="line"> L = (DNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(DNode));</span><br><span class="line"> <span class="keyword">if</span> (L==<span class="literal">NULL</span>)</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><span class="line"> L->next = <span class="literal">NULL</span>;</span><br><span class="line"> L->prior = <span class="literal">NULL</span>;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</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"><span class="function"><span class="keyword">bool</span> <span class="title">isEmpty</span><span class="params">(DLinklist &L)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span>(!L->next);</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="function"><span class="keyword">bool</span> <span class="title">InsertNextDNode</span><span class="params">(DNode *base_point, DNode *next_point)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (base_point == <span class="literal">NULL</span> || next_point == <span class="literal">NULL</span>)</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><span class="line"> next_point->next = base_point->next;</span><br><span class="line"> <span class="keyword">if</span> (base_point->next != <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> base_point->next->prior = next_point;</span><br><span class="line"> }</span><br><span class="line"> next_point->prior = base_point;</span><br><span class="line"> base_point->next = next_point;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</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"><span class="function"><span class="keyword">bool</span> <span class="title">DeleteNextDNode</span><span class="params">(DNode *point)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (point == <span class="literal">NULL</span>)</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><span class="line"> DNode* delete_point = point->next;</span><br><span class="line"> <span class="keyword">if</span> (delete_point == <span class="literal">NULL</span>)</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><span class="line"> <span class="comment">//设置该节点的后置节点</span></span><br><span class="line"> point->next = delete_point->next;</span><br><span class="line"> <span class="keyword">if</span> (delete_point->next != <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="comment">//设置后置节点的前置节点</span></span><br><span class="line"> delete_point->next->prior = point;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">free</span>(delete_point);</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="function"><span class="keyword">void</span> <span class="title">DestoryList</span><span class="params">(DLinklist &L)</span> </span>{</span><br><span class="line"> <span class="keyword">while</span> (L->next !=<span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> DeleteNextDNode(L);</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">free</span>(L);</span><br><span class="line"> L = <span class="literal">NULL</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"><span class="function"><span class="keyword">void</span> <span class="title">showList</span><span class="params">(DNode *point)</span> </span>{</span><br><span class="line"> <span class="comment">//后向遍历</span></span><br><span class="line"> <span class="keyword">while</span> (point != <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> point = point->next;</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//前向遍历</span></span><br><span class="line"> <span class="keyword">while</span> (point != <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> point = point->prior;</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//前向遍历(跳过头结点)</span></span><br><span class="line"> <span class="keyword">while</span> (point->prior != <span class="literal">NULL</span>) {</span><br><span class="line"> point = point->prior;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> DLinklist L;</span><br><span class="line"> InitDLinklist(L);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h1 id="循环单链表"><a href="#循环单链表" class="headerlink" title="循环单链表"></a>循环单链表</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><malloc.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">LNode</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">LNode</span>* <span class="title">next</span>;</span></span><br><span class="line">}LNode, * Linklist;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">InitList</span><span class="params">(Linklist &L)</span> </span>{</span><br><span class="line"> L = (LNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(LNode));</span><br><span class="line"> <span class="keyword">if</span> (L == <span class="literal">NULL</span>)</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><span class="line"> L->next = L;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">isEmpty</span><span class="params">(Linklist &L)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> L->next == L;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">isTail</span><span class="params">(Linklist &L, LNode *point)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> point->next == L;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h1 id="循环双链表"><a href="#循环双链表" class="headerlink" title="循环双链表"></a>循环双链表</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><malloc.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">DNode</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">DNode</span>* <span class="title">prior</span>, * <span class="title">next</span>;</span></span><br><span class="line">}DNode, * Dlinklist;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">InitDLinklist</span><span class="params">(Dlinklist &L)</span> </span>{</span><br><span class="line"> L = (DNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(DNode));</span><br><span class="line"> <span class="keyword">if</span> (L == <span class="literal">NULL</span>)</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><span class="line"> L->prior = L;</span><br><span class="line"> L->next = L;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">isEmpty</span><span class="params">(Dlinklist &L)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> L->next = L;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">isTail</span><span class="params">(Dlinklist &L, DNode *point)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> point->next == L;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">InsertNextNode</span><span class="params">(DNode *point, DNode *next_point)</span> </span>{</span><br><span class="line"> next_point->next = point->next;</span><br><span class="line"> point->next->prior = next_point;</span><br><span class="line"> next_point->prior = point;</span><br><span class="line"> point->next = next_point;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">DeleteNode</span><span class="params">(DNode *point)</span> </span>{</span><br><span class="line"> DNode* prior_point = point->prior;</span><br><span class="line"> prior_point->next = point->next;</span><br><span class="line"> point->next->prior = prior_point;</span><br><span class="line"> <span class="built_in">free</span>(point);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h1 id="静态链表"><a href="#静态链表" class="headerlink" title="静态链表"></a>静态链表</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><malloc.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Maxsize 10</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Node</span></span></span><br><span class="line"><span class="class">{</span></span><br><span class="line"> <span class="keyword">int</span> data;</span><br><span class="line"> <span class="keyword">int</span> next;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data;</span><br><span class="line"> <span class="keyword">int</span> next;</span><br><span class="line">}SLinklist[Maxsize];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">Node</span> <span class="title">x</span>;</span></span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>, <span class="keyword">sizeof</span>(x));</span><br><span class="line"></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">Node</span> <span class="title">l</span>[<span class="title">Maxsize</span>];</span></span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>, <span class="keyword">sizeof</span>(l));</span><br><span class="line"></span><br><span class="line"> SLinklist L;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>, <span class="keyword">sizeof</span>(L));</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/3e54ded0c1020e44e88fc38fd13b4c2b.png"></p>
<h1 id="顺序表和链表的比较"><a href="#顺序表和链表的比较" class="headerlink" title="顺序表和链表的比较"></a>顺序表和链表的比较</h1><p><img src="https://pic.rmb.bdstatic.com/bjh/63041b2cd5d8bbee4bc7fdc4b3f47ebd.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/cfee7c94673e1402f3fc52c66d6c5983.png"></p>
]]></content>
<categories>
<category>数据结构</category>
</categories>
<tags>
<tag>数据结构</tag>
<tag>考研</tag>
</tags>
</entry>
<entry>
<title>数据结构-第五章-树与二叉树</title>
<url>/posts/abac19d0/</url>
<content><![CDATA[<h1 id="二叉树的存储"><a href="#二叉树的存储" class="headerlink" title="二叉树的存储"></a>二叉树的存储</h1><p><img src="https://pic.rmb.bdstatic.com/bjh/3a7e2ffff9a918faa752fa5e69416b93.png"></p>
<a id="more"></a>
<figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><malloc.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Maxsize 100</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//顺序存储</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">TreeNode</span></span></span><br><span class="line"><span class="class">{</span></span><br><span class="line"> <span class="keyword">int</span> value;</span><br><span class="line"> <span class="keyword">bool</span> isEmpty;</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">//TreeNode t[Maxsize];</span></span><br><span class="line"><span class="comment">//for (int i = 0; i < Maxsize; i++)</span></span><br><span class="line"><span class="comment">//{</span></span><br><span class="line"><span class="comment">// t[i].isEmpty = true;</span></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="class"><span class="keyword">struct</span> <span class="title">ElemType</span></span></span><br><span class="line"><span class="class">{</span></span><br><span class="line"> <span class="keyword">int</span> value;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">BiTNode</span> {</span></span><br><span class="line"> ElemType data;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">BiTNode</span>* <span class="title">left_child</span>, * <span class="title">right_child</span>, * <span class="title">parent</span>;</span></span><br><span class="line">}BiTNode, * BiTree;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="comment">//定义一颗空树</span></span><br><span class="line"> BiTree root = <span class="literal">NULL</span>;</span><br><span class="line"> <span class="comment">//插入空结点</span></span><br><span class="line"> root = (BiTree)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(BiTree));</span><br><span class="line"> root->data.value = { <span class="number">1</span> };</span><br><span class="line"> root->left_child = <span class="literal">NULL</span>;</span><br><span class="line"> root->right_child = <span class="literal">NULL</span>;</span><br><span class="line"> root->parent = <span class="literal">NULL</span>;</span><br><span class="line"> <span class="comment">//插入新的结点</span></span><br><span class="line"> BiTNode* point = (BiTNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(BiTNode));</span><br><span class="line"> point->data.value = { <span class="number">2</span> };</span><br><span class="line"> point->left_child = <span class="literal">NULL</span>;</span><br><span class="line"> point->right_child = <span class="literal">NULL</span>;</span><br><span class="line"> point->parent = root;</span><br><span class="line"> root->left_child = point;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h1 id="二叉树的先中后序遍历"><a href="#二叉树的先中后序遍历" class="headerlink" title="二叉树的先中后序遍历"></a>二叉树的先中后序遍历</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><malloc.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ElemType</span></span></span><br><span class="line"><span class="class">{</span></span><br><span class="line"> <span class="keyword">int</span> value;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">BiTNode</span> {</span></span><br><span class="line"> ElemType data;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">BiTNode</span>* <span class="title">left_child</span>, * <span class="title">right_child</span>;</span></span><br><span class="line">}BiTNode, * BiTree;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">visit</span><span class="params">(BiTNode B)</span> </span>{</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>, B.data.value);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">visit</span><span class="params">(BiTree B)</span> </span>{</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>, B->data.value);</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="function"><span class="keyword">void</span> <span class="title">PreOrder</span><span class="params">(BiTree T)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (T != <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> visit(T);</span><br><span class="line"> PreOrder(T->left_child);</span><br><span class="line"> PreOrder(T->right_child);</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="function"><span class="keyword">void</span> <span class="title">InOrder</span><span class="params">(BiTree T)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (T != <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> InOrder(T->left_child);</span><br><span class="line"> visit(T);</span><br><span class="line"> InOrder(T->right_child);</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="function"><span class="keyword">void</span> <span class="title">PostOrder</span><span class="params">(BiTree T)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (T != <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> PostOrder(T->left_child);</span><br><span class="line"> PostOrder(T->right_child);</span><br><span class="line"> visit(T);</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="function"><span class="keyword">int</span> <span class="title">treeDepth</span><span class="params">(BiTree T)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (T == <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">int</span> left = treeDepth(T->left_child);</span><br><span class="line"> <span class="keyword">int</span> right = treeDepth(T->right_child);</span><br><span class="line"> <span class="keyword">return</span> left > right ? left + <span class="number">1</span> : right + <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h1 id="二叉树的层次遍历"><a href="#二叉树的层次遍历" class="headerlink" title="二叉树的层次遍历"></a>二叉树的层次遍历</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><malloc.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">//二叉树的链式存储</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">BiTNode</span> {</span></span><br><span class="line"> <span class="keyword">char</span> data;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">BiTNode</span>* <span class="title">left_child</span>, * <span class="title">right_child</span>;</span></span><br><span class="line">}BiTNode, * BiTree;</span><br><span class="line"></span><br><span class="line"><span class="comment">//链式队列结点</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">LinkNode</span> {</span></span><br><span class="line"> BiTNode* data;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">LinkNode</span>* <span class="title">next</span>;</span></span><br><span class="line">}LinkNode;</span><br><span class="line"></span><br><span class="line"><span class="comment">//队头队尾</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> LinkNode* front, * rear;</span><br><span class="line">}LinkQueue;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">visit</span><span class="params">(BiTNode B)</span> </span>{</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%c\n"</span>, B.data);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">visit</span><span class="params">(BiTree B)</span> </span>{</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%c\n"</span>, B->data);</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="function"><span class="keyword">void</span> <span class="title">InitQueue</span><span class="params">(LinkQueue &Q)</span> </span>{</span><br><span class="line"> Q.front = Q.rear = (LinkNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(LinkNode));</span><br><span class="line"> Q.front->next = <span class="literal">NULL</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"><span class="function"><span class="keyword">bool</span> <span class="title">isEmpty</span><span class="params">(LinkQueue Q)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> Q.front == Q.rear;</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="function"><span class="keyword">void</span> <span class="title">EnQueue</span><span class="params">(LinkQueue &Q, BiTNode* element)</span> </span>{</span><br><span class="line"> LinkNode* new_point = (LinkNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(LinkNode));</span><br><span class="line"> new_point->data = (BiTNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(BiTNode));</span><br><span class="line"> new_point->data = element;</span><br><span class="line"> new_point->next = <span class="literal">NULL</span>;</span><br><span class="line"> Q.rear->next = new_point;</span><br><span class="line"> Q.rear = new_point;</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="function"><span class="keyword">void</span> <span class="title">DeQueue</span><span class="params">(LinkQueue &Q, BiTree& T)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (Q.front == Q.rear)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"队列为空"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> LinkNode* new_point = Q.front->next;</span><br><span class="line"> T = new_point->data;</span><br><span class="line"> Q.front->next = new_point->next;</span><br><span class="line"> <span class="keyword">if</span> (Q.rear == new_point)</span><br><span class="line"> {</span><br><span class="line"> Q.rear = Q.front;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">free</span>(new_point);</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="function">BiTNode* <span class="title">InitTree</span><span class="params">()</span> </span>{</span><br><span class="line"> BiTNode* point = <span class="literal">NULL</span>;</span><br><span class="line"> <span class="keyword">char</span> ch;</span><br><span class="line"> scanf_s(<span class="string">"%c"</span>, &ch);</span><br><span class="line"> <span class="keyword">if</span> (ch == <span class="string">'#'</span>)</span><br><span class="line"> {</span><br><span class="line"> point == <span class="literal">NULL</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> point = (BiTNode*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(BiTNode));</span><br><span class="line"> point->data = ch;</span><br><span class="line"> point->left_child = InitTree();</span><br><span class="line"> point->right_child = InitTree();</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> point;</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="function"><span class="keyword">void</span> <span class="title">LevelOrder</span><span class="params">(BiTree T)</span> </span>{</span><br><span class="line"> LinkQueue Q;</span><br><span class="line"> InitQueue(Q);</span><br><span class="line"> BiTree point;</span><br><span class="line"> EnQueue(Q, T);</span><br><span class="line"> <span class="keyword">while</span> (!isEmpty(Q))</span><br><span class="line"> {</span><br><span class="line"> DeQueue(Q, point);</span><br><span class="line"> visit(point);</span><br><span class="line"> <span class="keyword">if</span> (point->left_child)</span><br><span class="line"> {</span><br><span class="line"> EnQueue(Q, point->left_child);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (point->right_child)</span><br><span class="line"> {</span><br><span class="line"> EnQueue(Q, point->right_child);</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 class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> BiTree T = InitTree();</span><br><span class="line"> LevelOrder(T);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/f1def503c4b0e0de5e35829e99a10709.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/8ce3b1f731785ffd3c9573be513d28a4.png"></p>
<h1 id="二叉树的线索化"><a href="#二叉树的线索化" class="headerlink" title="二叉树的线索化"></a>二叉树的线索化</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">ThreadNode</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">ThreadNode</span>* <span class="title">left_child</span>, * <span class="title">right_child</span>;</span></span><br><span class="line"> <span class="keyword">int</span> left_flag, right_flag;</span><br><span class="line">}ThreadNode, * ThreadTree;</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/5bf1a126c315f48eeb8f6992f41c2d00.png"></p>
<h2 id="中序线索化"><a href="#中序线索化" class="headerlink" title="中序线索化"></a>中序线索化</h2><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">ThreadNode</span> {</span></span><br><span class="line"> <span class="keyword">char</span> data;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">ThreadNode</span>* <span class="title">left_child</span>, * <span class="title">right_child</span>;</span></span><br><span class="line"> <span class="keyword">int</span> left_flag, right_flag;</span><br><span class="line">}ThreadNode, * ThreadTree;</span><br><span class="line"></span><br><span class="line"><span class="comment">//全局变量pre,指向当前访问结点的前驱</span></span><br><span class="line">ThreadNode* pre = <span class="literal">NULL</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">visit</span><span class="params">(ThreadNode *point)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (point->left_child == <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> point->left_child = pre;</span><br><span class="line"> point->left_flag = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (pre != <span class="literal">NULL</span> && pre->right_child == <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> pre->right_child = point;</span><br><span class="line"> pre->right_flag = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> pre = point;</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="function"><span class="keyword">void</span> <span class="title">InThread</span><span class="params">(ThreadTree T)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (T != <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> InThread(T->left_child);</span><br><span class="line"> visit(T);</span><br><span class="line"> InThread(T->right_child);</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="function"><span class="keyword">void</span> <span class="title">CreateInThread</span><span class="params">(ThreadTree T)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (T != <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> InThread(T);</span><br><span class="line"> <span class="keyword">if</span> (pre->right_child == <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> pre->right_flag = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="先序线索化"><a href="#先序线索化" class="headerlink" title="先序线索化"></a>先序线索化</h2><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">ThreadNode</span> {</span></span><br><span class="line"> <span class="keyword">char</span> data;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">ThreadNode</span>* <span class="title">left_child</span>, * <span class="title">right_child</span>;</span></span><br><span class="line"> <span class="keyword">int</span> left_flag, right_flag;</span><br><span class="line">}ThreadNode, * ThreadTree;</span><br><span class="line"></span><br><span class="line"><span class="comment">//全局变量pre,指向当前访问结点的前驱</span></span><br><span class="line">ThreadNode* pre = <span class="literal">NULL</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">visit</span><span class="params">(ThreadNode *point)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (point->left_child == <span class="literal">NULL</span>)<span class="comment">//左子树为空,建立前驱线索</span></span><br><span class="line"> {</span><br><span class="line"> point->left_child = pre;</span><br><span class="line"> point->left_flag = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (pre != <span class="literal">NULL</span> && pre->right_child == <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> pre->right_child = point;<span class="comment">//建立前驱节点的后继线索</span></span><br><span class="line"> pre->right_flag = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> pre = point;</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="function"><span class="keyword">void</span> <span class="title">PreThread</span><span class="params">(ThreadTree T)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (T != <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> visit(T);</span><br><span class="line"> <span class="keyword">if</span> (T->left_flag == <span class="number">0</span>)</span><br><span class="line"> {</span><br><span class="line"> PreThread(T->left_child);</span><br><span class="line"> }</span><br><span class="line"> PreThread(T->right_child);</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="function"><span class="keyword">void</span> <span class="title">CreatePreThread</span><span class="params">(ThreadTree T)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (T != <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> PreThread(T);</span><br><span class="line"> <span class="keyword">if</span> (pre->right_child == <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> pre->right_flag = <span class="number">1</span>;<span class="comment">//处理遍历的最后一个节点</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="后序线索化"><a href="#后序线索化" class="headerlink" title="后序线索化"></a>后序线索化</h2><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">ThreadNode</span> {</span></span><br><span class="line"> <span class="keyword">char</span> data;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">ThreadNode</span>* <span class="title">left_child</span>, * <span class="title">right_child</span>;</span></span><br><span class="line"> <span class="keyword">int</span> left_flag, right_flag;</span><br><span class="line">}ThreadNode, * ThreadTree;</span><br><span class="line"></span><br><span class="line"><span class="comment">//全局变量pre,指向当前访问结点的前驱</span></span><br><span class="line">ThreadNode* pre = <span class="literal">NULL</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">visit</span><span class="params">(ThreadNode *point)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (point->left_child == <span class="literal">NULL</span>)<span class="comment">//左子树为空,建立前驱线索</span></span><br><span class="line"> {</span><br><span class="line"> point->left_child = pre;</span><br><span class="line"> point->left_flag = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (pre != <span class="literal">NULL</span> && pre->right_child == <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> pre->right_child = point;<span class="comment">//建立前驱节点的后继线索</span></span><br><span class="line"> pre->right_flag = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> pre = point;</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="function"><span class="keyword">void</span> <span class="title">PostThread</span><span class="params">(ThreadTree T)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (T != <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> PostThread(T->left_child);</span><br><span class="line"> PostThread(T->right_child);</span><br><span class="line"> visit(T);</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="function"><span class="keyword">void</span> <span class="title">CreatePreThread</span><span class="params">(ThreadTree T)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (T != <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> PostThread(T);</span><br><span class="line"> <span class="keyword">if</span> (pre->right_child == <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> pre->right_flag = <span class="number">1</span>;<span class="comment">//处理遍历的最后一个节点</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h1 id="线索二叉数中照前驱后继"><a href="#线索二叉数中照前驱后继" class="headerlink" title="线索二叉数中照前驱后继"></a>线索二叉数中照前驱后继</h1><p><img src="https://pic.rmb.bdstatic.com/bjh/680607acd202ef0d3b6dbbfdb08d1338.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/b7b1d3dc64d746c3f16491101926a88c.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/2f5d107ed3e2929ea2181f3c2503b9a6.png"></p>
<h1 id="树的顺序存储(双亲表示法)"><a href="#树的顺序存储(双亲表示法)" class="headerlink" title="树的顺序存储(双亲表示法)"></a>树的顺序存储(双亲表示法)</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Max_Tree_Size 100</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">char</span> data;</span><br><span class="line"> <span class="keyword">int</span> parent;</span><br><span class="line">}PTNode;</span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> PTNode nodes[Max_Tree_Size];</span><br><span class="line"> <span class="keyword">int</span> num;</span><br><span class="line">}PTreee;</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/0e925e3cf171b8da141e38deea858f65.png"></p>
<p>删除元素(方案二) 将最后一个元素替换到要删除元素的位置</p>
<p>缺点 查找指定元素的时候只能从头开始遍历</p>
<h1 id="树的顺序-链式存储(孩子表示法)"><a href="#树的顺序-链式存储(孩子表示法)" class="headerlink" title="树的顺序+链式存储(孩子表示法)"></a>树的顺序+链式存储(孩子表示法)</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Max_Tree_Size 100</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">CTNode</span></span></span><br><span class="line"><span class="class">{</span></span><br><span class="line"> <span class="keyword">int</span> child;<span class="comment">//孩子结点在数组中的位置</span></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">CTNode</span>* <span class="title">next</span>;</span><span class="comment">//下一个孩子</span></span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">CTNode</span>* <span class="title">firstChild</span>;</span><span class="comment">//指向第一个孩子</span></span><br><span class="line">}CTBox;</span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> CTBox nodes[Max_Tree_Size];</span><br><span class="line"> <span class="keyword">int</span> num, root;<span class="comment">//结点数和根的位置</span></span><br><span class="line">}CTree;</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/0114d78e5f1217131e9078b085eb1968.png"></p>
<h1 id="树的链式存储(孩子兄弟表示法)"><a href="#树的链式存储(孩子兄弟表示法)" class="headerlink" title="树的链式存储(孩子兄弟表示法)"></a>树的链式存储(孩子兄弟表示法)</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">CSNode</span> {</span></span><br><span class="line"> <span class="keyword">int</span> data;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">CSNode</span>* <span class="title">first_child</span>, * <span class="title">next_sibling</span>;</span><span class="comment">//第一个孩子 和 右兄弟指针</span></span><br><span class="line">};</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/a49587c9ba24d1e47567e41f422d732f.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/2b378e71a1310bed21a44dcf6f5725bf.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/ff1fdc90281ac013ee125e64877c817e.png"></p>
<h1 id="树和森林的遍历"><a href="#树和森林的遍历" class="headerlink" title="树和森林的遍历"></a>树和森林的遍历</h1><p><img src="https://pic.rmb.bdstatic.com/bjh/800b2a9e1ded579d8599a1f261ab8a79.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/dc8cb02357c06516c0c664d7881373e0.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/b6c3f94232dff7f372d1e7f78dec07b4.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/4bbdd09e90f21909420f81aeb01b5704.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/bf9334a7d95cdcf40b5dcd697e00f6bb.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/5b81bdaf5ae217cd242541b2ed6788b1.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/def01f364f81e7b21b8de59577d9b09c.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/17ae66118584ad2ec26746de372d9ad7.png"></p>
<h1 id="二叉排序树的定义"><a href="#二叉排序树的定义" class="headerlink" title="二叉排序树的定义"></a>二叉排序树的定义</h1><p><img src="https://pic.rmb.bdstatic.com/bjh/0599db313340bb5608d3e8827af88bce.png"></p>
<h1 id="二叉排序树的构建和查找"><a href="#二叉排序树的构建和查找" class="headerlink" title="二叉排序树的构建和查找"></a>二叉排序树的构建和查找</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><malloc.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">//二叉排序树的结点</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">BSTNode</span> {</span></span><br><span class="line"> <span class="keyword">int</span> key;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">BSTNode</span>* <span class="title">left_child</span>, * <span class="title">right_child</span>;</span></span><br><span class="line">}BSTNode, * BSTree;</span><br><span class="line"></span><br><span class="line"><span class="comment">//在二叉排序树中查找值为key的结点 最坏空间复杂度 O(1)</span></span><br><span class="line"><span class="function">BSTNode* <span class="title">BST_Search</span><span class="params">(BSTree T, <span class="keyword">int</span> key)</span> </span>{</span><br><span class="line"> <span class="keyword">while</span> (T != <span class="literal">NULL</span> && key != T->key)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (key < T->key)<span class="comment">//小于在左子树上查找</span></span><br><span class="line"> {</span><br><span class="line"> T = T->left_child;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span><span class="comment">//大于在右子树上查找</span></span><br><span class="line"> {</span><br><span class="line"> T = T->right_child;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> T;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//递归实现二叉排序树的查找 最坏空间复杂度 O(h)</span></span><br><span class="line"><span class="function">BSTNode* <span class="title">BSTSearch</span><span class="params">(BSTree T, <span class="keyword">int</span> key)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (T == <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (key == T->key)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">return</span> T;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (key < T->key)</span><br><span class="line"> {</span><br><span class="line"> BSTSearch(T->left_child, key);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> BSTSearch(T->right_child, key);</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="function"><span class="keyword">void</span> <span class="title">BST_Insert</span><span class="params">(BSTree &T, <span class="keyword">int</span> value)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (T == <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> T = (BSTree)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(BSTNode));</span><br><span class="line"> T->key = value;</span><br><span class="line"> T->left_child = T->right_child = <span class="literal">NULL</span>;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"插入数据%d成功\n"</span>, value);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (value == T->key)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"存在相同的数据,插入失败!"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (value < T->key)</span><br><span class="line"> {</span><br><span class="line"> BST_Insert(T->left_child, value);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> BST_Insert(T->right_child, value);</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="function"><span class="keyword">void</span> <span class="title">Create_BST</span><span class="params">(BSTree &T, <span class="keyword">int</span> value[], <span class="keyword">int</span> num)</span> </span>{</span><br><span class="line"> T = <span class="literal">NULL</span>;</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span> (i < num)</span><br><span class="line"> {</span><br><span class="line"> BST_Insert(T, value[i]);</span><br><span class="line"> i += <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> BSTree T;</span><br><span class="line"> <span class="keyword">int</span> data[] = { <span class="number">50</span>,<span class="number">66</span>,<span class="number">60</span>,<span class="number">26</span>,<span class="number">21</span>,<span class="number">30</span>,<span class="number">70</span>,<span class="number">68</span> };</span><br><span class="line"> Create_BST(T, data, (<span class="keyword">sizeof</span>(data)/<span class="keyword">sizeof</span>(data[<span class="number">0</span>])));</span><br><span class="line"> BSTNode* result = BST_Search(T, <span class="number">68</span>);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"查找结果为:%d"</span>, result->key);</span><br><span class="line"> BSTNode* res = BSTSearch(T, <span class="number">60</span>);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"\n递归查找结果为:%d"</span>, res->key);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/8dd648259462dcc4b62ba52a5c682f67.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/fd9996a918feae0daae145cabe015002.png"></p>
<h1 id="平衡二叉树"><a href="#平衡二叉树" class="headerlink" title="平衡二叉树"></a>平衡二叉树</h1><p><img src="https://pic.rmb.bdstatic.com/bjh/dd570d35b9131d6e40bb0688e23c9eca.png"></p>
<p>二叉树插入和调整最小不平衡子树是重点</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/2974aca0535c5ddeafe8cb0bc2a92174.png"></p>
<p>查找效率分析看看这个图个乐</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/b73e68227cb8c1c568f816e619dab4e1.png"></p>
<h1 id="哈夫曼树"><a href="#哈夫曼树" class="headerlink" title="哈夫曼树"></a>哈夫曼树</h1><p><img src="https://pic.rmb.bdstatic.com/bjh/1fba7abaddc7b90918856f5b174abcfe.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/fdbc54c82b84d7cff9b66090d7901b6d.png"></p>
]]></content>
<categories>
<category>数据结构</category>
</categories>
<tags>
<tag>数据结构</tag>
<tag>考研</tag>
</tags>
</entry>
<entry>
<title>微博爬取相册的所有图片</title>
<url>/posts/2a5b7162/</url>
<content><![CDATA[<font color=#999AAA >
微博相册的批量爬取
</font>
<p><font color=#999AAA >微博有相册功能,那么我们如何批量下载相册中的所有照片呢?</font></p>
<p><font color=#999AAA >以下是本篇文章正文内容,下面案例可供参考</p>
<h1 id="一、分析实现思路"><a href="#一、分析实现思路" class="headerlink" title="一、分析实现思路"></a>一、分析实现思路</h1><p><font color=#999AAA >因为微博相册也是前后端分离,所以我们先去抓包对应的json数据<br><img src="https://img-blog.csdnimg.cn/20210103180658279.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
<a id="more"></a>
<p>这里以李荣浩的相册为例,一共有25页:<br><img src="https://img-blog.csdnimg.cn/20210103180747572.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>分析得出实际的链接应该为:’<a href="https://wx4.sinaimg.cn/large/'">https://wx4.sinaimg.cn/large/'</a> + pic_name<br><strong>再来看看链接循环爬取的分析</strong><br><img src="https://img-blog.csdnimg.cn/20210103181211482.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>这里只需要更改page的值即可实现循环爬取</p>
<h1 id="二、编写代码"><a href="#二、编写代码" class="headerlink" title="二、编写代码"></a>二、编写代码</h1><h2 id="1-引入库"><a href="#1-引入库" class="headerlink" title="1.引入库"></a>1.引入库</h2><p><font color=#999AAA >代码如下:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> fake_useragent <span class="keyword">import</span> UserAgent <span class="comment"># 伪装机型</span></span><br><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Thread <span class="comment"># 多进程</span></span><br><span class="line"><span class="keyword">from</span> queue <span class="keyword">import</span> Queue <span class="comment"># 队列</span></span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"></span><br><span class="line">headers = {</span><br><span class="line"> <span class="comment"># cookie 每天会变化,需要即使更换</span></span><br><span class="line"> <span class="string">'cookie'</span>: <span class="string">'SINAGLOBAL=74744724261.95033.1605948585466; wvr=6; '</span></span><br><span class="line"> <span class="string">'SUBP=0033WrSXqPxfM725Ws9jqgMF55529P9D9Whrq6C5pCwQBNf5XnQhDpfE5JpX5KMhUgL.Fo'</span></span><br><span class="line"> <span class="string">'-cehB7eoqpSKM2dJLoIEBLxKBLBonL12BLxKqL1KnL12-LxKnLBKML1h.LxKMLBKqLB.zt; ALF=1641197487; '</span></span><br><span class="line"> <span class="string">'SSOLoginState=1609661488; '</span></span><br><span class="line"> <span class="string">'SCF=AqFdnOicaqrQ3UjYRBY-C8Kp3PwjrkfR1lPLA0W8mjbwb9rIU1MBf0l9kWk3ahdAXFldqtvqcZ7UW_ehPXfM1JE.; '</span></span><br><span class="line"> <span class="string">'SUB=_2A25y9QxgDeRhGeNI61YR8ijNzjuIHXVRg3qorDV8PUNbmtAKLVTukW9NSH08UxX8Md1T1NOxjdEP88XVg1aJmi7t; '</span></span><br><span class="line"> <span class="string">'_s_tentry=login.sina.com.cn; Apache=9994350802777.143.1609661492706; '</span></span><br><span class="line"> <span class="string">'ULV=1609661492740:9:6:2:9994350802777.143.1609661492706:1609657348149; UOR=,,www.baidu.com; '</span></span><br><span class="line"> <span class="string">'webim_unReadCount=%7B%22time%22%3A1609666074015%2C%22dm_pub_total%22%3A0%2C%22chat_group_client%22%3A0'</span></span><br><span class="line"> <span class="string">'%2C%22chat_group_notice%22%3A0%2C%22allcountNum%22%3A3%2C%22msgbox%22%3A0%7D; '</span></span><br><span class="line"> <span class="string">'WBStorage=8daec78e6a891122|undefined'</span>,</span><br><span class="line"> <span class="comment"># 从哪里来</span></span><br><span class="line"> <span class="string">'referer'</span>: <span class="string">'https://photo.weibo.com/6816603335/talbum/index'</span>,</span><br><span class="line"> <span class="comment"># 伪装头</span></span><br><span class="line"> <span class="string">'user-agent'</span>: <span class="string">'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '</span></span><br><span class="line"> <span class="string">'Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66 '</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">fake = {</span><br><span class="line"> <span class="string">'User-Agent'</span>: UserAgent().random</span><br><span class="line">}</span><br><span class="line"><span class="comment"># ip代理池</span></span><br><span class="line">proxy_pool = [{<span class="string">'HTTP'</span>: <span class="string">'183.166.70.110:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'58.22.177.215:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'175.44.109.28:9999'</span>},</span><br><span class="line"> {<span class="string">'HTTP'</span>: <span class="string">'175.42.128.211:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'113.121.76.254:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'175.42.122.166:9999'</span>},</span><br><span class="line"> {<span class="string">'HTTP'</span>: <span class="string">'175.42.122.233:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'113.121.42.214:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'113.195.152.127:9999'</span>},</span><br><span class="line"> {<span class="string">'HTTP'</span>: <span class="string">'175.42.129.78:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'171.35.213.172:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'113.121.37.163:9999'</span>}]</span><br><span class="line"><span class="comment"># 访问json数据的url</span></span><br><span class="line">url = <span class="string">'https://photo.weibo.com/photos/get_all'</span></span><br></pre></td></tr></table></figure>
<h2 id="2-多进程的编写"><a href="#2-多进程的编写" class="headerlink" title="2.多进程的编写"></a>2.多进程的编写</h2><p><font color=#999AAA >代码如下:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SpiderImg</span>(<span class="params">Thread</span>):</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, d</span>):</span></span><br><span class="line"> Thread.__init__(self)</span><br><span class="line"> self.data = d</span><br><span class="line"> <span class="comment"># 重写run方法</span></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"> <span class="keyword">while</span> <span class="keyword">not</span> self.data.empty():</span><br><span class="line"> <span class="comment"># 取队列</span></span><br><span class="line"> a = self.data.get()</span><br><span class="line"> <span class="comment"># 获得id和url数据</span></span><br><span class="line"> i_id = <span class="built_in">list</span>(a.keys())[<span class="number">0</span>]</span><br><span class="line"> i_url = <span class="built_in">list</span>(a.values())[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># 访问链接取得数据</span></span><br><span class="line"> img = requests.get(url=i_url, headers=fake, proxies=random.choice(proxy_pool)).content</span><br><span class="line"> <span class="comment"># 将文件写入指定路径下的文件夹</span></span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">'E:/SpiderImg/李荣浩/{}.jpg'</span>.<span class="built_in">format</span>(i_id), <span class="string">'wb'</span>) <span class="keyword">as</span> t:</span><br><span class="line"> t.write(img)</span><br><span class="line"> print(i_id + <span class="string">'.jpg'</span> + <span class="string">' '</span> * <span class="number">4</span> + <span class="string">'下载完毕'</span> + <span class="string">'.'</span> * <span class="number">4</span>)</span><br></pre></td></tr></table></figure>
<p><font color=#999AAA >为了开启多进程爬取图片</p>
<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">
<h2 id="3-主函数的编写"><a href="#3-主函数的编写" class="headerlink" title="3.主函数的编写"></a>3.主函数的编写</h2><p><font color=#999AAA >代码如下:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> <span class="comment"># 初始化队列</span></span><br><span class="line"> data_queue = Queue()</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> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">26</span>):</span><br><span class="line"> params = {</span><br><span class="line"> <span class="string">'uid'</span>: <span class="string">'1739046981'</span>,</span><br><span class="line"> <span class="string">'album_id'</span>: <span class="string">'3581934839144367'</span>,</span><br><span class="line"> <span class="string">'count'</span>: <span class="string">'30'</span>,</span><br><span class="line"> <span class="string">'page'</span>: i,</span><br><span class="line"> <span class="string">'type'</span>: <span class="string">'3'</span>,</span><br><span class="line"> <span class="string">'__rnd'</span>: <span class="string">'1609667183074'</span></span><br><span class="line"> }</span><br><span class="line"> print(<span class="string">'正在爬取第{}页'</span>.<span class="built_in">format</span>(i) + <span class="string">'.'</span> * <span class="number">4</span>)</span><br><span class="line"> response = requests.get(url=url, params=params, headers=headers).json()</span><br><span class="line"> <span class="comment"># 解析数据</span></span><br><span class="line"> photo_list = response.get(<span class="string">'data'</span>).get(<span class="string">'photo_list'</span>)</span><br><span class="line"> <span class="keyword">for</span> photo <span class="keyword">in</span> photo_list:</span><br><span class="line"> <span class="comment"># 取得其中的pic_name 和 pic_name </span></span><br><span class="line"> pic_name = photo.get(<span class="string">'pic_name'</span>)</span><br><span class="line"> pic_name = photo.get(<span class="string">'photo_id'</span>)</span><br><span class="line"> photo_url = <span class="string">'https://wx4.sinaimg.cn/large/'</span> + pic_name</span><br><span class="line"> <span class="comment"># 添加到队列中</span></span><br><span class="line"> data_queue.put({photo_id: photo_url})</span><br><span class="line"> <span class="comment"># 开启多进程,根据队列中存放的url数据,下载图片</span></span><br><span class="line"> <span class="keyword">for</span> w <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">64</span>):</span><br><span class="line"> spider = SpiderImg(data_queue)</span><br><span class="line"> spider.start()</span><br></pre></td></tr></table></figure>
<h1 id="结果"><a href="#结果" class="headerlink" title="结果"></a>结果</h1><p><font color=#999AAA >程序运行结果:<br><img src="https://img-blog.csdnimg.cn/20210103182940445.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br><strong>注:案例仅供学习</strong></p>
]]></content>
<categories>
<category>爬虫学习</category>
</categories>
<tags>
<tag>Python</tag>
<tag>微博</tag>
<tag>相册</tag>
</tags>
</entry>
<entry>
<title>数据结构-第八章-排序</title>
<url>/posts/d311869f/</url>
<content><![CDATA[<h1 id="冒泡排序"><a href="#冒泡排序" class="headerlink" title="冒泡排序"></a>冒泡排序</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">swap</span><span class="params">(<span class="keyword">int</span> &a, <span class="keyword">int</span> &b)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> temp = a;</span><br><span class="line"> a = b;</span><br><span class="line"> b = temp;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<a id="more"></a>
<figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">BubbleSort</span><span class="params">(<span class="keyword">int</span> A[], <span class="keyword">int</span> n)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < n - <span class="number">1</span>; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">bool</span> flag = <span class="literal">false</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j = n - <span class="number">1</span>; j > i; j--)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (A[j - <span class="number">1</span>] > A[j])</span><br><span class="line"> {</span><br><span class="line"> swap(A[j - <span class="number">1</span>], A[j]);</span><br><span class="line"> flag = <span class="literal">true</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (flag == <span class="literal">false</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < n; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d "</span>, A[i]);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span>;</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 class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> A[] = { <span class="number">52</span>,<span class="number">6</span>,<span class="number">65</span>,<span class="number">52</span>,<span class="number">85</span>,<span class="number">33</span>,<span class="number">99</span>,<span class="number">125</span>,<span class="number">22</span>,<span class="number">33</span>,<span class="number">55</span>,<span class="number">66</span>,<span class="number">55</span>,<span class="number">88</span>,<span class="number">77</span>,<span class="number">55</span>,<span class="number">66</span>,<span class="number">55</span>,<span class="number">22</span>,<span class="number">59</span> };</span><br><span class="line"> BubbleSort(A, (<span class="keyword">sizeof</span>(A)/<span class="keyword">sizeof</span>(<span class="keyword">int</span>)));</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/8d5c4549b88da45725495f5f40a78191.png"></p>
<h1 id="快速排序"><a href="#快速排序" class="headerlink" title="快速排序"></a>快速排序</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">Partition</span><span class="params">(<span class="keyword">int</span> A[], <span class="keyword">int</span> low, <span class="keyword">int</span> high)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> pivot = A[low];</span><br><span class="line"> <span class="keyword">while</span> (low < high)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">while</span> (low < high && A[high] >= pivot)</span><br><span class="line"> {</span><br><span class="line"> high -= <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> A[low] = A[high];</span><br><span class="line"> <span class="keyword">while</span> (low < high && A[low] <= pivot)</span><br><span class="line"> {</span><br><span class="line"> low += <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> A[high] = A[low];</span><br><span class="line"> }</span><br><span class="line"> A[low] = pivot;</span><br><span class="line"> <span class="keyword">return</span> low;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">QuickSort</span><span class="params">(<span class="keyword">int</span> A[], <span class="keyword">int</span> low, <span class="keyword">int</span> high)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (low < high)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">int</span> point = Partition(A, low, high);</span><br><span class="line"> QuickSort(A, low, point - <span class="number">1</span>);</span><br><span class="line"> QuickSort(A, point + <span class="number">1</span>, high);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> A[] = { <span class="number">52</span>,<span class="number">6</span>,<span class="number">65</span>,<span class="number">52</span>,<span class="number">85</span>,<span class="number">33</span>,<span class="number">99</span>,<span class="number">125</span>,<span class="number">22</span>,<span class="number">33</span>,<span class="number">55</span>,<span class="number">66</span>,<span class="number">55</span>,<span class="number">88</span>,<span class="number">77</span>,<span class="number">55</span>,<span class="number">66</span>,<span class="number">55</span>,<span class="number">22</span>,<span class="number">59</span> };</span><br><span class="line"> QuickSort(A, <span class="number">0</span>, (<span class="keyword">sizeof</span>(A) / <span class="keyword">sizeof</span>(A[<span class="number">0</span>]) - <span class="number">1</span>));</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < (<span class="keyword">sizeof</span>(A) / <span class="keyword">sizeof</span>(A[<span class="number">0</span>])); i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d "</span>, A[i]);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/c82d2b540bb1a17c996b2adb8c59eb70.png"></p>
]]></content>
<categories>
<category>数据结构</category>
</categories>
<tags>
<tag>数据结构</tag>
<tag>考研</tag>
</tags>
</entry>
<entry>
<title>数据结构-第四章-串</title>
<url>/posts/ca01dcf1/</url>
<content><![CDATA[<h1 id="串的基本操作"><a href="#串的基本操作" class="headerlink" title="串的基本操作"></a>串的基本操作</h1><p><img src="https://pic.rmb.bdstatic.com/bjh/ec9cfc6be46553c85e42d23a856a460c.png"></p>
<a id="more"></a>
<h1 id="串的顺序存储"><a href="#串的顺序存储" class="headerlink" title="串的顺序存储"></a>串的顺序存储</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><malloc.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Maxlength 255</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">char</span> ch[Maxlength];</span><br><span class="line"> <span class="keyword">int</span> length;</span><br><span class="line">}SString;</span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">char</span>* ch;</span><br><span class="line"> <span class="keyword">int</span> length;</span><br><span class="line">}HString;</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">void</span> <span class="title">InitHString</span><span class="params">(HString &S)</span> </span>{</span><br><span class="line"> S.ch = (<span class="keyword">char</span>*)<span class="built_in">malloc</span>(Maxlength * <span class="keyword">sizeof</span>(<span class="keyword">char</span>));</span><br><span class="line"> S.length = <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h1 id="串的链式存储"><a href="#串的链式存储" class="headerlink" title="串的链式存储"></a>串的链式存储</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">//存储密度低</span></span><br><span class="line"><span class="comment">//typedef struct {</span></span><br><span class="line"><span class="comment">// char ch;</span></span><br><span class="line"><span class="comment">// struct StringNode* next;</span></span><br><span class="line"><span class="comment">//}StringNode, * String;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//提高存储密度</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">char</span> ch[<span class="number">4</span>];</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">StringNode</span>* <span class="title">next</span>;</span></span><br><span class="line">}StringNode, *String;</span><br></pre></td></tr></table></figure>
<h1 id="基本操作的实现"><a href="#基本操作的实现" class="headerlink" title="基本操作的实现"></a>基本操作的实现</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><string.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Maxlen 255</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">char</span> ch[Maxlen];</span><br><span class="line"> <span class="keyword">int</span> length;</span><br><span class="line">}SString;</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">void</span> <span class="title">InitString</span><span class="params">(SString& S)</span> </span>{</span><br><span class="line"> strcpy_s(S.ch, <span class="string">"abcdefghijk"</span>);</span><br><span class="line"> S.length = <span class="number">11</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"><span class="function"><span class="keyword">void</span> <span class="title">SubString</span><span class="params">(SString S, <span class="keyword">int</span> pos, <span class="keyword">int</span> len)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (pos + len - <span class="number">1</span> > S.length)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"越界了"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"从字符串%s的第%d位开始取%d位的结果为:"</span>, S.ch, pos, len);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = pos - <span class="number">1</span>; i < pos - <span class="number">1</span> + len; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%c"</span>, S.ch[i]);</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 class="function"><span class="keyword">bool</span> <span class="title">SubString</span><span class="params">(SString& Sub, SString S, <span class="keyword">int</span> pos, <span class="keyword">int</span> len)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (pos + len - <span class="number">1</span> > S.length)</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><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = pos - <span class="number">1</span>; i < pos + len - <span class="number">1</span>; i++)</span><br><span class="line"> {</span><br><span class="line"> Sub.ch[i - pos] = S.ch[i];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</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"><span class="function"><span class="keyword">int</span> <span class="title">StrCompare</span><span class="params">(SString S, SString T)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < S.length && i < T.length; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (S.ch[i] != T.ch[i])</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">return</span> S.ch[i] - T.ch[i];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> S.length - T.length;</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="function"><span class="keyword">int</span> <span class="title">IndexString</span><span class="params">(SString S, SString T)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">0</span>, n = S.length, m = T.length;</span><br><span class="line"> SString Sub;</span><br><span class="line"> <span class="keyword">while</span> (i <= n - m)</span><br><span class="line"> {</span><br><span class="line"> SubString(Sub, S, i, m);</span><br><span class="line"> <span class="keyword">if</span> (StrCompare(Sub, T) != <span class="number">0</span>)</span><br><span class="line"> {</span><br><span class="line"> i += <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">return</span> i;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> SString S;</span><br><span class="line"> InitString(S);</span><br><span class="line"> SubString(S, <span class="number">2</span>, <span class="number">4</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/752b4bc5bc1a011093a0bdae1468eb0e.png"></p>
<h1 id="朴素模式匹配算法"><a href="#朴素模式匹配算法" class="headerlink" title="朴素模式匹配算法"></a>朴素模式匹配算法</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><string.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Maxlen 255</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">char</span> ch[Maxlen];</span><br><span class="line"> <span class="keyword">int</span> length;</span><br><span class="line">}SString;</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">void</span> <span class="title">InitString</span><span class="params">(SString &S, <span class="keyword">const</span> <span class="keyword">char</span> *element)</span> </span>{</span><br><span class="line"> strcpy_s(S.ch, element);</span><br><span class="line"> S.length = <span class="built_in">strlen</span>(element);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">Index</span><span class="params">(SString S, SString T)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">int</span> j = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">int</span> k = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span> (i<S.length && j<T.length)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (S.ch[i] == T.ch[j])</span><br><span class="line"> {</span><br><span class="line"> i += <span class="number">1</span>;</span><br><span class="line"> j += <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> k += <span class="number">1</span>;</span><br><span class="line"> i = k;</span><br><span class="line"> j = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (j = T.length)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">return</span> k + <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> SString S;</span><br><span class="line"> InitString(S, <span class="string">"fioqnionqvnnakmdl1kasmopgqowmc"</span>);</span><br><span class="line"> SString T;</span><br><span class="line"> InitString(T, <span class="string">"qowmc"</span>);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"从%d位置开始相同"</span>, Index(S, T));</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/4de24e85a61cdd790ab34d9d2eccf249.png"></p>
<h1 id="KMP算法"><a href="#KMP算法" class="headerlink" title="KMP算法"></a>KMP算法</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><malloc.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><string.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Maxsize 255</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">char</span> ch[Maxsize];</span><br><span class="line"> <span class="keyword">int</span> length;</span><br><span class="line">}String;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">InitString</span><span class="params">(String& S, <span class="keyword">const</span> <span class="keyword">char</span>* c)</span> </span>{</span><br><span class="line"> strcpy_s(S.ch, <span class="string">" "</span>);</span><br><span class="line"> strcat_s(S.ch, c);</span><br><span class="line"> S.length = <span class="built_in">strlen</span>(c);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">PrintString</span><span class="params">(String S)</span> </span>{</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"字符串为%s 长度为%d\n"</span>, S.ch, S.length);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">Get_Length</span><span class="params">(String S)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> S.length;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">Get_Next</span><span class="params">(String S, <span class="keyword">int</span> *next)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">1</span>, j = <span class="number">0</span>;</span><br><span class="line"> next[<span class="number">0</span>] = <span class="number">-1</span>;</span><br><span class="line"> next[<span class="number">1</span>] = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span> (i < S.length)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (j==<span class="number">0</span> || S.ch[i] == S.ch[j])</span><br><span class="line"> {</span><br><span class="line"> ++i;</span><br><span class="line"> ++j;</span><br><span class="line"> next[i] = j;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> j = next[j];</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 class="function"><span class="keyword">int</span> <span class="title">KMP</span><span class="params">(String S, String T, <span class="keyword">int</span> *next)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">1</span>, j = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">while</span> (i <= S.length && j <= T.length)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (j == <span class="number">0</span> || S.ch[i] == T.ch[j])</span><br><span class="line"> {</span><br><span class="line"> i += <span class="number">1</span>;</span><br><span class="line"> j += <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> {</span><br><span class="line"> j = next[j];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (j > T.length)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">return</span> i - T.length;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> String S;</span><br><span class="line"> InitString(S, <span class="string">"ababaa"</span>);</span><br><span class="line"> <span class="keyword">int</span>* next = (<span class="keyword">int</span>*)<span class="built_in">malloc</span>(S.length * <span class="keyword">sizeof</span>(<span class="keyword">int</span>));</span><br><span class="line"> Get_Next(S, next);</span><br><span class="line"> String <span class="built_in">string</span>;</span><br><span class="line"> InitString(<span class="built_in">string</span>, <span class="string">"cccccababaaccccc"</span>);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d"</span>, KMP(<span class="built_in">string</span>, S, next));</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/eb234fbcfe8a41eaff8581c958b8cd28.png"></p>
<h1 id="KMP算法的优化"><a href="#KMP算法的优化" class="headerlink" title="KMP算法的优化"></a>KMP算法的优化</h1><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">Get_Nextval</span><span class="params">(String S, <span class="keyword">int</span> *next)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">0</span>, j = <span class="number">0</span>;</span><br><span class="line"> next[<span class="number">0</span>] = <span class="number">-1</span>;</span><br><span class="line"> next[<span class="number">1</span>] = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span> (i < S.length)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (j == <span class="number">0</span> || S.ch[i] == S.ch[j])</span><br><span class="line"> {</span><br><span class="line"> ++i;</span><br><span class="line"> ++j;</span><br><span class="line"> <span class="keyword">if</span> (S.ch[i] != S.ch[j])</span><br><span class="line"> {</span><br><span class="line"> next[i] = j;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> next[i] = next[j];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> j = next[j];</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 class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> String S;</span><br><span class="line"> InitString(S, <span class="string">"aaaab"</span>);</span><br><span class="line"> <span class="keyword">int</span>* next = (<span class="keyword">int</span>*)<span class="built_in">malloc</span>(S.length * <span class="keyword">sizeof</span>(<span class="keyword">int</span>));</span><br><span class="line"> Get_Next(S, next);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i < S.length + <span class="number">1</span>; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d "</span>, next[i]);</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line"> Get_Nextval(S, next);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i < S.length + <span class="number">1</span>; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d "</span>, next[i]);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img src="https://pic.rmb.bdstatic.com/bjh/23f2adf0e8035c6ed6d17310cb119059.png"></p>
]]></content>
<categories>
<category>数据结构</category>
</categories>
<tags>
<tag>数据结构</tag>
<tag>考研</tag>
</tags>
</entry>
<entry>
<title>有道翻译js逆向</title>
<url>/posts/cb40ebbd/</url>
<content><![CDATA[<p><img src="https://img-blog.csdnimg.cn/20210109180814355.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
<p>对有道翻译进行的js逆向爬虫分析。</p>
<a id="more"></a>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p><font color=#999AAA >js逆向第一战。</font></p>
<h1 id="一、JS逆向是什么?"><a href="#一、JS逆向是什么?" class="headerlink" title="一、JS逆向是什么?"></a>一、JS逆向是什么?</h1><p><font color=#999AAA >抓取网页端数据时,经常被加密参数、加密数据所困扰,获取不到想要的数据。这个时候需要根据JavaScript的代码逆向进行解决问题。</p>
<h1 id="二、分析和编写代码"><a href="#二、分析和编写代码" class="headerlink" title="二、分析和编写代码"></a>二、分析和编写代码</h1><h2 id="1-分析"><a href="#1-分析" class="headerlink" title="1.分析"></a>1.分析</h2><p>地址:<a href="http://fanyi.youdao.com/?keyfrom=fanyi-new.logo">有道翻译</a><br>在输入框内输入英文,抓包工具中新增一个接口:<br><img src="https://img-blog.csdnimg.cn/20210109180814355.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>显而易见,这就是我们想要的数据,那么我们来看看请求头。<br><img src="https://img-blog.csdnimg.cn/20210109180952378.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>对比多个请求头的参数后发现,salt,sign,和lts是一直动态变化的,我们去搜索一下sign在js文件中出现的位置,并初步排除一下代码段。<br><img src="https://img-blog.csdnimg.cn/20210109181143454.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>搜到一条结果,格式化一下,再在其中搜索sign:<br><img src="https://img-blog.csdnimg.cn/20210109181256786.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>有十五个值,我们根据特征逐条查看一下,找到了其中的关键片段:<br><img src="https://img-blog.csdnimg.cn/2021010918144276.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>这里可以很清楚的看到:</p>
<ul>
<li>调用了工具md5加密</li>
<li>(new Date).getTime() 时间戳</li>
<li>parseInt(10 * Math.random(), 10) 10以内的随机数</li>
<li>n.md5(“fanyideskweb” + e + i + “Tbh5E8=q6U3EXe+&L[4c@”) 拼接字符串后,进行md5加密<br>于是,打断点进行测试,注意在语句运行之后打断点:<br><img src="https://img-blog.csdnimg.cn/20210109181839947.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>于是这里的e就是我们输入的英文字符串,r是时间戳,i是时间戳后加一个随机数,对应关系为:</li>
<li>ts: r</li>
<li>salt: i</li>
<li>sign: 拼接并加密后的e<br>与我们的请求头对应上了,接下来我们只需要在python中模仿其做出相同的操作即可。</li>
</ul>
<h2 id="2-编写代码"><a href="#2-编写代码" class="headerlink" title="2.编写代码"></a>2.编写代码</h2><p><font color=#999AAA >代码如下:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">import</span> hashlib</span><br><span class="line"><span class="keyword">import</span> time</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">TranslationSpider</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span>(<span class="params">self, word</span>):</span></span><br><span class="line"> <span class="comment"># 先请求基本页面再请求接口,session中会存在对应的cookie等参数</span></span><br><span class="line"> self.base_url = <span class="string">'http://fanyi.youdao.com/?keyfrom=fanyi-new.logo'</span></span><br><span class="line"> <span class="comment"># 接口地址</span></span><br><span class="line"> self.url = <span class="string">'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'</span></span><br><span class="line"> <span class="comment"># 初始化session</span></span><br><span class="line"> self.session = requests.session()</span><br><span class="line"> <span class="comment"># 初始化伪装头</span></span><br><span class="line"> self.headers = {</span><br><span class="line"> <span class="string">'Referer'</span>: <span class="string">'http://fanyi.youdao.com/'</span>,</span><br><span class="line"> <span class="string">'User-Agent'</span>: <span class="string">'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '</span></span><br><span class="line"> <span class="string">'Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66 '</span></span><br><span class="line"> }</span><br><span class="line"> <span class="comment"># 初始化参数</span></span><br><span class="line"> self.word = word</span><br><span class="line"> self.data = {}</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">generator_data</span>(<span class="params">self</span>):</span></span><br><span class="line"> <span class="comment"># 获得时间戳</span></span><br><span class="line"> ts = <span class="built_in">str</span>(<span class="built_in">int</span>(time.time() * <span class="number">1000</span>))</span><br><span class="line"> <span class="comment"># 时间戳加随机数</span></span><br><span class="line"> salt = ts + <span class="built_in">str</span>(random.randint(<span class="number">0</span>, <span class="number">10</span>))</span><br><span class="line"> <span class="comment"># md5加密</span></span><br><span class="line"> sign = <span class="string">"fanyideskweb"</span> + self.word + salt + <span class="string">"Tbh5E8=q6U3EXe+&L[4c@"</span></span><br><span class="line"> md5 = hashlib.md5()</span><br><span class="line"> md5.update(sign.encode())</span><br><span class="line"> sign = md5.hexdigest()</span><br><span class="line"> <span class="comment"># post请求的参数</span></span><br><span class="line"> self.data = {</span><br><span class="line"> <span class="string">"i"</span>: self.word,</span><br><span class="line"> <span class="string">"from"</span>: <span class="string">"AUTO"</span>,</span><br><span class="line"> <span class="string">"to"</span>: <span class="string">"AUTO"</span>,</span><br><span class="line"> <span class="string">"smartresult"</span>: <span class="string">"dict"</span>,</span><br><span class="line"> <span class="string">"client"</span>: <span class="string">"fanyideskweb"</span>,</span><br><span class="line"> <span class="string">"salt"</span>: salt,</span><br><span class="line"> <span class="string">"sign"</span>: sign,</span><br><span class="line"> <span class="string">"lts"</span>: ts,</span><br><span class="line"> <span class="string">"bv"</span>: <span class="string">"b286f0a34340b928819a6f64492585e8"</span>,</span><br><span class="line"> <span class="string">"doctype"</span>: <span class="string">"json"</span>,</span><br><span class="line"> <span class="string">"version"</span>: <span class="string">"2.1"</span>,</span><br><span class="line"> <span class="string">"keyfrom"</span>: <span class="string">"fanyi.web"</span>,</span><br><span class="line"> <span class="string">"action"</span>: <span class="string">"FY_BY_REALTlME"</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_request</span>(<span class="params">self</span>):</span></span><br><span class="line"> <span class="comment"># 请求初始界面</span></span><br><span class="line"> self.session.get(url=self.base_url, headers=self.headers)</span><br><span class="line"> <span class="comment"># 再请求接口地址 并返回json</span></span><br><span class="line"> response = self.session.post(url=self.url, data=self.data, headers=self.headers).json()</span><br><span class="line"> <span class="keyword">return</span> response</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">parse_json</span>(<span class="params">self, json</span>):</span></span><br><span class="line"> <span class="comment"># 解析传过来的json数据</span></span><br><span class="line"> tgt = json[<span class="string">'translateResult'</span>][<span class="number">0</span>][<span class="number">0</span>][<span class="string">'tgt'</span>]</span><br><span class="line"> entries = json[<span class="string">'smartResult'</span>][<span class="string">'entries'</span>]</span><br><span class="line"> print(<span class="string">'英文{}翻译结果为:{}'</span>.<span class="built_in">format</span>(self.word, tgt))</span><br><span class="line"> print(<span class="string">''</span>.join(entries))</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"># 调用封装好的方法</span></span><br><span class="line"> self.generator_data()</span><br><span class="line"> self.parse_json(self.get_request())</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"># 循环翻译</span></span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> w = <span class="built_in">input</span>(<span class="string">'输入需要翻译的英文:'</span>)</span><br><span class="line"> <span class="comment"># 输入exit0退出</span></span><br><span class="line"> <span class="keyword">if</span> w == <span class="string">'exit0'</span>:</span><br><span class="line"> print(<span class="string">'退出成功!'</span>)</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="comment"># new一个对象</span></span><br><span class="line"> spider = TranslationSpider(w)</span><br><span class="line"> <span class="comment"># 运行</span></span><br><span class="line"> spider.run()</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p><font color=#999AAA >第一个js逆向的项目结束,以后再见。</p>
]]></content>
<categories>
<category>爬虫学习</category>
</categories>
<tags>
<tag>Python</tag>
<tag>有道翻译</tag>
<tag>js逆向</tag>
</tags>
</entry>
<entry>
<title>爬取b站视频弹幕并制作词云一</title>
<url>/posts/fc448f83/</url>
<content><![CDATA[<font color=#999AAA >
用过B站的小伙伴们都知道,B站的弹幕是一绝。
今天我们爬取指定bv号视频下的弹幕,添加到csv文件中并制作成词云。
</font>
<p>优化后的完整代码:<a href="https://blog.csdn.net/HandsomeFishman/article/details/112309330">代码地址</a></p>
<h1 id="一、分析弹幕的接口url地址"><a href="#一、分析弹幕的接口url地址" class="headerlink" title="一、分析弹幕的接口url地址"></a>一、分析弹幕的接口url地址</h1><p><font color=#999AAA >这里有两个地址可以实现爬取弹幕,一个是有限条的,另一个则是根据日期循环爬取,可以实现所有弹幕的爬取。</font><br>案例是冰冰的vlog.001<br><img src="https://img-blog.csdnimg.cn/2021010412201182.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
<a id="more"></a>
<p>第一个不需要登录就可以爬取的接口为:</p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">https://comment.bilibili.com/{oid/cid}.xml</span><br></pre></td></tr></table></figure>
<p>我抓包抓了很久也没有找到这样的包,b站现在把弹幕的接口藏得很深…不是很好找,最后是看着别人的博客在移动端的网页js中找到了这样的请求地址。<br><img src="https://img-blog.csdnimg.cn/20210104114429984.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>可以看到返回的结果是一个xml界面,只需要请求这个界面使用xpath对其进行定位就可以很容易的获取到自己想要的数据。<br><strong>那么我们现在来分析第二个接口:</strong><br><img src="https://img-blog.csdnimg.cn/20210104114644958.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>可以看到右侧有一个弹幕历史的功能,我们先把抓包记录清除一下,点击按钮看看有什么新抓到的包:<br><img src="https://img-blog.csdnimg.cn/20210104114811377.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>可以看到这里出现了一个新的请求,内容是这样的:<br><img src="https://img-blog.csdnimg.cn/20210104114937972.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>这不就是对应的日期嘛,不用想,请求头中肯定会有对应的月份数据,按月份来分组,达到这样的日历点击效果。果然:<br><img src="https://img-blog.csdnimg.cn/20210104115154902.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>点击十二月后,有了新的请求:<br><img src="https://img-blog.csdnimg.cn/20210104115253993.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>因为这个视频是12-31号发布的,所以十二月只有这一个数据。<br>点击具体的一天后:<br><img src="https://img-blog.csdnimg.cn/20210104115450413.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>弹幕的数据就出现了:<br><img src="https://img-blog.csdnimg.cn/2021010411552953.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>所以我们只需要请求对应的日期索引(以月份分组),再循环遍历发送请求就好了,这里需要登录,所以我们使用到cookie,接下来看代码编写。</p>
<h1 id="二、代码编写"><a href="#二、代码编写" class="headerlink" title="二、代码编写"></a>二、代码编写</h1><h2 id="1-引入库"><a href="#1-引入库" class="headerlink" title="1.引入库"></a>1.引入库</h2><p><font color=#999AAA >代码如下:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">from</span> lxml <span class="keyword">import</span> etree</span><br><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">from</span> wordcloud <span class="keyword">import</span> WordCloud</span><br><span class="line"><span class="keyword">import</span> jieba</span><br></pre></td></tr></table></figure>
<h2 id="2-爬虫类编写"><a href="#2-爬虫类编写" class="headerlink" title="2.爬虫类编写"></a>2.爬虫类编写</h2><p><font color=#999AAA >初始化:</font></p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">BarrageSpider</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span>(<span class="params">self, bv</span>):</span></span><br><span class="line"> <span class="comment"># 需要一个bv号,在接下来的代码中进行替换操作</span></span><br><span class="line"> self.bv = bv</span><br><span class="line"> <span class="comment"># 不需要登录的弹幕接口地址 只能爬取部分弹幕</span></span><br><span class="line"> self.barrage_url = <span class="string">'https://comment.bilibili.com/{}.xml'</span></span><br><span class="line"> <span class="comment"># 需要登陆的弹幕接口地址 根据日期进行分类 需要循环爬取 最后归总数据</span></span><br><span class="line"> self.date_url = <span class="string">'https://api.bilibili.com/x/v2/dm/history?type=1&oid={}&date={}'</span> <span class="comment"># 2021-01-01</span></span><br><span class="line"> <span class="comment"># 点击按钮弹出日历的数据接口,这里我们用来作索引</span></span><br><span class="line"> self.index_url = <span class="string">'https://api.bilibili.com/x/v2/dm/history/index?type=1&oid={}&month={}'</span> <span class="comment"># 2021-01</span></span><br><span class="line"> <span class="comment"># 在抓包工具中找的一个简洁的请求,里面有我们需要的oid或者是cid</span></span><br><span class="line"> self.bv_url = <span class="string">'https://api.bilibili.com/x/player/pagelist?bvid='</span> + bv + <span class="string">'&jsonp=jsonp'</span></span><br><span class="line"> <span class="comment"># 不需要登录接口的伪装头</span></span><br><span class="line"> self.comment = {</span><br><span class="line"> <span class="string">'referer'</span>: <span class="string">'https://www.bilibili.com/'</span>,</span><br><span class="line"> <span class="string">'user-agent'</span>: <span class="string">'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '</span></span><br><span class="line"> <span class="string">'Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66 '</span></span><br><span class="line"> }</span><br><span class="line"> <span class="comment"># 需要登录的伪装头 因为需要登录 ip代理已经没有意义了 这里就不再使用IP代理</span></span><br><span class="line"> self.date_headers = {</span><br><span class="line"> <span class="string">"referer"</span>: <span class="string">"https://www.bilibili.com/"</span>,</span><br><span class="line"> <span class="string">"origin"</span>: <span class="string">"https://www.bilibili.com"</span>,</span><br><span class="line"> <span class="string">"cookie"</span>: <span class="string">"cookie"</span>,</span><br><span class="line"> <span class="string">"user-agent"</span>: <span class="string">"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "</span></span><br><span class="line"> <span class="string">"Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66 "</span></span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<p><font color=#999AAA >封装函数:</font></p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 从接口返回的json中获取到我们的cid 注: cid = oid</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">get_cid</span>(<span class="params">self</span>):</span></span><br><span class="line"> <span class="comment"># 定位到数据data中下面的cid</span></span><br><span class="line"> <span class="keyword">return</span> requests.get(url=self.bv_url, headers=self.comment).json()[<span class="string">'data'</span>][<span class="number">0</span>][<span class="string">'cid'</span>]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 解析不需要登录的接口 返回类型是xml文件</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">parse_url</span>(<span class="params">self</span>):</span></span><br><span class="line"> <span class="comment"># 获取指定视频的cid/oid</span></span><br><span class="line"> cid = self.get_cid()</span><br><span class="line"> <span class="comment"># 对页面进行伪装请求,这里注意不要转换成text,使用二进制</span></span><br><span class="line"> response = requests.get(url=self.barrage_url.<span class="built_in">format</span>(cid), headers=self.comment).content</span><br><span class="line"> <span class="comment"># etree解析</span></span><br><span class="line"> data = etree.HTML(response)</span><br><span class="line"> <span class="comment"># 定位到所有的d元素</span></span><br><span class="line"> barrage_list = data.xpath(<span class="string">'//d'</span>)</span><br><span class="line"> <span class="keyword">for</span> barrage <span class="keyword">in</span> barrage_list:</span><br><span class="line"> <span class="comment"># 获取d元素的p属性值</span></span><br><span class="line"> info = barrage.xpath(<span class="string">'./@p'</span>)[<span class="number">0</span>].split(<span class="string">','</span>)</span><br><span class="line"> <span class="comment"># 获取弹幕内容</span></span><br><span class="line"> content = barrage.xpath(<span class="string">'./text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> item = {<span class="string">'出现时间'</span>: info[<span class="number">0</span>], <span class="string">'弹幕模式'</span>: info[<span class="number">1</span>], <span class="string">'字体大小'</span>: info[<span class="number">2</span>], <span class="string">'颜色'</span>: info[<span class="number">3</span>], <span class="string">'发送时间'</span>: info[<span class="number">4</span>], <span class="string">'弹幕池'</span>: info[<span class="number">5</span>],</span><br><span class="line"> <span class="string">'用户ID'</span>: info[<span class="number">6</span>], <span class="string">'rowID'</span>: info[<span class="number">7</span>], <span class="string">'内容'</span>: content}</span><br><span class="line"> <span class="comment"># 因为这只是一部分弹幕 所以就没有进行持久化存储 没有必要</span></span><br><span class="line"> print(item)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 循环爬取所有弹幕 需要传入month的数据 根据视频发布的日期到现在的所有月份</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">parse_date_url</span>(<span class="params">self, month</span>):</span></span><br><span class="line"> <span class="comment"># 存放爬到的数据</span></span><br><span class="line"> result = []</span><br><span class="line"> <span class="comment"># 获取视频的oid</span></span><br><span class="line"> oid = self.get_cid()</span><br><span class="line"> <span class="comment"># 获取日期索引</span></span><br><span class="line"> date_by_month = requests.get(url=self.index_url.<span class="built_in">format</span>(oid, month), headers=self.date_headers).json()[<span class="string">'data'</span>]</span><br><span class="line"> <span class="comment"># 根据日期索引循环请求</span></span><br><span class="line"> <span class="keyword">for</span> day <span class="keyword">in</span> date_by_month:</span><br><span class="line"> <span class="comment"># 注意还是二进制文件</span></span><br><span class="line"> date_page = requests.get(url=self.date_url.<span class="built_in">format</span>(oid, day), headers=self.date_headers).content</span><br><span class="line"> date_data = etree.HTML(date_page)</span><br><span class="line"> <span class="comment"># 解析到到所有的d元素</span></span><br><span class="line"> barrage_list = date_data.xpath(<span class="string">'//d'</span>)</span><br><span class="line"> <span class="comment"># 循环解析数据</span></span><br><span class="line"> <span class="keyword">for</span> barrage <span class="keyword">in</span> barrage_list:</span><br><span class="line"> <span class="comment"># 获取d元素的p属性值</span></span><br><span class="line"> things = barrage.xpath(<span class="string">'./@p'</span>)[<span class="number">0</span>].split(<span class="string">','</span>)</span><br><span class="line"> <span class="comment"># 获取弹幕内容 并去掉所有空格</span></span><br><span class="line"> content = barrage.xpath(<span class="string">'./text()'</span>)[<span class="number">0</span>].replace(<span class="string">" "</span>, <span class="string">""</span>)</span><br><span class="line"> item = {<span class="string">'出现时间'</span>: things[<span class="number">0</span>], <span class="string">'弹幕模式'</span>: things[<span class="number">1</span>], <span class="string">'字体大小'</span>: things[<span class="number">2</span>], <span class="string">'颜色'</span>: things[<span class="number">3</span>], <span class="string">'发送时间'</span>: things[<span class="number">4</span>],</span><br><span class="line"> <span class="string">'弹幕池'</span>: things[<span class="number">5</span>],</span><br><span class="line"> <span class="string">'用户ID'</span>: things[<span class="number">6</span>], <span class="string">'rowID'</span>: things[<span class="number">7</span>], <span class="string">'内容'</span>: content}</span><br><span class="line"> result.append(item)</span><br><span class="line"> <span class="comment"># 返回封装好的数据</span></span><br><span class="line"> <span class="keyword">return</span> result</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">wordCloud</span>(<span class="params">self</span>):</span></span><br><span class="line"> WordCloud(font_path=<span class="string">"C:/Windows/Fonts/simfang.ttf"</span>, background_color=<span class="string">'white'</span>, scale=<span class="number">16</span>).generate(<span class="string">" "</span>.join(</span><br><span class="line"> [c <span class="keyword">for</span> c <span class="keyword">in</span> jieba.cut(<span class="string">""</span>.join(<span class="built_in">str</span>((pd.read_csv(<span class="string">'{}弹幕池数据集.csv'</span>.<span class="built_in">format</span>(self.bv))[<span class="string">'内容'</span>]).tolist()))) <span class="keyword">if</span> <span class="built_in">len</span>(c) > <span class="number">1</span>])).to_file(</span><br><span class="line"> <span class="string">"{}词云.png"</span>.<span class="built_in">format</span>(self.bv))</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p><font color=#999AAA >主函数调用:</font></p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> <span class="comment"># 输入指定的视频bv号</span></span><br><span class="line"> bv_id = <span class="built_in">input</span>(<span class="string">'输入视频对应的bv号:'</span>)</span><br><span class="line"> <span class="comment"># new一个对象</span></span><br><span class="line"> spider = BarrageSpider(bv_id)</span><br><span class="line"> <span class="comment"># 请求今年1月和去年12月的数据 并合并数据</span></span><br><span class="line"> one = spider.parse_date_url(<span class="string">'2021-01'</span>)</span><br><span class="line"> two = spider.parse_date_url(<span class="string">'2020-12'</span>)</span><br><span class="line"> one.extend(two)</span><br><span class="line"> <span class="comment"># 数据格式化处理 并输出csv格式文件</span></span><br><span class="line"> data = pd.DataFrame(one)</span><br><span class="line"> data.drop_duplicates(subset=[<span class="string">'rowID'</span>], keep=<span class="string">'first'</span>)</span><br><span class="line"> <span class="comment"># 字符集编码需要为utf-8-sig 不然会乱码</span></span><br><span class="line"> data.to_csv(<span class="string">'{}弹幕池数据集.csv'</span>.<span class="built_in">format</span>(bv_id), index=<span class="literal">False</span>, encoding=<span class="string">'utf-8-sig'</span>)</span><br><span class="line"> <span class="comment"># 生成词云</span></span><br><span class="line"> spider.wordCloud()</span><br></pre></td></tr></table></figure>
<h1 id="运行结果"><a href="#运行结果" class="headerlink" title="运行结果"></a>运行结果</h1><p><img src="https://img-blog.csdnimg.cn/20210104121710597.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
<p><img src="https://img-blog.csdnimg.cn/20210104121629776.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>可以看到有5000条数据。<br>词云如图:<br><img src="https://img-blog.csdnimg.cn/20210104121736154.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br><strong>注:案例仅供学习</strong></p>
]]></content>
<categories>
<category>爬虫学习</category>
</categories>
<tags>
<tag>Python</tag>
<tag>B站</tag>
<tag>弹幕</tag>
</tags>
</entry>
<entry>
<title>爬取教务成绩的另一种姿势</title>
<url>/posts/b27af333/</url>
<content><![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>之前已经有过一篇爬取成绩的实现blog,是基于学校官网的入口,再进入到教务系统进行查询,中途需要保持session。</p>
<p>现在发现了一个新的入口:</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/f8036105c9a22d9d1dbc3ceb2c97ba79.png"></p>
<a id="more"></a>
<p>于是乎准备从这里进行成绩的爬取,经过一番分析后,发现爬取的姿势中需要包含一些参数,这些参数在网页的源代码中可以找到,即隐含域的值,input标签的hidden属性。如下图:</p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/77b2c8168b8a1bd981cace72ae77b5aa.png"></p>
<p><img src="https://pic.rmb.bdstatic.com/bjh/3ca8b0366ec1acbc996d19fba8d6211c.png"></p>
<p>这样就需要先使用xpath分析网页源代码,取到想要的值,再作post提交的参数。</p>
<p>基本实现逻辑就是这样,下面进行代码的编写。</p>
<h1 id="代码实现"><a href="#代码实现" class="headerlink" title="代码实现"></a>代码实现</h1><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">from</span> lxml <span class="keyword">import</span> etree</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用到的url</span></span><br><span class="line">base_url = <span class="string">'http://202.195.102.33/'</span></span><br><span class="line">login_url = <span class="string">'http://202.195.102.33/login_gh.aspx'</span></span><br><span class="line">home_url = <span class="string">'http://202.195.102.33/web_xsxk/web_xs_xk_cjcx_fzjh.aspx'</span></span><br><span class="line">query_url = <span class="string">'http://202.195.102.33/web_cjgl/web_cj_xscj_cx_jy.aspx'</span></span><br><span class="line"><span class="comment"># ip代理池</span></span><br><span class="line">proxy_pool = [{<span class="string">'HTTP'</span>: <span class="string">'123.169.124.51:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'175.43.56.26:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'113.194.142.137:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'175.42.68.43:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'171.35.175.173:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'113.195.18.159:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'125.108.112.49:9000'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'113.195.23.235:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'121.232.199.237:9000'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'123.101.231.234:9999'</span>}]</span><br><span class="line"><span class="comment"># 请求头伪装</span></span><br><span class="line">headers = {</span><br><span class="line"> <span class="string">'User-Agent'</span>: <span class="string">'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '</span></span><br><span class="line"> <span class="string">'Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66 '</span></span><br><span class="line">}</span><br><span class="line"><span class="comment"># 学号 密码 的数据源</span></span><br><span class="line">data = pd.read_excel(io=<span class="string">'./软件186.xlsx'</span>, nrows=<span class="number">37</span>)</span><br><span class="line">person = []</span><br><span class="line">grade = []</span><br><span class="line"><span class="comment"># 处理账号数据</span></span><br><span class="line"><span class="keyword">for</span> d <span class="keyword">in</span> data.values:</span><br><span class="line"> person.append(</span><br><span class="line"> {</span><br><span class="line"> <span class="string">'学号'</span>: d[<span class="number">1</span>],</span><br><span class="line"> <span class="string">'身份证号'</span>: d[<span class="number">4</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"><span class="keyword">for</span> p <span class="keyword">in</span> person:</span><br><span class="line"> proxies = random.choice(proxy_pool)</span><br><span class="line"> session = requests.session()</span><br><span class="line"> base_data = etree.HTML(session.get(url=base_url, headers=headers, proxies=proxies).content.decode())</span><br><span class="line"> __VIEWSTATE = base_data.xpath(<span class="string">'//input[@id="__VIEWSTATE"]/@value'</span>)[<span class="number">0</span>]</span><br><span class="line"> data = {</span><br><span class="line"> <span class="string">'__VIEWSTATE'</span>: __VIEWSTATE,</span><br><span class="line"> <span class="string">'UserName'</span>: p[<span class="string">'学号'</span>],</span><br><span class="line"> <span class="string">'Password'</span>: p[<span class="string">'身份证号'</span>][-<span class="number">6</span>:],</span><br><span class="line"> <span class="string">'getpassword'</span>: <span class="string">''</span></span><br><span class="line"> }</span><br><span class="line"> session.post(url=login_url, data=data, headers=headers, proxies=proxies)</span><br><span class="line"> __VIEWSTATE = etree.HTML(session.get(url=home_url, headers=headers, proxies=proxies).content.decode()).xpath(</span><br><span class="line"> <span class="string">'//input[@id="__VIEWSTATE'</span></span><br><span class="line"> <span class="string">'"]/@value'</span>)[<span class="number">0</span>]</span><br><span class="line"> data = {</span><br><span class="line"> <span class="string">'__VIEWSTATE'</span>: __VIEWSTATE,</span><br><span class="line"> <span class="string">'ImageButton2.x'</span>: <span class="string">'47'</span>,</span><br><span class="line"> <span class="string">'ImageButton2.y'</span>: <span class="string">'55'</span></span><br><span class="line"> }</span><br><span class="line"> session.post(url=home_url, headers=headers, data=data, proxies=proxies)</span><br><span class="line"> session.get(url=query_url, headers=headers, proxies=proxies).content.decode()</span><br><span class="line"> __VIEWSTATE = etree.HTML(session.get(url=query_url, headers=headers, proxies=proxies).content.decode()).xpath(</span><br><span class="line"> <span class="string">'//input[@id="__VIEWSTATE"]/@value'</span>)[<span class="number">0</span>]</span><br><span class="line"> data = {</span><br><span class="line"> <span class="string">'ScriptManager1'</span>: <span class="string">'UpdatePanel1|Btcx'</span>,</span><br><span class="line"> <span class="string">'__EVENTTARGET'</span>: <span class="string">''</span>,</span><br><span class="line"> <span class="string">'__EVENTARGUMENT'</span>: <span class="string">''</span>,</span><br><span class="line"> <span class="string">'__VIEWSTATE'</span>: __VIEWSTATE,</span><br><span class="line"> <span class="string">'Btcx'</span>: <span class="string">'查询成绩'</span></span><br><span class="line"> }</span><br><span class="line"> headers = {</span><br><span class="line"> <span class="string">'User-Agent'</span>: <span class="string">'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '</span></span><br><span class="line"> <span class="string">'Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66 '</span>,</span><br><span class="line"> <span class="string">'X-MicrosoftAjax'</span>: <span class="string">'Delta=true'</span></span><br><span class="line"> }</span><br><span class="line"> query_page = session.post(url=query_url, headers=headers, data=data, proxies=proxies).content.decode()</span><br><span class="line"> table = etree.HTML(query_page)</span><br><span class="line"> trs = table.xpath(<span class="string">'//table[@id="gvcj1"]/tr[@class="dg1-item"]'</span>)</span><br><span class="line"> count = <span class="number">1</span></span><br><span class="line"> td_date = {}</span><br><span class="line"> <span class="keyword">for</span> td <span class="keyword">in</span> trs:</span><br><span class="line"> name = td.xpath(<span class="string">'./td[2]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> subject = td.xpath(<span class="string">'./td[4]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> score = td.xpath(<span class="string">'./td[7]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">if</span> count == <span class="number">1</span>:</span><br><span class="line"> print(<span class="string">'正在爬取{}的成绩...'</span>.<span class="built_in">format</span>(name))</span><br><span class="line"> td_date[<span class="string">'姓名'</span>] = name</span><br><span class="line"> td_date[subject] = score</span><br><span class="line"> count += <span class="number">1</span></span><br><span class="line"> grade.append(td_date)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 持久化存储</span></span><br><span class="line">save = pd.DataFrame(grade)</span><br><span class="line">save.to_csv(<span class="string">'软件186班级成绩.csv'</span>, index=<span class="literal">False</span>, encoding=<span class="string">'utf-8-sig'</span>)</span><br></pre></td></tr></table></figure>
<h1 id="结果截图"><a href="#结果截图" class="headerlink" title="结果截图"></a>结果截图</h1><p><img src="https://pic.rmb.bdstatic.com/bjh/46610b138dc5600651538ba44fc9834b.png"></p>
]]></content>
<categories>
<category>爬虫学习</category>
</categories>
<tags>
<tag>Python</tag>
<tag>成绩查询</tag>
</tags>
</entry>
<entry>
<title>爬取豆瓣评论并进行数据可视化</title>
<url>/posts/31c415b7/</url>
<content><![CDATA[<font color=#999AAA >
使用python对豆瓣进行评论爬取,并数据可视化
</font>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p><font color=#999AAA >对豆瓣界面进行分析,没有前后端分离,对界面元素分析后,爬取相关信息并保存在csv表格中,然后进行数据分析。</font></p>
<p><font color=#999AAA >提示:以下是本篇文章正文内容,下面案例可供参考</p>
<h1 id="一、思路分析"><a href="#一、思路分析" class="headerlink" title="一、思路分析"></a>一、思路分析</h1><p>分析豆瓣页面数据,以及怎样实现循环爬取。<br><img src="https://img-blog.csdnimg.cn/20210103191844540.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
<a id="more"></a>
<p>解析到class为review-list 的div中,存放着一片div列表,也就是评论界面。<br><img src="https://img-blog.csdnimg.cn/20210103192008970.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>将其中的元素一一对应起来,接下来进行下一页爬取的分析。<br><img src="https://img-blog.csdnimg.cn/20210103192120312.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>get请求携带的start参数改变,并且步长是20,也就是20条数据。也就是说,循环请求的地址为:<br><a href="https://movie.douban.com/subject/27069428/reviews?start=0">https://movie.douban.com/subject/27069428/reviews?start=0</a><br><a href="https://movie.douban.com/subject/27069428/reviews?start=20">https://movie.douban.com/subject/27069428/reviews?start=20</a><br><a href="https://movie.douban.com/subject/27069428/reviews?start=40">https://movie.douban.com/subject/27069428/reviews?start=40</a><br><a href="https://movie.douban.com/subject/27069428/reviews?start=60">https://movie.douban.com/subject/27069428/reviews?start=60</a><br>……<br>接下来进行代码的编写。</p>
<h1 id="二、代码编写"><a href="#二、代码编写" class="headerlink" title="二、代码编写"></a>二、代码编写</h1><h2 id="1-引入库"><a href="#1-引入库" class="headerlink" title="1.引入库"></a>1.引入库</h2><p><font color=#999AAA >代码如下:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> csv</span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">from</span> lxml <span class="keyword">import</span> etree</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">from</span> fake_useragent <span class="keyword">import</span> UserAgent</span><br><span class="line"></span><br><span class="line"><span class="comment"># 伪装头</span></span><br><span class="line">headers = {</span><br><span class="line"> <span class="string">'User-Agent'</span>: UserAgent().random,</span><br><span class="line"> <span class="string">'Host'</span>: <span class="string">'movie.douban.com'</span>,</span><br><span class="line"> <span class="string">'Connection'</span>: <span class="string">'keep-alive'</span></span><br><span class="line">}</span><br><span class="line"><span class="comment"># 遍历用的url模板</span></span><br><span class="line">base_url = <span class="string">'https://movie.douban.com/subject/27069428/reviews?start={}'</span></span><br><span class="line"><span class="comment"># 代理池</span></span><br><span class="line">proxy_pool = [{<span class="string">'http'</span>: <span class="string">'http://123.169.118.8:9999'</span>}, {<span class="string">'http'</span>: <span class="string">'http://175.43.154.137:9999'</span>}, {<span class="string">'http'</span>: <span class="string">'http://117.91.165.126:9999'</span>}, {<span class="string">'http'</span>: <span class="string">'http://113.124.86.125:9999'</span>}]</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="2-解析页面数据"><a href="#2-解析页面数据" class="headerlink" title="2.解析页面数据"></a>2.解析页面数据</h2><p><font color=#999AAA >代码如下:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_detail</span>(<span class="params">url</span>):</span></span><br><span class="line"> <span class="comment"># 网页请求</span></span><br><span class="line"> response = requests.get(url=url, headers=headers, proxies=random.choice(proxy_pool)).text</span><br><span class="line"> response_data = etree.HTML(response)</span><br><span class="line"> <span class="comment"># etree解析网页 获得评论的div列表</span></span><br><span class="line"> div_list = response_data.xpath(<span class="string">'//div[@class="review-list "]/div'</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"> name = div.xpath(<span class="string">'./div/header/a[@class="name"]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> level = div.xpath(<span class="string">'./div/header/span[1]/@title'</span>)</span><br><span class="line"> <span class="comment"># 有的评价为空 list列表取[0]会报错</span></span><br><span class="line"> <span class="keyword">if</span> <span class="built_in">len</span>(level):</span><br><span class="line"> level = level[<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> level = <span class="string">'暂无评价'</span></span><br><span class="line"> time = div.xpath(<span class="string">'./div/header/span[@class="main-meta"]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> title = div.xpath(<span class="string">'./div/div/h2/a/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> content = <span class="string">""</span>.join(div.xpath(<span class="string">'./div/div/div[1]/div[@class="short-content"]/text()'</span>)).replace(<span class="string">"\n"</span>,</span><br><span class="line"> <span class="string">""</span>).replace(<span class="string">" "</span>, <span class="string">""</span>).split(<span class="string">"..."</span>)[<span class="number">0</span>]</span><br><span class="line"> up = div.xpath(<span class="string">'./div/div/div[@class="action"]/a[1]/span/text()'</span>)[<span class="number">0</span>].replace(<span class="string">"\n"</span>, <span class="string">""</span>).replace(<span class="string">" "</span>, <span class="string">""</span>)</span><br><span class="line"> down = div.xpath(<span class="string">'./div/div/div[@class="action"]/a[2]/span/text()'</span>)[<span class="number">0</span>].replace(<span class="string">"\n"</span>, <span class="string">""</span>).replace(<span class="string">" "</span>, <span class="string">""</span>)</span><br><span class="line"> reply = div.xpath(<span class="string">'./div/div/div[@class="action"]/a[3]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> detail = [name, level, time, title, content, up, down, reply]</span><br><span class="line"> <span class="comment"># 返回对应的一条数据</span></span><br><span class="line"> <span class="keyword">yield</span> detail</span><br></pre></td></tr></table></figure>
<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">
<h2 id="3-编写主函数"><a href="#3-编写主函数" class="headerlink" title="3.编写主函数"></a>3.编写主函数</h2><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> <span class="comment"># 打开表格文件 注意编码格式</span></span><br><span class="line"> file = <span class="built_in">open</span>(<span class="string">'有翡.csv'</span>, <span class="string">'w'</span>, newline=<span class="string">''</span>, encoding=<span class="string">'utf-8-sig'</span>)</span><br><span class="line"> writer = csv.writer(file)</span><br><span class="line"> <span class="comment"># 写表格的头部</span></span><br><span class="line"> writer.writerow([<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><br><span class="line"> <span class="comment"># 循环遍历 爬取所有评论</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">1101</span>, <span class="number">20</span>):</span><br><span class="line"> print(<span class="string">'正在爬取start={}的数据'</span>.<span class="built_in">format</span>(i))</span><br><span class="line"> <span class="comment"># 获得返回的数据</span></span><br><span class="line"> res = get_detail(base_url.<span class="built_in">format</span>(i))</span><br><span class="line"> <span class="comment"># 数据写入</span></span><br><span class="line"> writer.writerows(res)</span><br></pre></td></tr></table></figure>
<p>结果表格为:<br><img src="https://img-blog.csdnimg.cn/20210103192914142.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">
<h2 id="4-词云"><a href="#4-词云" class="headerlink" title="4.词云"></a>4.词云</h2><p>直接上代码:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">from</span> wordcloud <span class="keyword">import</span> WordCloud</span><br><span class="line"><span class="keyword">import</span> jieba</span><br><span class="line"></span><br><span class="line">all_content = <span class="string">''</span></span><br><span class="line">list_txt = []</span><br><span class="line">data = pd.read_csv(<span class="string">'test.csv'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> data[<span class="string">'评论标题'</span>]:</span><br><span class="line"> all_content += <span class="built_in">str</span>(i)</span><br><span class="line"><span class="keyword">for</span> c <span class="keyword">in</span> jieba.cut(all_content):</span><br><span class="line"> <span class="keyword">if</span> <span class="built_in">len</span>(c) >= <span class="number">2</span>:</span><br><span class="line"> list_txt.append(c)</span><br><span class="line">cut_text = <span class="string">" "</span>.join(list_txt)</span><br><span class="line">wordcloud = WordCloud(font_path=<span class="string">"C:/Windows/Fonts/simfang.ttf"</span>,</span><br><span class="line"> background_color=<span class="string">'white'</span>,</span><br><span class="line"> scale=<span class="number">32</span>,</span><br><span class="line"> mode=<span class="string">'RGBA'</span>,</span><br><span class="line"> margin=<span class="number">1</span>).generate(cut_text)</span><br><span class="line">filename = <span class="string">"test.png"</span></span><br><span class="line">wordcloud.to_file(filename)</span><br><span class="line">os.startfile(filename)</span><br></pre></td></tr></table></figure>
<p><strong>两张结果图片分别为:</strong></p>
<p>评论标题:<br><img src="https://img-blog.csdnimg.cn/20210103193316430.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>评论主体:<br><img src="https://img-blog.csdnimg.cn/20210103193418469.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>在舍友的指点下,成功将词云的代码只用一行实现,代码如下:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">from</span> wordcloud <span class="keyword">import</span> WordCloud</span><br><span class="line"><span class="keyword">import</span> jieba</span><br><span class="line"></span><br><span class="line">WordCloud(font_path=<span class="string">"C:/Windows/Fonts/simfang.ttf"</span>, background_color=<span class="string">'white'</span>, scale=<span class="number">16</span>).generate(<span class="string">" "</span>.join([c <span class="keyword">for</span> c <span class="keyword">in</span> jieba.cut(<span class="string">""</span>.join(<span class="built_in">str</span>((pd.read_csv(<span class="string">'test.csv'</span>)[<span class="string">'评论主体'</span>]).tolist()))) <span class="keyword">if</span> <span class="built_in">len</span>(c) > <span class="number">1</span>])).to_file(<span class="string">"test.png"</span>)</span><br></pre></td></tr></table></figure>
<h2 id="5-评分柱状图"><a href="#5-评分柱状图" class="headerlink" title="5.评分柱状图"></a>5.评分柱状图</h2><p>数据清洗直接上代码:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"></span><br><span class="line">data = pd.read_csv(<span class="string">'test.csv'</span>)[<span class="string">'评价'</span>]</span><br><span class="line">star = []</span><br><span class="line"><span class="keyword">for</span> level <span class="keyword">in</span> data:</span><br><span class="line"> <span class="keyword">if</span> level == <span class="string">'力荐'</span>:</span><br><span class="line"> star.append(<span class="number">5</span>)</span><br><span class="line"> <span class="keyword">elif</span> level == <span class="string">'推荐'</span>:</span><br><span class="line"> star.append(<span class="number">4</span>)</span><br><span class="line"> <span class="keyword">elif</span> level == <span class="string">'还行'</span>:</span><br><span class="line"> star.append(<span class="number">3</span>)</span><br><span class="line"> <span class="keyword">elif</span> level == <span class="string">'较差'</span>:</span><br><span class="line"> star.append(<span class="number">2</span>)</span><br><span class="line"> <span class="keyword">elif</span> level == <span class="string">'很差'</span>:</span><br><span class="line"> star.append(<span class="number">1</span>)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> star.append(<span class="number">0</span>)</span><br><span class="line">plt.rcParams[<span class="string">'font.sans-serif'</span>] = [<span class="string">'SimHei'</span>]</span><br><span class="line">plt.figure(figsize=(<span class="number">12</span>, <span class="number">8</span>))</span><br><span class="line">plt.hist(star, bins=<span class="number">17</span>)</span><br><span class="line">plt.xlabel(<span class="string">'评价等级(0表示没有评分)'</span>, size=<span class="number">18</span>)</span><br><span class="line">plt.ylabel(<span class="string">'人数'</span>, size=<span class="number">20</span>)</span><br><span class="line">plt.savefig(<span class="string">'评分.jpg'</span>)</span><br></pre></td></tr></table></figure>
<p>结果图:<br><img src="https://img-blog.csdnimg.cn/20210103194704217.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p><font color=#999AAA >以上就是今天要讲的内容,本文仅仅简单介绍了爬虫的使用和数据可视化的冰山一角,以后再见吧!<br><strong>注:案例仅供学习</strong></p>
]]></content>
<categories>
<category>爬虫学习</category>
</categories>
<tags>
<tag>Python</tag>
<tag>豆瓣</tag>
<tag>评论</tag>
</tags>
</entry>
<entry>
<title>爬取链家二手房信息并存储到数据库</title>
<url>/posts/2e361f77/</url>
<content><![CDATA[<font color=#999AAA >
爬取链家的二手房信息,存储到数据库方便以后查看
</font>
<h1 id="页面分析"><a href="#页面分析" class="headerlink" title="页面分析"></a>页面分析</h1><p><font color=#999AAA >分析页面后发现是前后端未分离的状态,所以需要使用xpath分析界面元素</font><br><img src="https://img-blog.csdnimg.cn/20210103184811880.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
<a id="more"></a>
<p>在li中存放着对应的div,有相关的信息:<br><img src="https://img-blog.csdnimg.cn/2021010318494381.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>分析请求链接:<br><img src="https://img-blog.csdnimg.cn/20210103185129747.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>只需要更改pg后面的数字即可,页面分析完毕。</p>
<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">
<p><font color=#999AAA >提示:以下是本篇文章正文内容,下面案例可供参考</p>
<h1 id="引入库"><a href="#引入库" class="headerlink" title="引入库"></a>引入库</h1><p><font color=#999AAA >代码如下:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> lxml <span class="keyword">import</span> etree</span><br><span class="line"><span class="keyword">from</span> fake_useragent <span class="keyword">import</span> UserAgent</span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">import</span> pymysql</span><br><span class="line"></span><br><span class="line"><span class="comment"># 代理池</span></span><br><span class="line">proxy_pool = [{<span class="string">'HTTP'</span>: <span class="string">'175.43.151.3:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'220.249.149.140:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'175.44.108.206:9999'</span>},</span><br><span class="line"> {<span class="string">'HTTP'</span>: <span class="string">'120.83.101.115:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'175.42.122.233:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'60.13.42.107:9999'</span>},</span><br><span class="line"> {<span class="string">'HTTP'</span>: <span class="string">'113.195.152.127:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'36.248.133.196:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'120.83.105.95:9999'</span>},</span><br><span class="line"> {<span class="string">'HTTP'</span>: <span class="string">'112.111.217.160:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'171.12.221.158:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'113.121.72.221:9999'</span>}]</span><br><span class="line"><span class="comment"># 伪装头</span></span><br><span class="line">headers = {</span><br><span class="line"> <span class="string">'Host'</span>: <span class="string">'nj.lianjia.com'</span>,</span><br><span class="line"> <span class="string">'User-Agent'</span>: UserAgent().random</span><br><span class="line">}</span><br><span class="line"><span class="comment"># 开启数据库</span></span><br><span class="line">conn = pymysql.Connect(host=<span class="string">'localhost'</span>, port=<span class="number">3306</span>, user=<span class="string">'用户名'</span>,</span><br><span class="line"> password=<span class="string">'数据库密码'</span>, db=<span class="string">'对应数据库'</span>, charset=<span class="string">'utf8'</span>)</span><br></pre></td></tr></table></figure>
<h1 id="方法编写"><a href="#方法编写" class="headerlink" title="方法编写"></a>方法编写</h1><p><font color=#999AAA >代码如下:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_page</span>(<span class="params">url</span>):</span></span><br><span class="line"> <span class="comment"># 请求页面</span></span><br><span class="line"> response = requests.get(url=url, headers=headers, proxies=random.choice(proxy_pool)).text</span><br><span class="line"> <span class="comment"># 使用etree解析对象</span></span><br><span class="line"> parse_data = etree.HTML(response)</span><br><span class="line"> <span class="comment"># 获取li的列表</span></span><br><span class="line"> li_list = parse_data.xpath(<span class="string">'//ul[@class="sellListContent"]/li'</span>)</span><br><span class="line"> <span class="comment"># 循环</span></span><br><span class="line"> <span class="keyword">for</span> li <span class="keyword">in</span> li_list:</span><br><span class="line"> <span class="comment"># 标题</span></span><br><span class="line"> title = li.xpath(<span class="string">'./div[@class="info clear"]/div[@class="title"]/a/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># 地址</span></span><br><span class="line"> flood = li.xpath(<span class="string">'./div[@class="info clear"]/div[@class="flood"]/div[@class="positionInfo"]/a[1]/text()'</span>)[<span class="number">0</span>] + \</span><br><span class="line"> <span class="string">'- '</span> + \</span><br><span class="line"> li.xpath(<span class="string">'./div[@class="info clear"]/div[@class="flood"]/div[@class="positionInfo"]/a[2]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># 房型描述</span></span><br><span class="line"> address = li.xpath(<span class="string">'./div[@class="info clear"]/div[@class="address"]/div[@class="houseInfo"]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># 状态</span></span><br><span class="line"> followInfo = li.xpath(<span class="string">'./div[@class="info clear"]/div[@class="followInfo"]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># 总价</span></span><br><span class="line"> totalPrice = li.xpath(<span class="string">'./div[@class="info clear"]/div[@class="priceInfo"]/div[@class="totalPrice"]/span['</span></span><br><span class="line"> <span class="string">'1]/text()'</span>)[<span class="number">0</span>] + <span class="string">'万'</span></span><br><span class="line"> <span class="comment"># 单价</span></span><br><span class="line"> unitPrice = li.xpath(<span class="string">'./div[@class="info clear"]/div[@class="priceInfo"]/div[@class="unitPrice"]/span[1]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># mysql数据库操作语句</span></span><br><span class="line"> sql = <span class="string">'insert into lianjia(title, flood, address, followInfo,totalPrice, unitPrice) '</span> \</span><br><span class="line"> <span class="string">'values ("{}", "{}", "{}", "{}", "{}", "{}")'</span>.<span class="built_in">format</span>(title, flood, address, followInfo, totalPrice, unitPrice)</span><br><span class="line"> cursor = conn.cursor()</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> <span class="comment"># 执行语句</span></span><br><span class="line"> cursor.execute(sql)</span><br><span class="line"> <span class="comment"># 事务</span></span><br><span class="line"> conn.commit()</span><br><span class="line"> <span class="keyword">except</span> Exception <span class="keyword">as</span> e:</span><br><span class="line"> print(e)</span><br><span class="line"> <span class="comment"># 异常则回滚,保证数据安全</span></span><br><span class="line"> conn.rollback()</span><br></pre></td></tr></table></figure>
<h1 id="主函数编写"><a href="#主函数编写" class="headerlink" title="主函数编写"></a>主函数编写</h1><p><font color=#999AAA >代码如下:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> <span class="comment"># 数据库模板</span></span><br><span class="line"> base_url = <span class="string">'https://nj.lianjia.com/ershoufang/pg{}/'</span></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> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">101</span>):</span><br><span class="line"> get_page(base_url.<span class="built_in">format</span>(i))</span><br><span class="line"> print(<span class="string">'正在存储第{}条'</span>.<span class="built_in">format</span>(i) + <span class="string">'....'</span>)</span><br><span class="line"> <span class="comment"># 关闭数据库链接</span></span><br><span class="line"> conn.close()</span><br></pre></td></tr></table></figure>
<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">
<h1 id="运行结果"><a href="#运行结果" class="headerlink" title="运行结果"></a>运行结果</h1><p><img src="https://img-blog.csdnimg.cn/20210103190350411.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>对其进行条件查找,找出自己想要的数据:<br><img src="https://img-blog.csdnimg.cn/20210103190905199.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br><strong>注:案例仅供学习</strong></p>
]]></content>
<categories>
<category>爬虫学习</category>
</categories>
<tags>
<tag>Python</tag>
<tag>链家</tag>
<tag>二手房</tag>
</tags>
</entry>
<entry>
<title>笔趣网整本小说爬取</title>
<url>/posts/cf49fdc5/</url>
<content><![CDATA[<font color=#999AAA >
使用python对笔趣网小说进行逐页爬取。
</font>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p><font color=#999AAA >这个网站的下载链接奇慢无比,闲来无事,使用python对其进行循环爬取。</font></p>
<p><font color=#999AAA >以下是本篇文章正文内容,下面案例可供参考</p>
<h1 id="一、页面分析"><a href="#一、页面分析" class="headerlink" title="一、页面分析"></a>一、页面分析</h1><p><img src="https://img-blog.csdnimg.cn/20210117152047206.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>很显然,这是书籍的详情页,我们在这个页面只需要两种数据,一个就是我们的书籍名称,还有就是对应章节的详情链接,只有获取了章节的详情链接我们才可以进行文字的爬取。</p>
<a id="more"></a>
<p><img src="https://img-blog.csdnimg.cn/20210117152300155.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>可以看出来这个界面很简单,也没什么反爬措施,轻而易举获得我们想要的数据。<br><img src="https://img-blog.csdnimg.cn/20210117152403409.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>这里唯一要注意的就是获取的文字内容是list,我们需要在其中进行再遍历。<br>然后替换其中的换行之类的无用字符,最后写入到txt文件中。</p>
<h1 id="二、代码编写"><a href="#二、代码编写" class="headerlink" title="二、代码编写"></a>二、代码编写</h1><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">from</span> fake_useragent <span class="keyword">import</span> UserAgent</span><br><span class="line"><span class="keyword">from</span> lxml <span class="keyword">import</span> etree</span><br><span class="line"></span><br><span class="line"><span class="comment"># 代理池</span></span><br><span class="line">proxy_pool = [{<span class="string">'HTTP'</span>: <span class="string">'175.42.129.251:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'175.43.156.31:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'175.43.58.14:9999'</span>},</span><br><span class="line"> {<span class="string">'HTTP'</span>: <span class="string">'120.84.101.48:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'223.247.164.191:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'182.46.121.25:9999'</span>},</span><br><span class="line"> {<span class="string">'HTTP'</span>: <span class="string">'115.221.245.116:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'58.22.177.192:9999'</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"><span class="class"><span class="keyword">class</span> <span class="title">BiQuSpider</span>:</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, url</span>):</span></span><br><span class="line"> print(<span class="string">'正在初始化...'</span>)</span><br><span class="line"> self.url = url</span><br><span class="line"> self.headers = {</span><br><span class="line"> <span class="string">"Referer"</span>: url,</span><br><span class="line"> <span class="string">'User-Agent'</span>: UserAgent().random</span><br><span class="line"> }</span><br><span class="line"> self.bookName = <span class="literal">None</span></span><br><span class="line"> self.url_pool = []</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">get_urls</span>(<span class="params">self</span>):</span></span><br><span class="line"> response = requests.get(url=self.url, headers=self.headers, proxies=random.choice(proxy_pool))</span><br><span class="line"> result = etree.HTML(response.content.decode())</span><br><span class="line"> title = result.xpath(<span class="string">'//div[@id="info"]/h1/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> self.bookName = title</span><br><span class="line"> urls = result.xpath(<span class="string">'//div[@class="book_list"]/ul/li'</span>)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> urls:</span><br><span class="line"> url = <span class="string">'http://www.biquw.com/book/94/'</span> + i.xpath(<span class="string">'./a/@href'</span>)[<span class="number">0</span>]</span><br><span class="line"> self.url_pool.append(url)</span><br><span class="line"> print(<span class="string">'章节链接爬取完毕...'</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">get_text</span>(<span class="params">self</span>):</span></span><br><span class="line"> <span class="keyword">for</span> url <span class="keyword">in</span> self.url_pool:</span><br><span class="line"> data = []</span><br><span class="line"> content_page = requests.get(url=url, headers=self.headers, proxies=random.choice(proxy_pool))</span><br><span class="line"> result = etree.HTML(content_page.content.decode())</span><br><span class="line"> content = result.xpath(<span class="string">'//div[@id="htmlContent"]'</span>)[<span class="number">0</span>]</span><br><span class="line"> title = result.xpath(<span class="string">'//div[@class="h1title"]/h1/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> print(<span class="string">'正在爬取{}'</span>.<span class="built_in">format</span>(title))</span><br><span class="line"> <span class="keyword">for</span> t <span class="keyword">in</span> content.xpath(<span class="string">'./text()'</span>):</span><br><span class="line"> text = t.replace(<span class="string">"\n"</span>, <span class="string">""</span>).replace(<span class="string">"\xa0"</span>, <span class="string">""</span>)</span><br><span class="line"> <span class="keyword">if</span> text:</span><br><span class="line"> data.append(<span class="string">' '</span> + text)</span><br><span class="line"> txt = <span class="string">'\n'</span>.join(data)</span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">'./{}.txt'</span>.<span class="built_in">format</span>(self.bookName), <span class="string">'a'</span>, encoding=<span class="string">'utf-8'</span>) <span class="keyword">as</span> w:</span><br><span class="line"> w.write(title + <span class="string">'\n'</span> + txt + <span class="string">'\n\n'</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">run</span>(<span class="params">self</span>):</span></span><br><span class="line"> self.get_urls()</span><br><span class="line"> self.get_text()</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"> spider = BiQuSpider(<span class="string">'http://www.biquw.com/book/94/'</span>)</span><br><span class="line"> spider.run()</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h1 id="结果"><a href="#结果" class="headerlink" title="结果"></a>结果</h1><p><img src="https://img-blog.csdnimg.cn/20210117152713346.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
]]></content>
<categories>
<category>爬虫学习</category>
</categories>
<tags>
<tag>Python</tag>
<tag>小说</tag>
</tags>
</entry>
<entry>
<title>百度翻译js逆向</title>
<url>/posts/c39daa58/</url>
<content><![CDATA[<p><img src="https://img-blog.csdnimg.cn/20210114115804948.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
<p>对百度翻译的js逆向爬虫分析。</p>
<a id="more"></a>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p><font color=#999AAA >在有道翻译的基础上对百度翻译进行js逆向</font><br><font color=#999AAA >以下是本篇文章正文内容,下面案例可供参考</p>
<h1 id="一、分析接口"><a href="#一、分析接口" class="headerlink" title="一、分析接口"></a>一、分析接口</h1><p>在输入框输入英文,在自带的抓包工具中可以看到有一个新的异步请求:<br><img src="https://img-blog.csdnimg.cn/20210114115804948.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>可以看到这里是需要cookie和token的:<br><img src="https://img-blog.csdnimg.cn/20210114115853560.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br><img src="https://img-blog.csdnimg.cn/20210114120028733.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>进行全局搜索sign:<br><img src="https://img-blog.csdnimg.cn/20210114120407509.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>可以看到这里就是我们传进去的参数,我们进行格式化,并找到相应的语句打断点:<br><img src="https://img-blog.csdnimg.cn/20210114120610152.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>可以看到n就是我们输入的数据,token是根据 window.common.token生成的,simple_means_flag始终为 3,transtype始终为realtime。<br>我们最后解决一下sign生成的问题,看一下生成的函数:<br><img src="https://img-blog.csdnimg.cn/20210114120853522.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>可以看到函数很长,我们使用python进行模拟的话,工作量是很大的,于是使用第三方库直接编译js,并分析函数过程中需要哪些值,要传哪些参数。<br>运行中发现缺少i的值,是不变的,于是补齐:<br><img src="https://img-blog.csdnimg.cn/20210114121216367.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>又发现有一个函数n没有定义:<br><img src="https://img-blog.csdnimg.cn/20210114121314159.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>定位到n所在的位置,就在函数e的上方,并在js文件中补齐:<br><img src="https://img-blog.csdnimg.cn/20210114121350149.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>到此分析已经结束,接下来进行代码的编写。</p>
<h1 id="二、代码编写"><a href="#二、代码编写" class="headerlink" title="二、代码编写"></a>二、代码编写</h1><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> execjs</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 模仿JavaScript生成sign参数</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_sign</span>(<span class="params">word</span>):</span></span><br><span class="line"> <span class="comment"># 打开js文件</span></span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">'test.js'</span>, <span class="string">'r'</span>, encoding=<span class="string">'utf8'</span>) <span class="keyword">as</span> js:</span><br><span class="line"> js_code = js.read()</span><br><span class="line"> <span class="comment"># 运行 js 文件</span></span><br><span class="line"> sign = execjs.<span class="built_in">compile</span>(js_code).call(<span class="string">'e'</span>, word)</span><br><span class="line"> <span class="comment"># 返回参数</span></span><br><span class="line"> <span class="keyword">return</span> sign</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="function"><span class="keyword">def</span> <span class="title">request</span>(<span class="params">word</span>):</span></span><br><span class="line"> <span class="comment"># 中英文识别</span></span><br><span class="line"> <span class="keyword">if</span> word[<span class="number">0</span>] <span class="keyword">in</span> [<span class="string">'a'</span>, <span class="string">'b'</span>, <span class="string">'c'</span>, <span class="string">'d'</span>, <span class="string">'e'</span>, <span class="string">'f'</span>, <span class="string">'g'</span>, <span class="string">'h'</span>, <span class="string">'i'</span>, <span class="string">'j'</span>, <span class="string">'k'</span>, <span class="string">'l'</span>, <span class="string">'m'</span>, <span class="string">'n'</span>,</span><br><span class="line"> <span class="string">'o'</span>, <span class="string">'p'</span>, <span class="string">'q'</span>, <span class="string">'r'</span>, <span class="string">'s'</span>, <span class="string">'t'</span>, <span class="string">'u'</span>, <span class="string">'v'</span>, <span class="string">'w'</span>, <span class="string">'x'</span>, <span class="string">'y'</span>, <span class="string">'z'</span>,</span><br><span class="line"> <span class="string">'A'</span>, <span class="string">'B'</span>, <span class="string">'C'</span>, <span class="string">'D'</span>, <span class="string">'E'</span>, <span class="string">'F'</span>, <span class="string">'G'</span>, <span class="string">'H'</span>, <span class="string">'I'</span>, <span class="string">'J'</span>, <span class="string">'K'</span>, <span class="string">'L'</span>, <span class="string">'M'</span>, <span class="string">'N'</span>,</span><br><span class="line"> <span class="string">'O'</span>, <span class="string">'P'</span>, <span class="string">'Q'</span>, <span class="string">'R'</span>, <span class="string">'S'</span>, <span class="string">'T'</span>, <span class="string">'U'</span>, <span class="string">'V'</span>, <span class="string">'W'</span>, <span class="string">'X'</span>, <span class="string">'Y'</span>, <span class="string">'Z'</span>]:</span><br><span class="line"> f = <span class="string">'en'</span></span><br><span class="line"> t = <span class="string">'zh'</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> f = <span class="string">'zh'</span></span><br><span class="line"> t = <span class="string">'en'</span></span><br><span class="line"> <span class="comment"># 获取sign</span></span><br><span class="line"> sign = get_sign(word)</span><br><span class="line"> url = <span class="string">'https://fanyi.baidu.com/v2transapi?from=en&to=zh'</span></span><br><span class="line"> <span class="comment"># 伪装头</span></span><br><span class="line"> headers = {</span><br><span class="line"> <span class="string">'cookie'</span>: <span class="string">'你的cookie'</span>,</span><br><span class="line"> <span class="string">'user-agent'</span>: <span class="string">'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '</span></span><br><span class="line"> <span class="string">'Chrome/87.0.4280.141 Safari/537.36 Edg/87.0.664.75 '</span></span><br><span class="line"> }</span><br><span class="line"> <span class="comment"># post提交的参数</span></span><br><span class="line"> formData = {</span><br><span class="line"> <span class="string">'from'</span>: f,</span><br><span class="line"> <span class="string">'to'</span>: t,</span><br><span class="line"> <span class="string">'query'</span>: word,</span><br><span class="line"> <span class="string">'transtype'</span>: <span class="string">'realtime'</span>,</span><br><span class="line"> <span class="string">'simple_means_flag'</span>: <span class="string">'3'</span>,</span><br><span class="line"> <span class="string">'sign'</span>: sign,</span><br><span class="line"> <span class="string">'token'</span>: <span class="string">'你的token'</span>,</span><br><span class="line"> <span class="string">'domain'</span>: <span class="string">'common'</span></span><br><span class="line"> }</span><br><span class="line"> <span class="comment"># 请求 并转json</span></span><br><span class="line"> response = requests.post(url=url, headers=headers, data=formData).json()</span><br><span class="line"> <span class="comment"># json数据分析</span></span><br><span class="line"> <span class="keyword">if</span> response.get(<span class="string">'liju_result'</span>).get(<span class="string">'tag'</span>):</span><br><span class="line"> print(<span class="string">', '</span>.join(response.get(<span class="string">'liju_result'</span>).get(<span class="string">'tag'</span>)))</span><br><span class="line"> <span class="keyword">if</span> response.get(<span class="string">'trans_result'</span>).get(<span class="string">'data'</span>):</span><br><span class="line"> <span class="keyword">for</span> d <span class="keyword">in</span> response.get(<span class="string">'trans_result'</span>).get(<span class="string">'data'</span>):</span><br><span class="line"> print(d[<span class="string">'dst'</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 class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> word = <span class="built_in">input</span>(<span class="string">'请输入需要翻译的英文(中文):'</span>)</span><br><span class="line"> <span class="keyword">if</span> word == <span class="string">'exit0'</span>:</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> request(word)</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>下面是JavaScript代码:</p>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">e</span>(<span class="params">r</span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> i = <span class="string">'320305.131321201'</span></span><br><span class="line"> <span class="keyword">var</span> o = r.match(<span class="regexp">/[\uD800-\uDBFF][\uDC00-\uDFFF]/g</span>);</span><br><span class="line"> <span class="keyword">if</span> (<span class="literal">null</span> === o) {</span><br><span class="line"> <span class="keyword">var</span> t = r.length;</span><br><span class="line"> t > <span class="number">30</span> && (r = <span class="string">""</span> + r.substr(<span class="number">0</span>, <span class="number">10</span>) + r.substr(<span class="built_in">Math</span>.floor(t / <span class="number">2</span>) - <span class="number">5</span>, <span class="number">10</span>) + r.substr(-<span class="number">10</span>, <span class="number">10</span>))</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> e = r.split(<span class="regexp">/[\uD800-\uDBFF][\uDC00-\uDFFF]/</span>), C = <span class="number">0</span>, h = e.length, f = []; h > C; C++)</span><br><span class="line"> <span class="string">""</span> !== e[C] && f.push.apply(f, a(e[C].split(<span class="string">""</span>))),</span><br><span class="line"> C !== h - <span class="number">1</span> && f.push(o[C]);</span><br><span class="line"> <span class="keyword">var</span> g = f.length;</span><br><span class="line"> g > <span class="number">30</span> && (r = f.slice(<span class="number">0</span>, <span class="number">10</span>).join(<span class="string">""</span>) + f.slice(<span class="built_in">Math</span>.floor(g / <span class="number">2</span>) - <span class="number">5</span>, <span class="built_in">Math</span>.floor(g / <span class="number">2</span>) + <span class="number">5</span>).join(<span class="string">""</span>) + f.slice(-<span class="number">10</span>).join(<span class="string">""</span>))</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">var</span> u = <span class="keyword">void</span> <span class="number">0</span></span><br><span class="line"> , l = <span class="string">""</span> + <span class="built_in">String</span>.fromCharCode(<span class="number">103</span>) + <span class="built_in">String</span>.fromCharCode(<span class="number">116</span>) + <span class="built_in">String</span>.fromCharCode(<span class="number">107</span>);</span><br><span class="line"> u = <span class="literal">null</span> !== i ? i : (i = <span class="built_in">window</span>[l] || <span class="string">""</span>) || <span class="string">""</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> d = u.split(<span class="string">"."</span>), m = <span class="built_in">Number</span>(d[<span class="number">0</span>]) || <span class="number">0</span>, s = <span class="built_in">Number</span>(d[<span class="number">1</span>]) || <span class="number">0</span>, S = [], c = <span class="number">0</span>, v = <span class="number">0</span>; v < r.length; v++) {</span><br><span class="line"> <span class="keyword">var</span> A = r.charCodeAt(v);</span><br><span class="line"> <span class="number">128</span> > A ? S[c++] = A : (<span class="number">2048</span> > A ? S[c++] = A >> <span class="number">6</span> | <span class="number">192</span> : (<span class="number">55296</span> === (<span class="number">64512</span> & A) && v + <span class="number">1</span> < r.length && <span class="number">56320</span> === (<span class="number">64512</span> & r.charCodeAt(v + <span class="number">1</span>)) ? (A = <span class="number">65536</span> + ((<span class="number">1023</span> & A) << <span class="number">10</span>) + (<span class="number">1023</span> & r.charCodeAt(++v)),</span><br><span class="line"> S[c++] = A >> <span class="number">18</span> | <span class="number">240</span>,</span><br><span class="line"> S[c++] = A >> <span class="number">12</span> & <span class="number">63</span> | <span class="number">128</span>) : S[c++] = A >> <span class="number">12</span> | <span class="number">224</span>,</span><br><span class="line"> S[c++] = A >> <span class="number">6</span> & <span class="number">63</span> | <span class="number">128</span>),</span><br><span class="line"> S[c++] = <span class="number">63</span> & A | <span class="number">128</span>)</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> p = m, F = <span class="string">""</span> + <span class="built_in">String</span>.fromCharCode(<span class="number">43</span>) + <span class="built_in">String</span>.fromCharCode(<span class="number">45</span>) + <span class="built_in">String</span>.fromCharCode(<span class="number">97</span>) + (<span class="string">""</span> + <span class="built_in">String</span>.fromCharCode(<span class="number">94</span>) + <span class="built_in">String</span>.fromCharCode(<span class="number">43</span>) + <span class="built_in">String</span>.fromCharCode(<span class="number">54</span>)), D = <span class="string">""</span> + <span class="built_in">String</span>.fromCharCode(<span class="number">43</span>) + <span class="built_in">String</span>.fromCharCode(<span class="number">45</span>) + <span class="built_in">String</span>.fromCharCode(<span class="number">51</span>) + (<span class="string">""</span> + <span class="built_in">String</span>.fromCharCode(<span class="number">94</span>) + <span class="built_in">String</span>.fromCharCode(<span class="number">43</span>) + <span class="built_in">String</span>.fromCharCode(<span class="number">98</span>)) + (<span class="string">""</span> + <span class="built_in">String</span>.fromCharCode(<span class="number">43</span>) + <span class="built_in">String</span>.fromCharCode(<span class="number">45</span>) + <span class="built_in">String</span>.fromCharCode(<span class="number">102</span>)), b = <span class="number">0</span>; b < S.length; b++)</span><br><span class="line"> p += S[b],</span><br><span class="line"> p = n(p, F);</span><br><span class="line"> <span class="keyword">return</span> p = n(p, D),</span><br><span class="line"> p ^= s,</span><br><span class="line"> <span class="number">0</span> > p && (p = (<span class="number">2147483647</span> & p) + <span class="number">2147483648</span>),</span><br><span class="line"> p %= <span class="number">1e6</span>,</span><br><span class="line"> p.toString() + <span class="string">"."</span> + (p ^ m)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">n</span>(<span class="params">r, o</span>) </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> t = <span class="number">0</span>; t < o.length - <span class="number">2</span>; t += <span class="number">3</span>) {</span><br><span class="line"> <span class="keyword">var</span> a = o.charAt(t + <span class="number">2</span>);</span><br><span class="line"> a = a >= <span class="string">"a"</span> ? a.charCodeAt(<span class="number">0</span>) - <span class="number">87</span> : <span class="built_in">Number</span>(a),</span><br><span class="line"> a = <span class="string">"+"</span> === o.charAt(t + <span class="number">1</span>) ? r >>> a : r << a,</span><br><span class="line"> r = <span class="string">"+"</span> === o.charAt(t) ? r + a & <span class="number">4294967295</span> : r ^ a</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> r</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h1 id="运行结果"><a href="#运行结果" class="headerlink" title="运行结果"></a>运行结果</h1><p><img src="https://img-blog.csdnimg.cn/20210114122048371.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
]]></content>
<categories>
<category>爬虫学习</category>
</categories>
<tags>
<tag>Python</tag>
<tag>js逆向</tag>
<tag>百度翻译</tag>
</tags>
</entry>
<entry>
<title>链家新房信息获取练习</title>
<url>/posts/b3588f8a/</url>
<content><![CDATA[<font color=#999AAA >
使用python对链家新房相关数据进行爬取,并进行持久化存储。
</font>
<div class="note default"><p>多练习 熟能生巧</p></div>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p><font color=#999AAA >以下是本篇文章正文内容,下面案例可供参考</p>
<h1 id="一、页面分析"><a href="#一、页面分析" class="headerlink" title="一、页面分析"></a>一、页面分析</h1><p>老样子进行页面分析,ul下的li中存放着我们想要的信息,没什么好讲的。<br><img src="https://img-blog.csdnimg.cn/20210117134357570.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
<a id="more"></a>
<p>理清楚思路,对所有一共八十几个页面进行访问,随机伪装机型和ip代理,并找到链接的请求格式。<br><img src="https://img-blog.csdnimg.cn/20210117134539263.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"><br>接下来只需要使用xpath定位到相关的元素信息即可,将解析的数据存入数据库中。<br>进入代码编写阶段。</p>
<h1 id="二、代码编写"><a href="#二、代码编写" class="headerlink" title="二、代码编写"></a>二、代码编写</h1><h2 id="1-数据库表的建立"><a href="#1-数据库表的建立" class="headerlink" title="1.数据库表的建立"></a>1.数据库表的建立</h2><p><font color=#999AAA >代码如下:</p>
<figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> `xinfang` (</span><br><span class="line"> `id` <span class="type">int</span>(<span class="number">255</span>) <span class="keyword">NOT</span> <span class="keyword">NULL</span> AUTO_INCREMENT,</span><br><span class="line"> `name` <span class="type">varchar</span>(<span class="number">255</span>) <span class="keyword">DEFAULT</span> <span class="keyword">NULL</span>,</span><br><span class="line"> `resblock_type` <span class="type">varchar</span>(<span class="number">10</span>) <span class="keyword">DEFAULT</span> <span class="keyword">NULL</span>,</span><br><span class="line"> `sale_status` <span class="type">varchar</span>(<span class="number">10</span>) <span class="keyword">DEFAULT</span> <span class="keyword">NULL</span>,</span><br><span class="line"> `area` <span class="type">varchar</span>(<span class="number">10</span>) <span class="keyword">DEFAULT</span> <span class="keyword">NULL</span>,</span><br><span class="line"> `location` <span class="type">varchar</span>(<span class="number">255</span>) <span class="keyword">DEFAULT</span> <span class="keyword">NULL</span>,</span><br><span class="line"> `resblock_room` <span class="type">varchar</span>(<span class="number">10</span>) <span class="keyword">DEFAULT</span> <span class="keyword">NULL</span>,</span><br><span class="line"> `resblock_area` <span class="type">varchar</span>(<span class="number">30</span>) <span class="keyword">DEFAULT</span> <span class="keyword">NULL</span>,</span><br><span class="line"> `main_price` <span class="type">varchar</span>(<span class="number">150</span>) <span class="keyword">DEFAULT</span> <span class="keyword">NULL</span>,</span><br><span class="line"> `<span class="keyword">second</span>` <span class="type">varchar</span>(<span class="number">30</span>) <span class="keyword">DEFAULT</span> <span class="keyword">NULL</span>,</span><br><span class="line"> `img_url` <span class="type">varchar</span>(<span class="number">255</span>) <span class="keyword">DEFAULT</span> <span class="keyword">NULL</span>,</span><br><span class="line"> <span class="keyword">PRIMARY</span> <span class="keyword">KEY</span> (`id`)</span><br><span class="line">) ENGINE<span class="operator">=</span>InnoDB AUTO_INCREMENT<span class="operator">=</span><span class="number">843</span> <span class="keyword">DEFAULT</span> CHARSET<span class="operator">=</span>utf8;</span><br></pre></td></tr></table></figure>
<h2 id="2-代码编写"><a href="#2-代码编写" class="headerlink" title="2.代码编写"></a>2.代码编写</h2><p><font color=#999AAA >代码如下:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">from</span> lxml <span class="keyword">import</span> etree</span><br><span class="line"><span class="keyword">from</span> fake_useragent <span class="keyword">import</span> UserAgent</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">import</span> pymysql</span><br><span class="line"></span><br><span class="line"><span class="comment"># 代理池</span></span><br><span class="line">proxy_pool = [{<span class="string">'HTTP'</span>: <span class="string">'112.84.53.165:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'171.35.169.58:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'49.86.180.142:9999'</span>},</span><br><span class="line"> {<span class="string">'HTTP'</span>: <span class="string">'113.194.131.190:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'110.243.22.233:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'123.169.163.99:9999'</span>},</span><br><span class="line"> {<span class="string">'HTTP'</span>: <span class="string">'123.163.117.140:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'113.195.20.166:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'114.235.23.237:9000'</span>},</span><br><span class="line"> {<span class="string">'HTTP'</span>: <span class="string">'202.109.157.64:9000'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'171.35.175.31:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'113.195.168.235:9999'</span>},</span><br><span class="line"> {<span class="string">'HTTP'</span>: <span class="string">'125.108.75.135:9000'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'123.101.237.3:9999'</span>}, {<span class="string">'HTTP'</span>: <span class="string">'139.155.41.15:8118'</span>},</span><br><span class="line"> {<span class="string">'HTTP'</span>: <span class="string">'118.212.104.240:9999'</span>}]</span><br><span class="line"><span class="comment"># 伪装头</span></span><br><span class="line">headers = {</span><br><span class="line"> <span class="string">'Referer'</span>: <span class="string">'https://nj.fang.lianjia.com/'</span>,</span><br><span class="line"> <span class="string">'User-Agent'</span>: UserAgent().random</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"> print(<span class="string">'打开数据库...'</span>)</span><br><span class="line"> <span class="comment"># 打开数据库</span></span><br><span class="line"> conn = pymysql.Connect(host=<span class="string">'localhost'</span>, port=<span class="number">3306</span>, user=<span class="string">'root'</span>,</span><br><span class="line"> password=<span class="string">''</span>, db=<span class="string">'spider'</span>, charset=<span class="string">'utf8'</span>)</span><br><span class="line"> <span class="comment"># 链接模板 使用format填充</span></span><br><span class="line"> base_url = <span class="string">'https://nj.fang.lianjia.com/loupan/pg{}/'</span></span><br><span class="line"> <span class="comment"># 存放url的数组</span></span><br><span class="line"> data = []</span><br><span class="line"> print(<span class="string">'初始化数据...'</span>)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">86</span>):</span><br><span class="line"> <span class="comment"># 循环写入url</span></span><br><span class="line"> data.append(base_url.<span class="built_in">format</span>(i))</span><br><span class="line"> print(<span class="string">'开始爬取...'</span>)</span><br><span class="line"> <span class="comment"># 遍历url 请求网址 并解析</span></span><br><span class="line"> <span class="keyword">for</span> url <span class="keyword">in</span> data:</span><br><span class="line"> <span class="comment"># get请求访问 使用代理</span></span><br><span class="line"> response = requests.get(url=url, headers=headers, proxies=random.choice(proxy_pool))</span><br><span class="line"> <span class="comment"># etree解析</span></span><br><span class="line"> res_data = etree.HTML(response.content.decode())</span><br><span class="line"> <span class="comment"># xpath定位到所有的li</span></span><br><span class="line"> lis = res_data.xpath(<span class="string">'//li[@class="resblock-list post_ulog_exposure_scroll has-results"]'</span>)</span><br><span class="line"> <span class="comment"># 在循环的li下进行解析</span></span><br><span class="line"> <span class="keyword">for</span> li <span class="keyword">in</span> lis:</span><br><span class="line"> <span class="comment"># 图片地址</span></span><br><span class="line"> img_url = li.xpath(<span class="string">'./a/img/@data-original'</span>)[<span class="number">0</span>].split(<span class="string">'.592x432.jpg'</span>)[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># 小区名字</span></span><br><span class="line"> name = li.xpath(<span class="string">'./div[@class="resblock-desc-wrapper"]/div[@class="resblock-name"]/a[1]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> <span class="comment"># 以下都是相关信息 就不做赘叙</span></span><br><span class="line"> resblock_type = li.xpath(<span class="string">'./div[@class="resblock-desc-wrapper"]/div[@class="resblock-name"]/span[1]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> sale_status = li.xpath(<span class="string">'./div[@class="resblock-desc-wrapper"]/div[@class="resblock-name"]/span[2]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> area = li.xpath(<span class="string">'./div[@class="resblock-desc-wrapper"]/div[@class="resblock-location"]/span[1]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> location = li.xpath(<span class="string">'./div[@class="resblock-desc-wrapper"]/div[@class="resblock-location"]/span[1]/text()'</span>)[<span class="number">0</span>] + <span class="string">'/'</span> + \</span><br><span class="line"> li.xpath(<span class="string">'./div[@class="resblock-desc-wrapper"]/div[@class="resblock-location"]/span[2]/text()'</span>)[<span class="number">0</span>] + <span class="string">'/'</span> + \</span><br><span class="line"> li.xpath(<span class="string">'./div[@class="resblock-desc-wrapper"]/div[@class="resblock-location"]/a[1]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> resblock_room = li.xpath(<span class="string">'./div[@class="resblock-desc-wrapper"]/a[@class="resblock-room"]/span[1]/text()'</span>)</span><br><span class="line"> <span class="comment"># 有些数据为空 要进行替换 否则数据库写入报错</span></span><br><span class="line"> <span class="keyword">if</span> resblock_room:</span><br><span class="line"> resblock_room = resblock_room[<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> resblock_room = <span class="string">'暂无信息'</span></span><br><span class="line"> resblock_area = li.xpath(<span class="string">'./div[@class="resblock-desc-wrapper"]/div[@class="resblock-area"]/span[1]/text()'</span>)</span><br><span class="line"> <span class="keyword">if</span> resblock_area:</span><br><span class="line"> resblock_area = resblock_area[<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> resblock_area = <span class="string">'暂无信息'</span></span><br><span class="line"> main_price = li.xpath(<span class="string">'./div[@class="resblock-desc-wrapper"]/div[@class="resblock-price"]/div[@class="main-price"]/span[@class="number"]/text()'</span>)[<span class="number">0</span>]</span><br><span class="line"> second = li.xpath(<span class="string">'./div[@class="resblock-desc-wrapper"]/div[@class="resblock-price"]/div[@class="second"]/text()'</span>)</span><br><span class="line"> <span class="keyword">if</span> second:</span><br><span class="line"> second = second[<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> second = <span class="string">'暂无信息'</span></span><br><span class="line"> <span class="comment"># sql语句</span></span><br><span class="line"> sql = <span class="string">'insert into xinfang(name, resblock_type, sale_status, area, location, resblock_room, resblock_area, main_price, second, img_url) values ("{}", "{}", "{}", "{}", "{}", "{}", "{}", "{}", "{}", "{}")'</span>.<span class="built_in">format</span>(</span><br><span class="line"> name, resblock_type, sale_status, area, location, resblock_room, resblock_area, main_price, second,</span><br><span class="line"> img_url)</span><br><span class="line"> cursor = conn.cursor()</span><br><span class="line"> <span class="comment"># 事务 提交 回滚</span></span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> cursor.execute(sql)</span><br><span class="line"> conn.commit()</span><br><span class="line"> <span class="keyword">except</span> Exception <span class="keyword">as</span> e:</span><br><span class="line"> print(e)</span><br><span class="line"> conn.rollback()</span><br><span class="line"> print(<span class="string">'爬取结束关闭数据库...'</span>)</span><br><span class="line"> <span class="comment"># 关闭数据库链接 程序结束</span></span><br><span class="line"> conn.close()</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">
<h1 id="结果"><a href="#结果" class="headerlink" title="结果"></a>结果</h1><p><font color=#999AAA >程序运行结果如下:<br><img src="https://img-blog.csdnimg.cn/202101171354012.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hhbmRzb21lRmlzaG1hbg==,size_16,color_FFFFFF,t_70"></p>
]]></content>
<categories>
<category>爬虫学习</category>
</categories>
<tags>
<tag>Python</tag>
<tag>链家</tag>
</tags>
</entry>
<entry>
<title>设计模式</title>
<url>/posts/364ea8cc/</url>
<content><![CDATA[<h1 id="期末复习"><a href="#期末复习" class="headerlink" title="期末复习"></a>期末复习</h1><h2 id="理论"><a href="#理论" class="headerlink" title="理论"></a>理论</h2><ul>
<li><strong>模式</strong>是在特定环境下人们解决某类重复出现问题的一套成功或有效的解决方案</li>
<li><strong>设计模式</strong>是在特定环境下为解决某一通用软件设计问题提供的一套定制的解决方案,描述了对象和类之间的相互作用。</li>
<li><strong>设计模式的优点</strong>:融合了专家的经验,方便人们使用,设计更加灵活,提高软件质量,有助于理解面向对象思想。</li>
</ul>
<p>七个常用的面向对象的设计原则:</p>
<ol>
<li>单一职责原则(SRP):一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中</li>
<li>开闭原则(OCP):软件应该对修改关闭,对扩展开放</li>
<li>里氏代换原则(LSP):所有引用基类的地方必须能够透明的使用其子类的对象</li>
<li>依赖倒转原则(DIP):高层模块应该依赖抽象,细节依赖于抽象</li>
<li>接口隔离原则(ISP):不依赖不需要的接口</li>
<li>合成复用原则(CRP):优先使用对象组合而不是继承</li>
<li>迪米特法则(LoD):每个软件单位对其他的单位都只有最少的知识,且局限于密切相关的软件单位</li>
</ol>
<a id="more"></a>
<p>设计模式优缺点:</p>
<table>
<thead>
<tr>
<th align="center">模式</th>
<th align="center">优点</th>
<th align="center">缺点</th>
</tr>
</thead>
<tbody><tr>
<td align="center">简单工厂</td>
<td align="center">创建使用相分离;无需知道类名;用配置文件 灵活</td>
<td align="center">工厂类职责过重;工厂类个数多,复杂 难以理解;系统扩展困难</td>
</tr>
<tr>
<td align="center">工厂方法</td>
<td align="center">完全符合开闭原则;不用关心创建细节;多态性设计</td>
<td align="center">添加新产品需要成对增加;复杂,难以理解</td>
</tr>
<tr>
<td align="center">建造者</td>
<td align="center">创建过程解耦;建造者相对独立;精细控制创建过程</td>
<td align="center">产品差异大不适合使用;复杂 难以理解</td>
</tr>
<tr>
<td align="center">原型</td>
<td align="center">提高创建效率;扩展性好;可以保存对象状态</td>
<td align="center">对类改造时违反开闭原则;深克隆较为复杂</td>
</tr>
<tr>
<td align="center">单例</td>
<td align="center">严格控制访问;提高性能</td>
<td align="center">扩展难;职责过重;长时间不使用会被回收</td>
</tr>
<tr>
<td align="center">适配器</td>
<td align="center">解耦;增加复用;灵活可扩展</td>
<td align="center">适配者不能为终类;只能继承一个类</td>
</tr>
<tr>