-
Notifications
You must be signed in to change notification settings - Fork 6
/
search.xml
375 lines (375 loc) · 153 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
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[站点 bug 维修记录]]></title>
<url>%2F2023%2F06%2F28%2F%E7%AB%99%E7%82%B9-bug-%E7%BB%B4%E4%BF%AE%E8%AE%B0%E5%BD%95%2F</url>
<content type="text"><![CDATA[两年多没有更新网站了,这两年,我完成了从一名大厂工程师到连续创业者的转变。 网站由于年久失修,存在了许多 bug,比如部分友链 404,阅读量统计失效等等,由于代码丢失,拖了两年才在旧电脑上找到这份代码,将所有 bug 修好后,发布此篇,以作记录。 RSA host key for github.com has changed. Could not read from remote repository123456789101112RSA host key for github.com has changed and you have requested strict checking.Host key verification failed.fatal: Could not read from remote repository.Please make sure you have the correct access rightsand the repository exists. at ChildProcess.<anonymous> (D:\hexoblog\node_modules\hexo-util\lib\spawn.js:37:17) at ChildProcess.emit (events.js:182:13) at ChildProcess.cp.emit (D:\hexoblog\node_modules\cross-spawn\lib\enoent.js:40:29) at maybeClose (internal/child_process.js:961:16) at Process.ChildProcess._handle.onexit (internal/child_process.js:248:5) 1、如果git config -l 没有输出,在 git 设置一下身份的名字和邮箱, 123git config --global user.name "yourname"git config --global user.email "[email protected]" yourname 必须与 github 的用户名一致 这里 [email protected] 必须与 github 登录邮箱一致 2、删除.ssh文件夹下的 known_hosts 文件(该文件主要作用是域名解析) 3、ssh-keygen -t rsa -C “[email protected]"(填写github对应的邮箱) 一路回车即可,yes,无需输入 4、在 github 设置界面新增SSH key 将 id_rsa.pub 里面的内容添加到如图中的 Key 上,Title 可随意。 Host key verification failed. Could not read from remote repository 12345678910111213141516171819Host key verification failed.fatal: Could not read from remote repository.Please make sure you have the correct access rightsand the repository exists.FATAL Something's wrong. Maybe you can find the solution here: http://hexo.io/docs/troubleshooting.htmlError: Host key verification failed.fatal: Could not read from remote repository.Please make sure you have the correct access rightsand the repository exists. at ChildProcess.<anonymous> (D:\hexoblog\node_modules\hexo-util\lib\spawn.js:37:17) at ChildProcess.emit (events.js:182:13) at ChildProcess.cp.emit (D:\hexoblog\node_modules\cross-spawn\lib\enoent.js:40:29) at maybeClose (internal/child_process.js:961:16) at Socket.stream.socket.on (internal/child_process.js:380:11) at Socket.emit (events.js:182:13) at Pipe._handle.close [as _onclose] (net.js:596:12) 这是错误是因为本地的博客版本与远程的版本不一致,解决方法是删除博客目录下的.deploy_git文件夹,然后克隆远程的仓库到博客目录里面,然后改名字为.deploy_git。 will not add file alias1234567fatal: will not add file alias 'categories/Python/index.html' ('categories/python/index.html' already exists in index) at ChildProcess.<anonymous> (D:\hexoblog\node_modules\hexo-util\lib\spawn.js:37:17) at ChildProcess.emit (events.js:182:13) at ChildProcess.cp.emit (D:\hexoblog\node_modules\cross-spawn\lib\enoent.js:40:29) at maybeClose (internal/child_process.js:961:16) at Process.ChildProcess._handle.onexit (internal/child_process.js:248:5) 解决办法,把 ./deploy_git/.git/config 里面的 ignorecase 值改成 false 评论丢失评论是保存在 LeanCloud 的,由于 LeanCloud 服务升级,代码丢失无法按期修改 appid 和 appkey,之前的评论数据全部丢失了,现在的评论是重开的。 兄弟站点已于 2022 年初新开兄弟站点 https://buyixiao.github.io/,更多有趣好玩实用的 tools,欢迎来玩]]></content>
<categories>
<category>hexo</category>
</categories>
<tags>
<tag>hexo</tag>
<tag>next</tag>
</tags>
</entry>
<entry>
<title><![CDATA[原创爬虫大全]]></title>
<url>%2F2020%2F12%2F03%2F%E5%8E%9F%E5%88%9B%E7%88%AC%E8%99%AB%E5%A4%A7%E5%85%A8%2F</url>
<content type="text"><![CDATA[好久没有更新网站了,应该快一年了 orz,这一年,我完成了从一名学生到大厂工程师的转变。 在这期间,陆陆续续的完成了一些爬虫项目,介绍如下,代码获取方式见文末。 微博爬虫一个完整爬取 搜索关键词的微博、用户微博以及评论的爬虫,已经开源在 github 上,地址如下: https://github.com/Python3Spiders/WeiboSuperSpider 微信公众号爬虫1、可以爬取 指定公众号所有文章的标题、内容、点赞数、好看数 2、可以爬取 指定公众号所有视频并下载到本地 知乎爬虫1、可以爬取 指定用户或者机构的所有想法、文章、回答、视频的标题点赞数和评论数 2、可以爬取 指定问题下的所有回答,爬取指定回答下的所有评论 链家爬虫可以爬取 指定城市的所有租房、成交房以及二手房数据,包含多达十个字段,没有任何敏感信息,仅做数据分析用 facebook 爬虫可以 爬取指定用户的帖子 instagram 爬虫1、可以爬取 指定用户的粉丝信息,关注信息 2、可以 下载指定用户的所有图片 youtube 爬虫可以爬取 指定视频的所有评论 bilibili 爬虫1、可以下载指定视频 2、可以爬取指定视频的所有评论和弹幕 如何获取源码 除了第一个微博爬虫,其余都没有开源,如有需要可通过关注公众号【月小水长】后台联系我。 #微信公众号爬虫、#知乎爬虫、#链家爬虫、#facebook 爬虫、#微博爬虫]]></content>
<categories>
<category>爬虫</category>
</categories>
<tags>
<tag>爬虫</tag>
<tag>新浪微博</tag>
<tag>微信公众号文章/视频</tag>
<tag>链家</tag>
<tag>知乎</tag>
</tags>
</entry>
<entry>
<title><![CDATA[刘媛媛:年轻人能为世界做什么]]></title>
<url>%2F2019%2F04%2F26%2F%E5%88%98%E5%AA%9B%E5%AA%9B%EF%BC%9A%E5%B9%B4%E8%BD%BB%E4%BA%BA%E8%83%BD%E4%B8%BA%E4%B8%96%E7%95%8C%E5%81%9A%E4%BB%80%E4%B9%88%2F</url>
<content type="text"><![CDATA[我是一名法学院的学生,我的每一门课的教授都曾经在他的课堂上讲过这么一句话,他们常常“说法律是这么规定的,但是现实生活中„„”现实生活是一种很神奇的生活,在现实生活中那些尊重规则的老实人往往一辈子都默默无闻,反倒是那些弄虚作假的人到最后会名利双收,于是乎像我这样的年轻人就经常有那些看着很有经验的前辈过来拍拍你的肩膀跟你说“年轻人你还不懂。”我想问的是我们年轻人你能为这个世界做什么,总有一天银行行长会是九零后,企业家会是九零后,甚至国家主席都会是九零后,当全社会都被九零后占领的时候,我想问你们九零后们,大家想把这个社会变成什么样。 我知道不是每一个人他都能够成为那种站在风口浪尖上去把握国家命运的人物,你我都是再普通不过的升斗小民,是这个庞大的社会机器上一颗小小的螺丝钉,读书的时候每天都被父母耳提面命说你干啥你都不要给我耽误学习;毕业的时候到处投简历,凄凄惶惶的等一家企业收留自己;逢年过节被逼婚,结婚买了房子要花自己年轻的时候的最好的二十年来偿还贷款,让每一个年轻人都忙着生存,而没有梦想,没有时间关心政治,没有时间关心环境,没有时间关心国家的命运,还哪有什么精力去为这社会做什么,但是后来我发现还是有一件事情你跟我都可以做到,这件事情就是我们这一代人在我们老去的路上,一定一定不要变坏,不要变成你年轻的时候最痛恨、最厌恶的那种成年人。如果将来你去路边摆摊,你就不要卖地沟油小吃,你不要缺斤短两;你将来开了工厂当了老板,你不要偷工减料,生产一些次品。每一个普通人他在自己普通的岗位上做一个好人是有非常非常严重的意义的,因为我们每一个人生下来都注定会改变世界。 我是一个学法律的,如果我将来是一个公正严明的法官,那么这个社会就因为多了一个好法官而变好了一点点,我希望大家都记住即使给了你十万个理由让你去作恶,你都要保持自己的操守跟底线,仅仅就因为一个理由,这个理由就是你不是一个禽兽,你是一个人。我更希望我们所有的九零后们,你们都能成为那种难能可贵的年轻人,一辈子都嫉恶如仇,绝不随波逐流,你绝不摧眉折腰,你绝不摧眉折腰,你绝不放弃自己的原则,你绝不绝不绝不失望于人性。所以我亲爱的九零后们,如果将来再是有那些人跟你说“年轻人你不要看不惯,你要适应这个社会。”这时候你就应该像一个真正的勇士一样直面他,你告诉他“我跟你不一样,我不是来适应社会的,我是来改变社会的。”]]></content>
<categories>
<category>励志</category>
</categories>
<tags>
<tag>励志</tag>
<tag>演讲</tag>
</tags>
</entry>
<entry>
<title><![CDATA[刘媛媛:寒门贵子]]></title>
<url>%2F2019%2F04%2F26%2F%E5%88%98%E5%AA%9B%E5%AA%9B%EF%BC%9A%E5%AF%92%E9%97%A8%E8%B4%B5%E5%AD%90%2F</url>
<content type="text"><![CDATA[在这个演讲开始之前,我先问问现场的大家一个问题,你们当中有谁觉得自己是家境普通,甚至出身贫寒,将来想要出人头地只能靠自己?你们当中又有谁觉得自己是有钱人家的小孩儿,起码在奋斗的时候可以从父母那里得到一点助力? 前些日子,有一个在银行工作了十年的HR(人力资源管理师),他在网络上发了一篇帖子,叫做《寒门再难出贵子》。意思是说在当下,我们这个社会里面,寒门的小孩儿他想要出人头地,想要成功,比我们父辈的那一代更难了。这个帖子引起了特别广泛的讨论,你们觉得这句话有道理吗? 先拿我自己说,我们家就是出身寒门的,我们家都不算寒门,我们家有没有门。我现在想想我都不知道,当初我爸跟我妈那么普通的农村夫妇,他是怎么样把三个孩子,我跟我两个哥,从农村供出来上大学,上研究生。我一直都觉得自己特别幸运,我爸跟我妈都没怎么读过书,我妈连小学一年级都没上过,她居然觉得读书很重要,她吃再多的苦,也要让我们三个孩子上大学。 我一直也不会拿自己跟那些,比如家庭富裕的小孩儿去做计较,我说们之间会有什么不同,或者有什么不平等,但是我们必须要承认这个世界是有一些不平等的,他们有很多优越的条件,我们都没有,他们有很多的捷径我们也没有,可是我们不能抱怨,每一个人的人生都是不尽相同的,有些人出生就含着金钥匙,有些人出生连爸妈都没有。 人生和人生是没有可比性的,我们的人生是怎么样,完全取决于自己的感受,你一辈子都在感受抱怨,那你的一生就是抱怨的一生,你一辈子都在感受感动,那你的一生就是感动的一生,你一辈子都立志于改变这个社会,那你的一生就是一个斗士的一生。 英国有一部纪录片,叫做《人生七年》,片中访问了十二个来自不同阶层的七岁小孩儿,每七年再去重新访问这些小孩儿到了影片的最后就发现,富人的孩子还是富人,穷人的孩子还是穷人,但是里面有一个叫尼克的贫穷的小孩儿,他到最后通过自己的奋斗变成了一名大学教授,可见命运的手掌里面是有漏网之鱼的。而且,现实生活中寒门子弟逆袭的例子更是数不胜数。 所以当我们遭受失败的时候,我们不能把所有的原因都归结到出生上去,更不能抱怨自己的父母为什么不如别人的父母,因为家境不好,并没有斩断一个人他成功的所有的可能。 当我在人生终于到很大的困难的时候,我就会在北京的大街上走一走,看着人来人往,而那时候我就想,刘媛媛,你在这个城市里面真的是一无所依,你有的只是你自己你什么都没有,你现在能做的就是单枪匹马的,在这个社会上杀出一条路来。(掌声!) 这段演讲到现在已经是最后一次了,其实在刚刚我问的时候就发现了,我们大部分人都不是出生豪门的,我们都要靠自己,所以你要相信,命运给你一个比别人低的起点,是想告诉你,让你用你的一生去奋斗出一个绝地反击的故事。 这个故事关于独立,关于梦想,关于勇气,关于坚忍,它不是一个水到渠成的童话,没有一点人间疾苦,这个事故是有志者事竟成,破釜沉舟,百二秦关终属楚;这个故事是苦心人天不负,卧薪尝胆,三千越甲可吞吴。]]></content>
<categories>
<category>励志</category>
</categories>
<tags>
<tag>励志</tag>
<tag>演讲</tag>
</tags>
</entry>
<entry>
<title><![CDATA[小程序 wx.authorize 之 scope.userLocation 授权错误]]></title>
<url>%2F2019%2F04%2F14%2F%E5%B0%8F%E7%A8%8B%E5%BA%8F-wx-authorize-%E4%B9%8B-scope-userLocation-%E6%8E%88%E6%9D%83%E9%94%99%E8%AF%AF%2F</url>
<content type="text"><![CDATA[今天做的一个小程序项目中需要用到scope.userLocation获取用户地理位置这个权限,这个权限对应两个接口wx.getLocation(Object object) 和wx.chooseLocation(Object object),这两个接口都能够获取到用户当前位置的经纬度,但是除此之外,wx.getLocation(Object object)还能获都速度、高度、经纬度的精确度等更多专业的地理信息;wx.chooseLocation(Object object)则更加通俗化一些,通过这个接口,我们可以获得具体的地理名称,比如某某街道xx号这样的,看到网上有很多关于获取地理名称的教程是先通过wx.getLocation(Object object)获取经纬度,再由第三方 API 解析成地理名称,这样未免太麻烦了,可能是不知道wx.chooseLocation(Object object)的存在。 我的思路是直接调用wx.chooseLocation(Object object),如果成功,则在它的回调函数success中直接获取地理名称,如果失败,则是由于还没有授权造成的,我们就在回调函数fail中获得授权然后再调用wx.chooseLocation(Object object)即可,一旦同意授权,除非你删除这个小程序,否则授权的有效性是一直存在的,下次直接调用wx.chooseLocation(Object object)就能成功回调。这部分代码如下: wx.chooseLocation({ success: function(res) { console.log('succes1') console.log(res) that.setData({ addr: res.address //调用成功直接设置地址 }) }, fail: function() { wx.getSetting({ success(res) { if (!res.authSetting['scope.userLocation']) { console.log("f1") wx.authorize({ scope: 'scope.userLocation', success() { wx.chooseLocation({ success: function(res) { that.setData({ addr: res.address //调用成功直接设置地址 }) }, }) console.log('success2') }, fail(){ console.log("f2") } }) } } }) } }) 但是,问题来了,这部分代码在电脑开发工具上一直可以按照预期结果运行,可是一旦放到手机上,就千奇百怪,大概一百次只有一次是按照预期结果运行的,其他的全部没有成功调出地图获取用户当前位置(我也好奇为什么会有一次成功???)。我查阅了官方文档,才发现,原来scope.userLocation这个权限比较特别,必须要在app.json文件中声明这个权限是用来干吗的。如下: "permission": { "scope.userLocation": { "desc": "需要记录打卡时的位置信息" } }, 注意看下图中的描述就是代码中的 desc:description 加了之后,症状就解除了。 欢迎留言,欢迎关注微信公众号: 月小水长]]></content>
<categories>
<category>小程序</category>
</categories>
<tags>
<tag>小程序</tag>
<tag>authorize</tag>
<tag>userLocation</tag>
</tags>
</entry>
<entry>
<title><![CDATA[wxPython 开发实战之输入控件 TextCtrl 使用验证器 Validator 来约束输入]]></title>
<url>%2F2019%2F04%2F12%2FwxPython-%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%98%E4%B9%8B%E8%BE%93%E5%85%A5%E6%8E%A7%E4%BB%B6-TextCtrl-%E4%BD%BF%E7%94%A8%E9%AA%8C%E8%AF%81%E5%99%A8-Validator-%E6%9D%A5%E7%BA%A6%E6%9D%9F%E8%BE%93%E5%85%A5%2F</url>
<content type="text"><![CDATA[前言TextCtrl 是 wxPython 框架里一个非常实用的文本输入控件,我们经常需要对 TextCtrl 做这样一个输入上的约束:只允许输入数字 (比如允许 1.2、4.5、100 这些输入而禁止诸如 .8、4t等输入,方便我们在将输入的 str 类型转成 int、float 等其他类型时不需要额外加判断来防止产生异常。今天我查阅 wxPython 的 API,发现了 Validator 这个类可以满足我们的需求。事实上,不仅是满足只允许输入数字这个需要,掌握了 Validator 这个类的使用,我们可以满足任何定制化的需求。 编码首先必须新建类继承自 wx.Validatorimport wx class MyNumberValidator(wx.Validator):# 创建验证器子类 def __init__(self): wx.Validator.__init__(self) def Clone(self): return MyNumberValidator() def Validate(self,win):#1 使用验证器方法 return True def TransferToWindow(self): return True def TransferFromWindow(self): return True 同时,必须重写 init()(完成初始化)、Clone()(返回当前类的一个实例)等五个方法,你只要把它们当成一个模板就行,然后在此基础上加上我们自己的逻辑。 根据需求加入实现逻辑import wx # import wx.lib.imagebrowser class MyNumberValidator(wx.Validator):# 创建验证器子类 def __init__(self): wx.Validator.__init__(self) self.ValidInput = ['.','0','1','2','3','4','5','6','7','8','9'] self.StringLength = 0 self.Bind(wx.EVT_CHAR,self.OnCharChanged) # 绑定字符改变事件 def OnCharChanged(self,event): # 得到输入字符的 ASCII 码 keycode = event.GetKeyCode() # 退格(ASCII 码 为8),删除一个字符。 if keycode == 8: self.StringLength -= 1 #事件继续传递 event.Skip() return # 把 ASII 码 转成字符 InputChar = chr(keycode) if InputChar in self.ValidInput: # 第一个字符为 .,非法,拦截该事件,不会成功输入 if InputChar == '.' and self.StringLength == 0: return False # 在允许输入的范围,继续传递该事件。 else: event.Skip() self.StringLength += 1 return True return False def Clone(self): return MyNumberValidator() def Validate(self,win):#1 使用验证器方法 return True def TransferToWindow(self): return True def TransferFromWindow(self): return True 注意这行代码,self.Bind(wx.EVT_CHAR,self.OnCharChanged) # 绑定字符输入事件,它的意思是,一旦用户输入了字符,该事件会首先交给OnCharChanged方法处理,在OnCharChanged中,特别注意event.Skip()这行代码,它的意思是,过了合法性检验这一关,该事件可以继续传递了,可以交给将该字符加入 textctrl.value 并显示出来的函数处理;否则,事件就在OnCharChanged中被拦截了,不会显示出来,输入失败。 给控件 textctrl 绑定验证器子类。很简单,只需要在创建 textctrl 的时候加指定关键词参数 wx.TextCtrl(self,validator=MyNumberValidator(),style=wx.TE_CENTER) style=wx.TE_CENTER 使输入字符居中 再说 Validate() 方法我们发现,Validator 类中和类名最相似的方法Validate()一直没有使用,其实这个方法是一般使用流程如下,先在 Validate() 方法中加上业务逻辑。 def Validate(self,win):#1 使用验证器方法 print(111) textCtrl = self.GetWindow() text = textCtrl.GetValue() valid_text = '' for i in text: if i in self.ValidInput: valid_text += i textCtrl.SetValue(valid_text) return True 然后在外部调用它验证合法性 self.n1.GetValidator().Validate(self.n1) Validate()也可以验证合法性,只不过它不能处理输入事件,必须在输入完成后才能验证合法性,相当于“马后炮”的作用。 一个完整的例子 # -*- coding: utf-8 -*- # author: inspurer(月小水长) # pc_type lenovo # create_time: 2019/4/12 13:37 # file_name: validator.py # github https://github.com/inspurer # qq邮箱 [email protected] # 微信公众号 月小水长(ID: inspurer) import wx # import wx.lib.imagebrowser class MyNumberValidator(wx.Validator):# 创建验证器子类 def __init__(self): wx.Validator.__init__(self) self.ValidInput = ['.','0','1','2','3','4','5','6','7','8','9'] self.StringLength = 0 self.Bind(wx.EVT_CHAR,self.OnCharChanged) # 绑定字符输入事件 def OnCharChanged(self, event): # 得到输入字符的 ASCII 码 keycode = event.GetKeyCode() # 退格(ASCII 码 为8),删除一个字符。 if keycode == 8: self.StringLength -= 1 # 事件继续传递 event.Skip() return # 把 ASII 码 转成字符 InputChar = chr(keycode) if InputChar in self.ValidInput: # 第一个字符为 .,非法,拦截该事件,不会成功输入 if InputChar == '.' and self.StringLength == 0: return False # 在允许输入的范围,继续传递该事件。 else: event.Skip() self.StringLength += 1 return True return False def Clone(self): return MyNumberValidator() def Validate(self,win):#1 使用验证器方法 print(111) textCtrl = self.GetWindow() text = textCtrl.GetValue() valid_text = '' for i in text: if i in self.ValidInput: valid_text += i textCtrl.SetValue(valid_text) return True def TransferToWindow(self): return True def TransferFromWindow(self): return True class GUI(wx.Frame): def __init__(self,parent): wx.Frame.__init__(self, parent=parent, title="wxPython开发实战",size=(400,300),style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX ) self.Center() self.SetBackgroundColour('white') font = wx.Font(16,wx.DECORATIVE, wx.NORMAL, wx.NORMAL) self.n1 = wx.TextCtrl(self,validator=MyNumberValidator(),pos=(100,30),size=(180,45),style=wx.TE_CENTER) self.n1.SetFont(font) self.n1.SetBackgroundColour('#95ec69') self.n1.SetHint('请输入第一个数字') self.n2 = wx.TextCtrl(self,validator=MyNumberValidator(),pos=(100,100),size=(180,45),style=wx.TE_CENTER) self.n2.SetFont(font) self.n2.SetBackgroundColour('#95ec69') self.n2.SetHint('请输入第二个数字') self.config = wx.Button(self,label="验证输入框一的合法性",pos=(115,170),size=(150,40)) self.config.SetBackgroundColour('#95ec69') self.Bind(wx.EVT_BUTTON,self.configClicked,self.config) def configClicked(self,event): self.n1.GetValidator().Validate(self.n1) pass if __name__ == "__main__": app = wx.App() GUI(None).Show() app.MainLoop()]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>Python</tag>
<tag>wxPython</tag>
<tag>TextCtrl</tag>
<tag>Validator</tag>
</tags>
</entry>
<entry>
<title><![CDATA[丘吉尔二战演讲]]></title>
<url>%2F2019%2F04%2F10%2F%E4%B8%98%E5%90%89%E5%B0%94%E4%BA%8C%E6%88%98%E6%BC%94%E8%AE%B2%2F</url>
<content type="text"><![CDATA[I have nothing to offer but blood, toil, tears and sweat. We have before us an ordeal of the most grievous kind. We have before us many, many months of struggle and suffering.我所能奉献的唯有热血、辛劳、眼泪和汗水我们所面临的将是一场极其严酷的考验,将是旷日持久的斗争和苦难。 You ask, what is our policy? I say it is to wage war by land, sea and air. War with all our might and with all the strength God has given us, and to wage war against a monstrous tyranny never surpassed in the dark and lamentable catalogue of human crime. That is our policy. 若问我们的政策是什么?我的回答是:在陆上、海上、空中作战。尽我们的全力,尽上帝赋予我们的全部力量去作战,对人类黑暗、可悲的罪恶史上空前凶残的暴政作战。这就是我们的政策。 You ask, what is our aim? I can answer in one word, It is victory. Victory at all costs-victory in spite of all terrors-victory, however long and hard the road may be, for without victory there is no survival. 若问我们的目标是什么?我可以用一个词来回答,那就是胜利。不惜一切代价,去夺取胜利–不惧一切恐怖,去夺取胜利–不论前路如何漫长、如何艰苦,去夺取胜利。因为没有胜利就不能生存。 Let that be realized. No survival for the British Empire, no survival for all that the British Empire has stood for, no survival for the urge, the impulse of the ages, that mankind shall move forward toward his goal. 我们务必认识到,没有胜利就不复有大英帝国,没有胜利就不复有大英帝国所象征的一切,没有胜利就不复有多少世纪以来的强烈要求和冲动:人类应当向自己的目标迈进。 I take up my task in buoyancy and hope. I feel sure that our cause will not be suffered to fail among men. 我精神振奋、满怀信心地承担起我的任务。我确信,大家联合起来,我们的事业就不会遭到挫败。 I feel entitled at this juncture, at this time, to claim the aid of all and to say, “Come then, let us go forward together with our united strength.” 在此时此刻的危急关头,我觉得我有权要求各方面的支持。我要说:”来吧,让我们群策群力,并肩前进!”]]></content>
<categories>
<category>励志</category>
</categories>
<tags>
<tag>励志</tag>
<tag>名人演讲</tag>
</tags>
</entry>
<entry>
<title><![CDATA[2012奥巴马连任成功竞选演讲]]></title>
<url>%2F2019%2F04%2F10%2F2012%E5%A5%A5%E5%B7%B4%E9%A9%AC%E8%BF%9E%E4%BB%BB%E6%88%90%E5%8A%9F%E7%AB%9E%E9%80%89%E6%BC%94%E8%AE%B2%2F</url>
<content type="text"><![CDATA[2012年奥巴马胜选演讲全文(中英文对照) Thank you. Thank you. Thank you so much. (Sustained cheers, applause.) Tonight, more than 200 years after a former colony won the right to determine its own destiny, the task of perfecting our union moves forward. (Cheers, applause.) 谢谢,谢谢,非常感谢。 两百多年前,人民在这块曾经的殖民地上赢得了自己的命运;今夜,我们向实现完美联邦的目标又迈近了一步。 It moves forward because of you. It moves forward because you reaffirmed the spirit that has triumphed over war and depression, the spirit that has lifted this country from the depths of despair to the great heights of hope, the belief that while each of us will pursue our own individual dreams, we are an American family, and we rise or fall together as one nation and as one people. (Cheers, applause.) 这一步,是因为你们;这一步,是因为你们证明了克服战争和萧条的那种精神仍在,那份把我们国家从绝望的深渊带向希望之巅的精神。我们每个人都可以追逐自己的梦想。 美国同胞血浓于水,作为一个国家和民族,我们共起落、同荣辱。 Tonight, in this election, you, the American people, reminded us that while our road has been hard, while our journey has been long, we have picked ourselves up, we have fought our way back, and we know in our hearts that for the United States of America, the best is yet to come. 今晚,在这次选举中,你们,美国人民们,提醒了我们:尽管路程艰辛,历程漫长,我们仍能振作精神,奋起反击。我们心中坚信,美利坚的每天更加美好。 (Cheers, applause.) I want to thank every American who participated in this election. (Cheers, applause.) Whether you voted for the very first time — (cheers) — or waited in line for a very long time — (cheers) — by the way, we have to fix that. (Cheers, applause.) Whether you pounded the pavement or picked up the phone — (cheers, applause) — whether you held an Obama sign or a Romney sign, you made your voice heard and you made a difference. (Cheers, applause.) 我想感谢每一位亲身参与大选的美国人。无论这是你的第一次投票,又或是在队伍中等待了很久。顺便说一句,排队这个问题真是亟待解决。无论你是步行前往,还是拿起电话;无论你举的牌子上,写的是奥巴马还是罗姆尼… 你的声音都会被听到,你也一样带来了改变。 I just spoke with Governor Romney and I congratulated him and Paul Ryan on a hard-fought campaign. (Cheers, applause.) We may have battled fiercely, but it’s only because we love this country deeply and we care so strongly about its future. From George to Lenore to their son Mitt, the Romney family has chosen to give back to America through public service. And that is a legacy that we honor and applaud tonight. (Cheers, applause.) In the weeks ahead, I also look forward to sitting down with Governor Romney to talk about where we can work together to move this country forward. 我刚刚和罗姆尼州长通了话,向他和保罗·瑞安,就这场艰难的战役,表示了我的祝贺。双方的选战之所以惨烈,正是因为我们都如此深爱这个国家,如此关心它的未来。从乔治到兰 诺夫妇,再到他们的儿子米特,罗姆尼一家选择通过献身公务来报效国家。今晚,我们向这一份宝贵的政治遗产致以我们的敬意和掌声。在未来的几个星期,我还希望能和罗姆尼州长坐下来,讨论在哪些方面,我们可以共同努力,推动这个国家向前。 I want to thank my friend and partner of the last four years, America’s happy warrior, the best vice president anybody could ever hope for, Joe Biden. (Cheers, applause.) 我想谢谢我的朋友,我过去四年的搭档,美国的快乐战士—乔·拜登。能有他做副总统。夫复何求。 And I wouldn’t be the man I am today without the woman who agreed to marry me 20 years ago. (Cheers, applause.) Let me say this publicly. Michelle, I have never loved you more. (Cheers, applause.) I have never been prouder to watch the rest of America fall in love with you too as our nation’s first lady. (Cheers, applause.) 另外,假如没有那位20年前同意嫁给我的女人,我今天也不可能站在这里。让我告诉所有人吧:米歇尔,我对你的爱,是如此深切。我目睹着我之外的美国人都爱上了你,作为第一夫人的你,我对你的骄傲,也是如此深切。 Sasha and Malia — (cheers, applause) — before our very eyes, you’re growing up to become two strong, smart, beautiful young women, just like your mom. (Cheers, applause.) And I am so proud of you guys. But I will say that for now, one dog’s probably enough. (Laughter.) 萨莎和玛利亚(奥巴马的两个女儿),就在我们的注视下,你们已经成长为两位坚强、智慧、美丽的年轻女士,就像你们的妈妈一样。我真得为你们骄傲。不过我还是要说,一条狗应该已经够了。 To the best campaign team and volunteers in the history of politics — (cheers, applause) — the best — the best ever — (cheers, applause) — some of you were new this time around, and some of you have been at my side since the very beginning.(Cheers, applause.) But all of you are family. No matter what you do or where you go from here, you will carry the memory of the history we made together. (Cheers, applause.) And you will have the lifelong appreciation of a grateful president. Thank you for believing all the way — (cheers, applause) — to every hill, to every valley. (Cheers, applause.) You lifted me up the whole day, and I will always be grateful for everything that you’ve done and all the incredible work that you’ve put in. (Cheers, applause.) 至政治史上最好的竞选团队和志愿者们:你们是最好的,最最好的。你们中有些人是新鲜加入,有些人从一开始就与我们共同进退,但你们都是我的家人。无论你在做什么,以后要做什么,你们都能带上这段我们共同创造的历史,以及这位感恩的总统对你们一生的感激。 谢谢你们的一路坚信,陪我翻过每座丘岭,穿越每座山谷。一路走来,多亏你们的辅佑。 我会永远为你们所付出的一切和所有卓越之至的工作而心怀感激。 I know that political campaigns can sometimes seem small, even silly. And that provides plenty of fodder for the cynics who tell us that politics is nothing more than a contest of egos or the domain of special interests. But if you ever get the chance to talk to folks who turned out at our rallies and crowded along a rope line in a high school gym or — or saw folks working late at a campaign office in some tiny county far away from home, you’ll discover something else. 我知道有时候政治竞选看起来渺小,甚至愚蠢,这为愤世嫉俗者们提供了很多素材。他们告诉我们,政治不过是为特殊利益集团服务的猴戏。但如果你曾经同参加过我们的集会的普通人,或是在高中体育馆围线外排队的人们交谈过;或是看到在远离家乡的小郡县竞选办公室里工作到很晚的人们,你一定会有新的认识。 You’ll hear the determination in the voice of a young field organizer who’s working his way through college and wants to make sure every child has that same opportunity. (Cheers, applause.) You’ll hear the pride in the voice of a volunteer who’s going door to door because her brother was finally hired when the local auto plant added another shift. (Cheers, applause.) 你会在一位半工半读的年轻活动现场组织者声音中,听到无比的坚定。他想让每个孩子都能有均等的机会;你会在一名志愿者声音中,听到他的自豪。她挨家挨户的告诉每一个人,她的哥哥终于有了工作,因为当地的汽车公司增加了一个轮班; You’ll hear the deep patriotism in the voice of a military spouse who’s working the phones late at night to make sure that no one who fights for this country ever has to fight for a job or a roof over their head when they come home. (Cheers, applause.) 你会在一位军嫂声音中听到她的爱国主义情怀。她深夜也不放下电话是为了要让每一位保家卫国的战士,都不用在回家后,却为一份工作、一片屋檐,苦苦求而不得。 That’s why we do this. That’s what politics can be. That’s why elections matter. It’s not small, it’s big. It’s important. Democracy in a nation of 300 million can be noisy and messy and complicated. We have our own opinions. Each of us has deeply held beliefs. And when we go through tough times, when we make big decisions as a country, it necessarily stirs passions, stirs up controversy. That won’t change after tonight. And it shouldn’t. These arguments we have are a mark of our liberty, and we can never forget that as we speak, people in distant nations are risking their lives right now just for a chance to argue about the issues that matter — (cheers, applause) — the chance to cast their ballots like we did today. 这就是我们做这些的原因。政治也可以说这样的。这就是为什么,选举是重要的。它并不渺小,它是件大事,很重要的大事。在有三亿人口的国家中,民主会显得喧哗、混乱、复杂。我们有自己的观点,每个人都有自己坚定的信仰。当面对困难的时期,当我们的国家需要作出重大的决定时,它必然会激发热情,也掀起争议。这些在今晚之后都不会改变,也不应该被改变。这些争论是我们自由的印记。我们永远不能忘记,就在此时此刻,在一些遥远的国家,人民正在冒着生命的危险,只为了能有讨论那些重要话题的机会,为了能有像我们今天这样投出自己一票的机会。 But despite all our differences, most of us share certain hopes for America’s future. We want our kids to grow up in a country where they have access to the best schools and the best teachers — (cheers, applause) — a country that lives up to its legacy as the global leader in technology and discovery and innovation — (scattered cheers, applause) — with all of the good jobs and new businesses that follow. We want our children to live in an America that isn’t burdened by debt, that isn’t weakened up by inequality, that isn’t threatened by the destructive power of a warming planet. (Cheers, applause.) 尽管我们有不同,我们中的大多数,对美国的未来怀有一样的希望。我们希望自己的孩子成长在这样一个国家:他们能去到最好的学校,有最好的老师;它不会辜负前人留下的遗产,继续成为全球科技、探索、创新的领导者,有好的工作、新的产业随之而来;我们希望自己孩子成长的美国,不会被债务负累,不会因不平等而有所削弱,也不会被地球变暖而带来的危害所威胁。 We want to pass on a country that’s safe and respected and admired around the world, a nation that is defended by the strongest military on earth and the best troops this — this world has ever known — (cheers, applause) — but also a country that moves with confidence beyond this time of war to shape a peace that is built on the promise of freedom and dignity for every human being. 我们想要传承的,是一个安全并受全球尊敬与爱戴的国家。 我们想要传承的,是一个由世界最强军事力量保卫,拥有最好的军队的国家。同时,也是一个自信前行的国家——走出战争的阴霾,塑造和平景象,保障每个人的自由与尊严。 We believe in a generous America, in a compassionate America, in a tolerant America open to the dreams of an immigrant’s daughter who studies in our schools and pledges to our flag — (cheers, applause) — to the young boy on the south side of Chicago who sees a life beyond the nearest street corner — (cheers, applause) — to the furniture worker’s child in North Carolina who wants to become a doctor or a scientist, an engineer or an entrepreneur, a diplomat or even a president. 我们相信美国是一个慷慨大度的国家,一个悲天悯人的国家,更是一个海纳百川的国家。 我们要接纳在我国学校学习并对我们的国旗宣誓,满怀梦想的移民;要接纳身处芝加哥南部市井之中却能志存高远的男孩;还要接纳北卡州家具工人的孩子,他们梦想着成为医生、科学家、工程师、企业家、外交官,甚至是总统。 That’s the — (cheers, applause) — that’s the future we hope for. (Cheers, applause.) That’s the vision we share. That’s where we need to go — forward. (Cheers, applause.) That’s where we need to go. (Cheers, applause.) 那正是我们所期望的未来,是我们共有的愿景,是我们需要”前进”的方向,那是我们的目标。 Now, we will disagree, sometimes fiercely, about how to get there. As it has for more than two centuries, progress will come in fits and starts. It’s not always a straight line. It’s not always a smooth path. By itself, the recognition that we have common hopes and dreams won’t end all the gridlock, resolve all our problems or substitute for the painstaking work of building consensus and making the difficult compromises needed to move this country forward. 对于如何实现这一目标,我们可能会意见相左,有时分歧甚大,两个多世纪以来,一直如此。 我们总会断断续续地取得进步,前行的路线总有曲折,不会一直是平坦通途。 认识到我们拥有共同的希望与梦想,单靠这一点无法终结所有的政治僵局,或解决我们所有问题。建立共识,作出推动这个国家向前所必要的艰难妥协,这些艰辛的工作也无法得以替代。 But that common bond is where we must begin. Our economy is recovering. A decade of war is ending. (Cheers, applause.) A long campaign is now over. (Cheers, applause.) And whether I earned your vote or not, I have listened to you. I have learned from you. And you’ve made me a better president. And with your stories and your struggles, I return to the White House more determined and more inspired than ever about the work there is to do and the future that lies ahead. (Cheers, applause.) 但我们必须以这一共同纽带为起点。 我们的经济正在复苏,为期十年的战争已近尾声,一场漫长的竞选现已结束。 无论我是否赢得了你的选票,我都倾听了你的呼声,从你身上得到了教益,你使我成长为更优秀的总统。 带着你们的故事与挣扎,我回到白宫时,对面临的任务与未来,更为坚定,更有激情。 Tonight you voted for action, not politics as usual. (Cheers, applause.) You elected us to focus on your jobs, not ours. And in the coming weeks and months, I am looking forward to reaching out and working with leaders of both parties to meet the challenges we can only solve together — reducing our deficit, reforming out tax code, fixing our immigration system, freeing ourselves from foreign oil. We’ve got more work to do. (Cheers, applause.) But that doesn’t mean your work is done. 今晚,你们投票换来的将会是积极的行动,而不是以往那样的政治游戏。你们选择了我们,是让我们关注你们的就业,而非我们自己的官位。 在接下来的数周、数月中,我期待着与两党领袖进行接触与合作,共同应对我们必须携手攻克的难关,降低赤字、改革税法、完善移民体系、摆脱对进口石油的依赖…我们还有更多的工作要完成,但这并不意味着你们的任务已经结束。 The role of citizens in our democracy does not end with your vote. America’s never been about what can be done for us; it’s about what can be done by us together, through the hard and frustrating but necessary work of self- government. (Cheers, applause.) That’s the principle we were founded on. 公民在我们的民主体系中所扮演的角色,并不止于投票。 美利坚的意义,并不在于别人能为我们做什么,而是在于我们能一起做什么,而这依靠的就是公民自治。这虽然困难而又往往令人灰心,却是不可或缺的。这是我们的建国理念。 This country has more wealth than any nation, but that’s not what makes us rich. We have the most powerful military in history, but that’s not what makes us strong. Our university, our culture are all the envy of the world, but that’s not what keeps the world coming to our shores. What makes America exceptional are the bonds that hold together the most diverse nation on Earth, the belief that our destiny is shared — (cheers, applause) — that this country only works when we accept certain obligations to one another and to future generations, so that the freedom which so many Americans have fought for and died for come with responsibilities as well as rights, and among those are love and charity and duty and patriotism. That’s what makes America great. (Cheers, applause.) 我们国家的财富多于其他任何国家,可我们的富有并不源于此。 我们有史上最强的军事力量,可这并不是我们力量的源头。 我们的大学,我们的文化,为全世界所钦羡,可这并非吸引各国人民前来我国的根源。 美国的卓尔不群之根源在于,将全球最为多元化的国家团结起来的纽带,在于信奉我们的命运紧密相连。信奉只有当我们对彼此,对下几代人负起一定责任,我们国家才有希望。美国的卓尔不群之根源,在于无数美国人为之奋斗与献身的自由,这自由背后,既有义务又有权 利,其中就包括仁爱、慈善、责任和爱国。美国的伟大,就是靠这些精神铸就而成的。 I am hopeful tonight because I have seen this spirit at work in America. I’ve seen it in the family business whose owners would rather cut their own pay than lay off their neighbors and in the workers who would rather cut back their hours than see a friend lose a job. I’ve seen it in the soldiers who re-enlist after losing a limb and in those SEALs who charged up the stairs into darkness and danger because they knew there was a buddy behind them watching their back. (Cheers, applause.) I’ve seen it on the shores of New Jersey and New York, where leaders from every party and level of government have swept aside their differences to help a community rebuild from the wreckage of a terrible storm. (Cheers, applause.) 我今晚充满希望,因为我目睹了美国上下洋溢着的精神: 在宁愿扣自己薪水,也不愿裁掉邻里员工的家族企业中; 在宁愿自己少干些,也不愿让朋友失业的工人们身上; 在手脚伤残,却仍延长服役年限的士兵身上; 在海军陆战队员身上,他们无畏地冲上楼梯,冲进黑暗与危险,只因心知有人会照顾他们。 在新泽西与纽约的海岸上也可以见到,各党领袖、各级政府撇开分歧,共同帮助一个社区重建被可怕的风暴摧毁的家园。 And I saw it just the other day in Mentor, Ohio, where a father told the story of his 8-year-old daughter whose long battle with leukemia nearly cost their family everything had it not been for health care reform passing just a few months before the insurance company was about to stop paying for her care. (Cheers, applause.) I had an opportunity to not just talk to the father but meet this incredible daughter of his. And when he spoke to the crowd, listening to that father’s story, every parent in that room had tears in their eyes because we knew that little girl could be our own. 前些天,我在俄亥俄州的曼图尔市见到了一位父亲,他跟我讲了他8岁女儿的故事。女儿与白血病的斗争差点使他们倾家荡产,幸好医保改革在保险公司停止支付,其医疗费用前数月得以通过。我不仅与这位父亲进行了交谈,也遇到了他坚强的女儿。当她向听众发言时,在场的每一位父母都眼含热泪。因为我们知道,这个小女孩的遭遇也可能发生在我们的孩子身上。 And I know that every American wants her future to be just as bright. That’s who we are. That’s the country I’m so proud to lead as your president. (Cheers, applause.) And tonight, despite all the hardship we’ve been through, despite all the frustrations of Washington, I’ve never been more hopeful about our future. (Cheers, applause.) I have never been more hopeful about America. And I ask you to sustain that hope. 我知道每一位美国同胞,都希望她有同样光明的未来。 这就是我们,这就是我非常自豪地以总统身份领导的国家。 今晚,纵有我们所经历的磨难,纵有华盛顿诸般挫折,我从未对我们的未来如此充满希望,我从未对美利坚如此充满希望。 我请求你们,保持这份希望。 AUDIENCE MEMBER: We got your back, Mr. President! PRESIDENT OBAMA: I’m not talking about blind optimism, the kind of hope that just ignores the enormity of the tasks ahead or the road blocks that stand in our path. I’m not talking about the wishful idealism that allows us to just sit on the sidelines or shirk from a fight. I have always believed that hope is that stubborn thing inside us that insists, despite all the evidence to the contrary, that something better awaits us so long as we have the courage to keep reaching, to keep working, to keep fighting. (Cheers, applause.) 我不是指盲目乐观,无视眼前艰巨任务与障碍的那种希望,我也不是指让我们袖手旁观或逃避斗争的那种一厢情愿的理想主义。 我一直认为,希望是我们心中顽强不屈的那样东西。 虽有各种不利证据,却仍坚持有更好的未来等待着我们。只要我们有勇气去不断争取、不断努力、不断奋斗。 America, I believe we can build on the progress we’ve made and continue to fight for new jobs and new opportunities and new security for the middle class. I believe we can keep the promise of our founding, the idea that if you’re willing to work hard, it doesn’t matter who you are or where you come from or what you look like or where you love (ph). It doesn’t matter whether you’re black or white or Hispanic or Asian or Native American or young or old or rich or poor, abled, disabled, gay or straight. (Cheers, applause.) You can make it here in America if you’re willing to try. (Cheers, applause.) 美利坚,我相信,我们能百尺竿头更进一步,继续奋斗,为中产阶级创造就业、创造机会、创造保障。 我相信,我们能继续履行国父们的承诺——只要你踏实肯干,你是谁,从哪儿来,什么种族,爱哪里,都不重要。无论你是黑人、白人、西班牙裔、亚裔,还是印第安居民,无论你年轻与否、富有与否、健全与否、性向如何,你都能在美国有所成就,只要你愿意努力。 I believe we can seize this future together because we are not as divided as our politics suggests. We’re not as cynical as the pundits believe. We are greater than the sum of our individual ambitions and we remain more than a collection of red states and blue states. We are, and forever will be, the United States of America. (Cheers, applause.) And together, with your help and God’s grace, we will continue our journey forward and remind the world just why it is that we live in the greatest nation on earth. (Cheers, applause.) Thank you, America. (Cheers, applause.) God bless you. God bless these United States. (Cheers, applause.) 我相信,我们可以共同把握这一未来。因为有别于政坛所表现的,我们其实并没有那么分裂,我们并不像评论员们所认为的那样愤世嫉俗。我们的伟大,胜于我们个人野心的总和,我们不仅仅是红蓝州的集合。我们现在是,也将永远是,美利坚合众国。 在你们的帮助下和上帝的眷顾下,我们将继续前进,向全世界昭示,我们为何居于地球上最伟大的国家。 感谢你们,美利坚的人民们! 上帝保佑你们! 上帝保佑美国!]]></content>
<categories>
<category>励志</category>
</categories>
<tags>
<tag>励志</tag>
<tag>名人演讲</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Python 爬取 CSDN 博客信息]]></title>
<url>%2F2019%2F04%2F09%2FPython-%E7%88%AC%E5%8F%96-CSDN-%E5%8D%9A%E5%AE%A2%E4%BF%A1%E6%81%AF%2F</url>
<content type="text"><![CDATA[突然闲来无事想要爬取csdn博客,顺便温习下相关技术点。 爬取目标以我的csdn主页为例爬取的主要的数据已经在上用红线图标出来了,主要可分为两部分 所有博客的八个统计数据,原创的博客数、你的粉丝数、博客获得的赞、博客的评论数、博客等级、访问量、积分和排名每篇博客的具体信息,如标题、发布时间、阅读数、评论数 思路分析Google Chrome浏览器F12开发者工具查看网页结构,比较简单,如下图所示csdn网站虽然是一个技术性博客,但是貌似它的反爬措施做的不那么优秀,举个例子,我在分析网页结构的过程中发现它的评论数不是通过Ajax动态渲染的,而新浪新闻做到了这一点,也许是因为新闻类的实时性要求较高而技术博客类没这个必要吧。 主要技术点Requests库获取网页我看到许多爬虫教程都是用的urllib2等比较过时的爬虫库来获取网页信息,一来python2马上停止支持,python2时代的urllib2的凸现出来的毛病会越来越多且无法得到官方的修复;二来无论是基于python2的ulilib2还是python3的urllib3,过程都稍显繁琐,不如requests库简明,而且urllib2/3能做的requests都能做,干嘛不用requests呢? requests.get(url=myUrl,headers=headers).text get()接收两个关键字参数,第一个就是我们要爬取网页的URL,第二个就是请求头,用于模拟浏览器访问服务器,不然csdn的服务器会拒绝连接,不懂的可以百度补一下计算机网络相关知识。 get()返回的是一个requests.models.Response对象,通过它的text属性可以得到网页的源码,字符串类型,这样以后我们就能通过方便地解析网页获取我们想要的信息了。 pyqeury库解析网页其实解析网页最直接的办法是利用re这个库写正则表达式提取信息,优点是正则是万能的,所有的字符串提取都可以通过字符串提取,只有改变匹配的规则就行了,不过缺点是学习起来费劲(最好还是要掌握的,毕竟每个语言的匹配规则都是类似的,在java学的匹配规则照样可以用在python中,只是语法不同,API稍有差异) 第三方解析库有BeautifulSoup、lxml、pyquery等,学习这些库前最好已经掌握css选择器的一些语法规则,再学这些解析库就事半功倍了,个人感觉最好用的是pyquery库。安装pyquery需要在在命令行下输入: pip istall pyquery 拿到网页源码后,通过 doc = pq(myPage) 得到一个pyquery.pyquery.PyQuery对象,其中参数就是网页源码 然后可以通过 doc(“aside .data-info dl”).items() 来得到aside标签下class为data-info的标签下的所有dl标签,返回的仍是一个pyquery.pyquery.PyQuery对象,如果dl的标签不止一个,我们可以通过.items()把这个对象转乘一个生成器,通过for a in b来迭代获取每一个dl标签,同样地,迭代出来的每一个子项还是pyquery.pyquery.PyQuery对象。 下面是pyquery常见的api|名称|功能||:—:|:—:||attr(key)|得到标签下属性key的属性值,字符串类型||parent()/children()|得到标签的父/子标签||text()|得到标签的文本| 更多的api可以参考:pyqeury官方教程 另外的,假设一个pyquery.pyquery.PyQuery对象a,通过a(“li”),可以对a里的li标签再选择,所以这种选择过程可以是多重嵌套的,一个容易忘记的选择器语法是a(“[b=c]”),用来选择a标签下属性b的属性值为c的所有标签。 运行结果如下图所示,所有的功能目标已经实现 其中csdn id就是想要爬取博主的id,可以去博主的主页看 源代码2019/01/21,代码如下: 代码最新更新在我的github:python爬虫集合之csdn爬虫 同时可以关注我的csdn爬虫专栏:python3爬虫实战 感谢支持! # -*- coding: utf-8 -*- # author: inspurer(月小水长) # pc_type lenovo # create_date: 2019/1/21 # file_name: csdn # qq_mail [email protected] import requests from pyquery import PyQuery as pq # 当前的博客列表页号 page_num = 1 account = str(input('print csdn id:')) #account = "ygdxt" # 首页地址 baseUrl = 'http://blog.csdn.net/' + account # 连接页号,组成爬取的页面网址 myUrl = baseUrl + '/article/list/' + str(page_num) headers = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'} # 构造请求 # 访问页面 myPage = requests.get(myUrl,headers=headers).text doc = pq(myPage) data_info = doc("aside .data-info dl").items() for i,item in enumerate(data_info): if i==0: print("原创:"+item.attr("title")) if i==1: print("粉丝:"+item.attr("title")) if i==2: print("喜欢:"+item.attr("title")) if i==3: print("评论:"+item.attr("title")) grade_box = doc(".grade-box dl").items() for i,item in enumerate(grade_box): if i==0: childitem = item("dd > a") print("等级:"+childitem.attr("title")[0:2]) if i==1: childitem = item("dd") print("访问:"+childitem.attr("title")) if i==2: childitem = item("dd") print("积分:"+childitem.attr("title")) if i==3: print("排名:"+item.attr("title")) # 获取每一页的信息 while True: # 首页地址 baseUrl = 'http://blog.csdn.net/' + account # 连接页号,组成爬取的页面网址 myUrl = baseUrl + '/article/list/' + str(page_num) # 构造请求 myPage = requests.get(myUrl,headers=headers).text if len(myPage) < 30000: break print('-----------------------------第 %d 页---------------------------------' % (page_num,)) doc = pq(myPage) articles = doc(".article-list > div").items() articleList = [] for i,item in enumerate(articles): if i == 0: continue title = item("h4 > a").text()[2:] date = item("p > .date").text() num_item = item("p > .read-num").items() ariticle = [date, title] for j,jitem in enumerate(num_item): if j == 0: read_num = jitem.text() ariticle.append(read_num) else: comment_num = jitem.text() ariticle.append(comment_num) articleList.append(ariticle) for item in articleList: if(len(item)==4): print("%s %s %s %s"%(item[0],item[1],item[2],item[3])) page_num = page_num + 1]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>Python</tag>
<tag>爬虫</tag>
<tag>CSDN</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Python 实现自动化翻译和替换的脚本]]></title>
<url>%2F2019%2F04%2F08%2FPython-%E5%AE%9E%E7%8E%B0%E8%87%AA%E5%8A%A8%E5%8C%96%E7%BF%BB%E8%AF%91%E5%92%8C%E6%9B%BF%E6%8D%A2%E7%9A%84%E8%84%9A%E6%9C%AC%2F</url>
<content type="text"><![CDATA[妈妈再也不用担心我的英语了。 一个可能你似曾相识的场景阅读内容包含大量英文的 PPT、Word、Excel 或者记事本时,由于英语不熟悉,为了流利地阅读,需要打开浏览器进入谷歌翻译的主界面,然后把英文复制到谷歌翻译的输入框中,最后又把翻译结果复制回 PPT、Word 和 Excel。 要是一个两个单词还好,要是发现有 100 个单词不认识,就必须复制粘贴 200 次,如此机械性重复性的工作,应该交给程序来做,这就是我设计下面这个自动化翻译工具的初衷。 提升办公效率的法宝 如上图,运行程序并保持后台运行,在电脑上的任何一个软件中选择一段文本,并 Ctrl + C 复制到系统剪贴板中,程序就会自动帮助我们完成翻译,并将翻译结果自动复制到系统剪贴版中,只需 Ctrl + V,就完成了翻译结果对原文的替换。 编码实现程序主要分为两部分,第一部分为谷歌翻译爬虫,第二部分就是实现这个将翻译结果自动替换的业务逻辑。 谷歌翻译爬虫通过浏览器 F12 开发者工具,很容易定位到翻译请求的 URL: http://translate.google.cn/translate_a/single?client=t&sl=en&tl=zh-CN&hl=zh-CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss &dt=t&ie=UTF-8&oe=UTF-8&clearbtn=1&otf=1&pc=1&srcrom=0&ssel=0&tsel=0&kc=2 这个请求接受两个参数,一个就是我们要翻译的字符串 q,另一个是用于用户认证的 tk(token),其中 q 很容易构造,tk 的构造就需要花费一番心力了,需要我们调试 js 代码,这里参考 Github 上大神的轮子: https://github.com/cocoa520/Google_TK 谷歌翻译爬虫的主要代码如下: def translate(tk, content): if len(content) > 4891: print("翻译的长度超过限制!!!") return param = {'tk': tk, 'q': content} result = requests.get("""http://translate.google.cn/translate_a/single?client=t&sl=en &tl=zh-CN&hl=zh-CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss &dt=t&ie=UTF-8&oe=UTF-8&clearbtn=1&otf=1&pc=1&srcrom=0&ssel=0&tsel=0&kc=2""", params=param) data = result.json() print(data[0][0][0]) 返回结果是 json 形式的,翻译结果保存在结果的第一个元组中。 Python 操作系统剪贴板将读取剪贴板的内容的代码封装成函数如下: def getText():#读取剪切板 # 打开剪贴板 w.OpenClipboard() # 读取剪贴板的内容 d = w.GetClipboardData(win32con.CF_TEXT) # 关闭剪贴板 w.CloseClipboard() try: return d.decode('utf-8') except: return d.decode('gbk') 返回值 d 是字节类型的,需要解码,中文按 gbk 格式解码,英文按 utf-8 解码。 类似地,写入剪贴板的代码如下: def setText(aString):#写入剪切板 # 打开剪贴板 w.OpenClipboard() # 清空剪贴板 w.EmptyClipboard() # 写入剪贴板 w.SetClipboardText(aString) # 关闭剪贴板 w.CloseClipboard() 实现将翻译结果自动替换原文的逻辑的代码如下: while(True): # 如果剪贴板正在被占用 try: cs = getText() except: time.sleep(1) cs = getText() print('cs',cs) if cs and cs != ls: print('准备翻译') content = getText() tk = js.getTk(content) res = translate(tk, content) setText(res) time.sleep(1) ls = res 值得注意的是,系统剪贴板对象是单例模式的,在操作系统范围内只有一个,而且读写剪贴板都是互斥的,在读(写)剪贴板的同时不允许任何对剪贴板的写(读)操作。试想这样一种情景,我们在其他软件中 Ctrl + C 写入剪贴板,而此时我们的程序代码正好执行到读剪贴板那一行,毫无疑问会报错,我的解决办法是使用 try…except 语句延时 1 s再读取,这样可以大大降低读写碰撞的概率,但无疑消耗了程序性能。最好的办法是判断剪贴板对象句柄是否被占用,其实我一直在寻找是否存在判断剪贴板对象句柄是否被占用的 API,但是一直没有找到,如果有人知道的话,欢迎评论区留言。 源代码获取关注公众号 月小水长,后台回复,自动替换的翻译软件 即可获取所有源代码]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>Python</tag>
<tag>爬虫</tag>
<tag>谷歌翻译</tag>
</tags>
</entry>
<entry>
<title><![CDATA[PAT (Advanced Level) Practice NO.1002]]></title>
<url>%2F2019%2F03%2F23%2FPAT-Advanced-Level-Practice-NO-1002%2F</url>
<content type="text"><![CDATA[Question1002 A+B for Polynomials (25 分)This time, you are supposed to find A+B where A and B are two polynomials.Input Specification: Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial: K N1 aN1 N2 aN2 … NK aNK where K is the number of nonzero terms in the polynomial, Ni and aNi (i=1,2,⋯,K) are the exponents and coefficients, respectively. It is given that 1≤K≤10,0≤NK<⋯<N2<N1≤1000.Output Specification: For each test case you should output the sum of A and B in one line, with the same format as the input. Notice that there must be NO extra space at the end of each line. Please be accurate to 1 decimal place. Sample Input:2 1 2.4 0 3.22 2 1.5 1 0.5 Sample Output:3 2 1.5 1 2.9 0 3.2 Solutionimport java.util.*; //CreateTime: 2019/3/21 23:21 //Author: 月小水长(https://github.com/inspurer) /* 类名:首字母大写,其他单词中首字母大写,其他小写 方法名:首字母小写,其他单词中首字母大写,其他小写 变量:与方法名规则同 包名:全部小写 */ public class Main { public static void main(String [] args){ Scanner sc = new Scanner(System.in); String aLine = null; String [] l = null; HashMap<Integer,Float> [] hm = new HashMap[2]; for(int i = 0; i < 2; i++){ aLine = sc.nextLine(); l = aLine.split(" "); hm[i] = new HashMap<Integer, Float>(Integer.parseInt(l[0])); for(int j = 1; j < l.length; j += 2){ hm[i].put(Integer.parseInt(l[j]),Float.parseFloat(l[j+1])); } } sc.close(); HashSet<Integer> setKeys = new HashSet<>(hm[0].keySet()); setKeys.addAll(hm[1].keySet()); ArrayList<Integer> sumKeys = new ArrayList<>(setKeys); HashMap<Integer,Float> res = new HashMap<Integer,Float>(); // 排除掉系数为 0 for(int i = 0; i < sumKeys.size(); i++){ int key = sumKeys.get(i); float value = hm[0].getOrDefault(key,0.0f)+hm[1].getOrDefault(key,0.0f); if(value == 0.0f) continue; res.put(key,value); } ArrayList resultKeys = new ArrayList(res.keySet()); Collections.sort(resultKeys, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o2 - o1; } }); // 如果项数为0,只把0输出就可以了 if(res.size() == 0) { System.out.print(0); return; } System.out.print(res.size()); System.out.print(" "); for(int i = 0; i < resultKeys.size(); i++){ int key = (int)resultKeys.get(i); System.out.print(key); System.out.print(" "); System.out.printf("%.1f",res.get(key)); if(i == resultKeys.size() - 1) break; System.out.print(" "); } } } /* 格式错误,要求跟输入一样,浮点数保留一位小数,最后不能有空格 没有考虑到如果两个多项式相加,会出现系数为0的情况,此时不再记录(多虑的是demo分明有0输出了么,但是它是指数不是系数) 数据的类型,一定尽量开始就合适 */ CodePAT Advanced Pratice 题解系列代码集合]]></content>
<categories>
<category>PAT</category>
</categories>
<tags>
<tag>PAT</tag>
<tag>collection</tag>
</tags>
</entry>
<entry>
<title><![CDATA[PAT (Advanced Level) Practice No.1001]]></title>
<url>%2F2019%2F03%2F22%2FPAT-Advanced-Level-Practice-No-1001%2F</url>
<content type="text"><![CDATA[Question001 A+B Format (20 分)Calculate a+b and output the sum in standard format – that is, the digits must be separated into groups of three by commas (unless there are less than four digits).Input Specification: Each input file contains one test case. Each case contains a pair of integers a and b where −106≤a,b≤106. The numbers are separated by a space.Output Specification: For each test case, you should output the sum of a and b in one line. The sum must be written in the standard format. Sample Input:-1000000 9 Sample Output:-999,991 Solutionimport java.util.LinkedList; import java.util.Scanner; //CreateTime: 2019/3/21 23:21 //Author: 月小水长(https://github.com/inspurer) /* 类名:首字母大写,其他单词中首字母大写,其他小写 方法名:首字母小写,其他单词中首字母大写,其他小写 变量:与方法名规则同 包名:全部小写 */ public class Main { public static void main(String [] args){ Scanner scanner = new Scanner(System.in); int num1 = Integer.parseInt(scanner.next()); int num2 = Integer.parseInt(scanner.next()); scanner.close(); num1 += num2; int flag = num1>=0?1:0; num1 = num1>0?num1:-num1; if(String.valueOf(num1).length()<4) { if (flag == 0) { System.out.print(-num1); } else { System.out.print(num1); } return; } LinkedList<String> result = new LinkedList<String>(); do{ result.add(String.valueOf(num1%10)); num1 /= 10; if((result.size()+1)%4==0&&num1>0){ result.add(","); } }while (num1>0); if(flag==0){ result.add("-"); } for(int i = result.size()-1;i>=0;i--) System.out.print(result.get(i)); } } ConclusionScanner.nextInt() 方法只能接收正整数,如输入负整数则会忽略掉掉负号,相当于对输入取 abs() ,要想解决这个 Bug,可以通过 1int num1 = Integer.parseInt(scanner.next()); 解决。 next() 和 nextLine() 都接收字符串;next() 方法一定要接收到有效字符串才可以结束输入,对输入有效字符之前遇到的空格键、Tab 键或回车键等,next() 方法会自动将其去掉,只有在输入有效字符之后,next() 方法才将其后输入的空格键、Tab 键或回车键视为分隔符或结束符;nextLine() 方法的结束符只是回车键,即 nextLine() 方法返回的是回车键的所有字符。 CodePAT Advanced Pratice 题解系列代码集合]]></content>
<categories>
<category>PAT</category>
</categories>
<tags>
<tag>PAT</tag>
<tag>scanner</tag>
</tags>
</entry>
<entry>
<title><![CDATA[利用Tensorflow构建自己的物体识别模型(一)]]></title>
<url>%2F2018%2F12%2F03%2F%E5%88%A9%E7%94%A8Tensorflow%E6%9E%84%E5%BB%BA%E8%87%AA%E5%B7%B1%E7%9A%84%E7%89%A9%E4%BD%93%E8%AF%86%E5%88%AB%E6%A8%A1%E5%9E%8B-%E4%B8%80%2F</url>
<content type="text"><![CDATA[原料windows10+python3.5+pycharm 安装tensorflow利用Tensorflow训练搭建自己的物体训练模型,万里长征第一步,先安装tensorflow。 tensorflow分为cpu版和gpu版,gpu版的运行速度是cpu的50倍,但是gpu版的坑太多,要安装许多开发套件,对windows的支持不够友好;更为致命的是,它需要Nvida的中高端显卡,我的电脑系统是windows10,显卡是入门级显卡,开始我还想挣扎一下,安装个gpu版,大概试了一个晚上,到底是没有成功,识时务者为俊杰,那就安装cpu版的吧。 pip insatll tensorflow 假如没有报错,做个测试,运行以下代码 import tensorflow as tf #指定一个常数张量 first_blood = tf.constant('double kill') #创建一个会话,方便查看结果 sess = tf.Session() print(str(sess.run(first_blood))) 运行结果如下 E:\python\python.exe "E:/pycharm src/TF/__init__.py" 2018-12-01 23:33:25.181550: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 double kill Process finished with exit code 0 如果出现警告: Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 翻译过来的大致意思是:你的CPU支持AVX扩展,但是你安装的TensorFlow版本无法编译使用 此时需要在第一行代码前加上两行代码: import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' import tensorflow as tf # 指定一个常数张量 first_blood = tf.constant('double kill') # 创建一个会话,方便查看结果 sess = tf.Session() print(str(sess.run(first_blood))) 下载Tensorflow object detection API如果有git的话,右键git bash,使用命令下载: git clone https://github.com/tensorflow/models.git 或者直接打开网站: https://github.com/tensorflow/models 点击绿色按钮->downlaod zip 下载好之后,把文件解压,注意解压路径不要包含中文,比如我的解压后的路径是: C:\Users\lenovo\Desktop\note\gitclone\models 如果下载速度很慢,可以参考:https://blog.csdn.net/ygdxt/article/details/82825013 下载并配置protoc在https://github.com/google/protobuf/releases中选择windows版本: 只有win32,也就是windows32位的,64位是兼容32位的。 下载好之后,解压,把bin目录下的protoc.exe复制到..\models\research文件夹下。 接着就是配置protoc了,在打开cmd下切换到..\models\research目录, 执行命令protoc object_detection\protos\*.proto --python_out=. 如果报以下的错(其实很大可能性会报错,无论是不是在管理员模式下): object_detection\protos*.proto: No such file or directory 则需要对指令做修改,指令protoc object_detection\protos\*.proto --python_out=.中的*.proto表示是对research目录下的所有后缀名为proto的文件做操作,那干脆我们把指令中的*.proto这部分改成所有后缀名为proto的文件,每执行一次,就会生成一个.py文件,由于文件太多,我已经把指令写成脚本: import os path_url = os.path.join(os.getcwd(),r"object_detection\protos") print("proto path:",path_url) for file in os.listdir(path_url): cmd = "protoc object_detection\protos\{} --python_out=." if file.endswith(".proto"): command = cmd.format(file) print("excuting command:",command) os.popen(command) 在..\research目录下新建一个文件excuter.py,把以上代码复制进去,保存运行,稍等一会儿就可以看到..\research\object_detection\protos目录下生成了许多.py文件,说明protoc配置成功。 models环境变量配置配置环境变量依次打开:我的电脑—>高级系统设置—>环境变量,新建一个系统变量: 系统变量名只要不和已有的重复,符合命令规范,没有其他要求,我这里是tensorflow系统变量名下有两个值,..\research和..\research\slim的绝对路径。 测试在..\research下打开cmd,运行以下命令, python object_detection/builders/model_builder_test.py 如果出现错误: 报错原因是你的models路径太长,python无法找指定模块,解决办法是在你的python安装路径下新建一个tensorflow_model.pth文件(比如我的是E:\python\Lib\site-packages)把写到环境变量里的那两个路径复制到该文件中。 再运行命令python object_detection/builders/model_builder_test.py 说明配置成功 利用tensorflow自带模型测试测试的图片是在 C:\Users\lenovo\Desktop\note\gitclone\models\research\object_detection\test_images 我们看到这里有现成的两张图片,当然也可以换成自己的。 测试的脚本是 C:\Users\lenovo\Desktop\note\gitclone\models\research\object_detection\object_detection_tutorial.ipynb 这是一个需要用jupyter notebook打开的文件,不过好像在jupyter notebook运行会有许多毛病我已经把这个ipynb文件改写成py文件,并修复了一些未知问题,文件内容如下: import numpy as np import os import six.moves.urllib as urllib import sys import tarfile import tensorflow as tf import zipfile from distutils.version import StrictVersion from collections import defaultdict from io import StringIO from matplotlib import pyplot as plt from PIL import Image # This is needed since the notebook is stored in the object_detection folder. sys.path.append("..") from object_detection.utils import ops as utils_ops if StrictVersion(tf.__version__) < StrictVersion('1.9.0'): raise ImportError('Please upgrade your TensorFlow installation to v1.9.* or later!') import numpy as np import os import six.moves.urllib as urllib import sys import tarfile import tensorflow as tf import zipfile from distutils.version import StrictVersion from collections import defaultdict from io import StringIO from matplotlib import pyplot as plt from PIL import Image # This is needed since the notebook is stored in the object_detection folder. sys.path.append("..") from object_detection.utils import ops as utils_ops if StrictVersion(tf.__version__) < StrictVersion('1.9.0'): raise ImportError('Please upgrade your TensorFlow installation to v1.9.* or later!') from utils import label_map_util from utils import visualization_utils as vis_util # What model to download. MODEL_NAME = 'ssd_mobilenet_v1_coco_2017_11_17' MODEL_FILE = MODEL_NAME + '.tar.gz' DOWNLOAD_BASE = 'http://download.tensorflow.org/models/object_detection/' # Path to frozen detection graph. This is the actual model that is used for the object detection. PATH_TO_FROZEN_GRAPH = MODEL_NAME + '/frozen_inference_graph.pb' # List of the strings that is used to add correct label for each box. PATH_TO_LABELS = os.path.join('data', 'mscoco_label_map.pbtxt') opener = urllib.request.URLopener() opener.retrieve(DOWNLOAD_BASE + MODEL_FILE, MODEL_FILE) tar_file = tarfile.open(MODEL_FILE) for file in tar_file.getmembers(): file_name = os.path.basename(file.name) if 'frozen_inference_graph.pb' in file_name: tar_file.extract(file, os.getcwd()) detection_graph = tf.Graph() with detection_graph.as_default(): od_graph_def = tf.GraphDef() with tf.gfile.GFile(PATH_TO_FROZEN_GRAPH, 'rb') as fid: serialized_graph = fid.read() od_graph_def.ParseFromString(serialized_graph) tf.import_graph_def(od_graph_def, name='') category_index = label_map_util.create_category_index_from_labelmap(PATH_TO_LABELS, use_display_name=True) def load_image_into_numpy_array(image): (im_width, im_height) = image.size return np.array(image.getdata()).reshape( (im_height, im_width, 3)).astype(np.uint8) # For the sake of simplicity we will use only 2 images: # image1.jpg # image2.jpg # If you want to test the code with your images, just add path to the images to the TEST_IMAGE_PATHS. PATH_TO_TEST_IMAGES_DIR = 'test_images' TEST_IMAGE_PATHS = [ os.path.join(PATH_TO_TEST_IMAGES_DIR, 'image{}.jpg'.format(i)) for i in range(1, 3) ] # Size, in inches, of the output images. IMAGE_SIZE = (12, 8) output_num = 1 output_img_dic = r'\output_images' def run_inference_for_single_image(image, graph): with graph.as_default(): with tf.Session() as sess: # Get handles to input and output tensors ops = tf.get_default_graph().get_operations() all_tensor_names = {output.name for op in ops for output in op.outputs} tensor_dict = {} for key in [ 'num_detections', 'detection_boxes', 'detection_scores', 'detection_classes', 'detection_masks' ]: tensor_name = key + ':0' if tensor_name in all_tensor_names: tensor_dict[key] = tf.get_default_graph().get_tensor_by_name( tensor_name) if 'detection_masks' in tensor_dict: # The following processing is only for single image detection_boxes = tf.squeeze(tensor_dict['detection_boxes'], [0]) detection_masks = tf.squeeze(tensor_dict['detection_masks'], [0]) # Reframe is required to translate mask from box coordinates to image coordinates and fit the image size. real_num_detection = tf.cast(tensor_dict['num_detections'][0], tf.int32) detection_boxes = tf.slice(detection_boxes, [0, 0], [real_num_detection, -1]) detection_masks = tf.slice(detection_masks, [0, 0, 0], [real_num_detection, -1, -1]) detection_masks_reframed = utils_ops.reframe_box_masks_to_image_masks( detection_masks, detection_boxes, image.shape[0], image.shape[1]) detection_masks_reframed = tf.cast( tf.greater(detection_masks_reframed, 0.5), tf.uint8) # Follow the convention by adding back the batch dimension tensor_dict['detection_masks'] = tf.expand_dims( detection_masks_reframed, 0) image_tensor = tf.get_default_graph().get_tensor_by_name('image_tensor:0') # Run inference output_dict = sess.run(tensor_dict, feed_dict={image_tensor: np.expand_dims(image, 0)}) # all outputs are float32 numpy arrays, so convert types as appropriate output_dict['num_detections'] = int(output_dict['num_detections'][0]) output_dict['detection_classes'] = output_dict[ 'detection_classes'][0].astype(np.uint8) output_dict['detection_boxes'] = output_dict['detection_boxes'][0] output_dict['detection_scores'] = output_dict['detection_scores'][0] if 'detection_masks' in output_dict: output_dict['detection_masks'] = output_dict['detection_masks'][0] return output_dict for image_path in TEST_IMAGE_PATHS: image = Image.open(image_path) # the array based representation of the image will be used later in order to prepare the # result image with boxes and labels on it. image_np = load_image_into_numpy_array(image) # Expand dimensions since the model expects images to have shape: [1, None, None, 3] image_np_expanded = np.expand_dims(image_np, axis=0) # Actual detection. output_dict = run_inference_for_single_image(image_np, detection_graph) # Visualization of the results of a detection. vis_util.visualize_boxes_and_labels_on_image_array( image_np, output_dict['detection_boxes'], output_dict['detection_classes'], output_dict['detection_scores'], category_index, instance_masks=output_dict.get('detection_masks'), use_normalized_coordinates=True, line_thickness=8) plt.figure(figsize=IMAGE_SIZE) print(1,image_np) plt.imshow(image_np) plt.show() global output_num global output_img_dic if not os.path.exists(output_img_dic): os.mkdir(output_img_dic) output_img_path = os.path.join(output_img_dic,str(output_num)+".png") plt.savefig(output_img_path) 运行上述代码需要安装matplotlib库,直接pip install matplotlib安装失败的可以去官网安装与python版本对应的whl文件。安装matplotlib.whl时需要先出pycharm。同时由于需要下载模型文件,需要在网络好的情况下进行测试。否则就会报HTTP ERROR 运行效果图 声明以上就是本次教程的所有内容,后续还会有系列教程,原创作品,转载请联系[email protected]欢迎大家多多上机操作,指出本教程的不足之处,如有问题,可加群交流,群号码: 861016679本文首发于我的简书,如果您在本站上看到了google广告,请多多点击,算是对我的一个鼓励,能够赞赏那就更好了,谢谢!]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>Python</tag>
<tag>tensorflow</tag>
</tags>
</entry>
<entry>
<title><![CDATA[一文搞定 Python 的时间处理]]></title>
<url>%2F2018%2F12%2F03%2F%E4%B8%80%E6%96%87%E6%90%9E%E5%AE%9Apython%E7%9A%84%E6%97%B6%E9%97%B4%E5%A4%84%E7%90%86%2F</url>
<content type="text"><![CDATA[如果认真看完这篇文章你还不知道怎么处理python的时间问题,你可以来diss我 time模块# -*- coding: utf-8 -*- # author: inpurer(月小水长) # pc_type lenovo # create_date: 2018/12/3 # file_name: timetest.py # description: 月小水长,热血未凉 import time t0 = time.time() #description: 输出当前时间距离1970.1.1的秒数,精确到小数点后6位,也叫做时间戳 #output sample: 1543799532.602318 print(t0) t1 = time.localtime(t0) #description: 把时间戳转成元组,包含七个元素,前六个见名知意,tm_wday是指今天是当前周的第几天(index from 0),tm_yday类似,tm_isdst是否是夏令时,不用关心 #output sample: time.struct_time(tm_year=2018, tm_mon=12, tm_mday=3, tm_hour=9, tm_min=22, tm_sec=24, tm_wday=0, tm_yday=337, tm_isdst=0) print(t1) #so,可以这样输出今天是今年的第多少天 print(t1[-2]+1) #下面是对该元组的格式化 #description: 简单可读形式 #output sample: Mon Dec 3 09:31:18 2018 t2 = time.asctime(t1) print(t2) #description: 可通过参数设置成各种形式,下面是一种标准形式,各参数见名知意 #output sample: 2018-12-03 09:33:36 t3 = time.strftime("%Y-%m-%d %H:%M:%S", t1) print(t3) #%y 两位数的年份表示(00-99) # %Y 四位数的年份表示(000-9999) # %m 月份(01-12) # %d 月内中的一天(0-31) # %H 24小时制小时数(0-23) # %I 12小时制小时数(01-12) # %M 分钟数(00=59) # %S 秒(00-59) # # %a 本地简化星期名称 # %A 本地完整星期名称 # %b 本地简化的月份名称 # %B 本地完整的月份名称 # %c 本地相应的日期表示和时间表示 # %j 年内的一天(001-366) # %p 本地A.M.或P.M.的等价符 # %U 一年中的星期数(00-53)星期天为星期的开始 # %w 星期(0-6),星期天为星期的开始 # %W 一年中的星期数(00-53)星期一为星期的开始 # %x 本地相应的日期表示 # %X 本地相应的时间表示 # %Z 当前时区的名称 # %% %号本身 # 下面是把格式化字符串转成元组 # description: 第一个参数个格式化后的字符串,后一个参数和格式化对应,便于反格式化 # output sample: time.struct_time(tm_year=2018, tm_mon=12, tm_mday=3, tm_hour=9, tm_min=47, tm_sec=7, tm_wday=0, tm_yday=337, tm_isdst=-1) t4 = time.strptime(t3,'%Y-%m-%d %H:%M:%S') print(t4) # 把元组转成时间戳 #description: 是time.localtime的反函数,不过由于格式化的原因,精度有所下降 #output sample: 1543801627.0 t5 = time.mktime(t4) print(t5) datetime模块# -*- coding: utf-8 -*- # author: inpurer(月小水长) # pc_type lenovo # create_date: 2018/12/3 # file_name: timetest.py # description: 月小水长,热血未凉 import datetime #通过datetime.datetime.now()可以获得当前日期时间的一个实例 #这个实例是一个datetime类对象而不是字符串 #虽然直接打印该实例输出的是一个字符串,只是调用datetime实现的__str__方法而已 t0 = datetime.datetime.now() print(t0) #print: 2018-12-03 12:55:49.905971 print(type(t0)) #print: <class 'datetime.datetime'> #然后就可以通过对象名.的方法输出各个时间信息,该信息是一个int类型 print(t0.year) #print: 2018 print(type(t0.year)) #print: <class 'int'> print(t0.month) print(t0.day) print(t0.hour) print(t0.minute) print(t0.second) 时间的存储,比较存储理论上我们可以通过拼接datetime.datetime.now()实例的各个时间变量来构建我们自己的想要时间,例如我们想要存储year-month-day这样的时间信息,我们可以这样做: import datetime t0 = datetime.datetime.now() #注意year/month/day都是int类型,不像java那样可以直接拼接字符串和数字 wanted_time = str(t0.year)+"-"+str(t0.month)+"-"+str(t0.day) 但是,这样做会有非常尴尬的问题:格式不统一,可能会出现下面这样的存储形式: 2018-1-12018-1-112018-11-12018-11-11…………….. 特别是在数据量非常庞大的时候,阅读起来非常费力,这是因为year/month/day这些都是int型,所以1就是1,不会显示成01,要实现对齐效果,必须还得字符串的格式化,所以,我们通常用的是time模块(其实datetime也有字符串的格式化,不过展开讲就太多了,不必要浪费这么多学习成本) import time t0 = time.localtime() wanted_time = time.strftime("%Y-%m-%d",t0) 比较就拿上面刚刚说的wanted_time来说,可以直接通过>、=、<这些符号来比较,因为wanted_time就是一个字符串。]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>Python</tag>
<tag>time</tag>
<tag>datetime</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Python 实现微信自动回复和群聊助手]]></title>
<url>%2F2018%2F12%2F01%2FPython%E5%AE%9E%E7%8E%B0%E5%BE%AE%E4%BF%A1%E8%87%AA%E5%8A%A8%E5%9B%9E%E5%A4%8D%E5%92%8C%E7%BE%A4%E8%81%8A%E5%8A%A9%E6%89%8B%2F</url>
<content type="text"><![CDATA[本文首发于我的简书https://www.jianshu.com/p/4b7b4f4fb0e4 本教程的作用零基础手把手教你打造一款微信机器人,包括好友聊天自动回复和群聊助手两个部分,零基础!话不多说,下面开始实战编码。 第一部分:好友聊天自动回复第一步,安装python环境。打开python官网https://www.python.org/downloads/,下载与你的电脑系统相匹配的python发行版本,推荐python3.5-python3.6,版本太高了可能有许多未知的bug,太低了兼容性不太好。 第二步,安装itchat库在命令行下输入pip install itchat完成安装 第三步,编写代码核心代码如下: #coding=utf8 import itchat # 当接收到的消息是Text,即文字消息 #注册re_msg的意义在于,告诉itchat每次有符合特定条件的消息,itchat要把消息作为参数,去调用re_msg。 @itchat.msg_register('Text') def text_reply(msg): #message:取出msg里面的文本消息 message = msg['Text'] # 回复给好友 replay = u'肖涛已在电脑上登陆网页微信,但暂时无法进行交流,可以给他发送电脑QQ消息哈' #主要是一些关键词设置 # if B in A 如果 A中有B的话 if u'干什么' in message: replay = u'在忙呢' elif u'逼' in message: replay = u'含有敏感词汇,请注意言辞' elif u'生气' in message: replay = u'生气对身体不好' elif u'?' in message: replay = u'哈哈,我也不知道' elif u'不理你' in message: replay = u'乖,忙完给你买糖吃' elif u'涛' in message: replay = u'他是我主人' elif u'厉害' in message: replay = u'不不不,辣鸡一个' elif u'你好' in message: replay = u'你好哇' elif u'好吧' in message: replay = u'再见' return replay #弹出扫码登录界面,参数这样设置的好处是短时间内退出程序,再次登录可以不用扫码 itchat.auto_login(hotReload=True) #开启自动回复 itchat.run() 以上代码都是本人亲自编写,如需转载请私信我。代码截至2018/11/30本人调试有效,最新的代码更新在我的github:auto_replay.py如有问题欢迎评论。 运行代码运行之后,会弹出一个二维码,用微信扫一扫登录网页版微信之后,这份代码就会接管你的消息通知。下面是一个简单的效果图 第二部分:群聊助手第一步是点对点的消息自动回复,本部分实现的是点对多、在群中的消息自动回复。请确认上一部分实现无误之后再来尝试第二部分,因为第二部分需要第一部分的环境配置做支撑。 编写代码 import itchat import requests def get_response(msg): apiUrl = 'http://www.tuling123.com/openapi/api' #改成你自己的图灵机器人的api 'key': 'ce697b3fc8b54d5f88c2fa59772cb2cf', # Tuling Key 'info': msg, # 这是我们发出去的消息 'userid': 'wechat-robot', # 这里可随意修改 } # 通过如下命令发送一个post请求 r = requests.post(apiUrl, data=data).json() return r.get('text') @itchat.msg_register(itchat.content.TEXT) #用于接收来自朋友间的对话消息 #如果不用这个,朋友发的消息便不会自动回复 def print_content(msg): return get_response(msg['Text']) #用于接收群里面的对话消息 @itchat.msg_register([itchat.content.TEXT], isGroupChat=True) def print_content(msg): return get_response(msg['Text']) itchat.auto_login(True) itchat.run() 接入图灵机器人打卡图灵机器人官网,http://www.tuling123.com/,注册账号,新建一个机器人,如下图把图中的apikey替换到代码里就行,如果你要用我的,我也无法拒绝,毕竟我的apikey也贴出来了。 运行效果 简要原理一但接收到信息,就会调用get_response()方法,把消息传给图灵机器人,然后图灵机器人把回复信息再返回给微信。 截至2018/11/30代码运行无误,最新更新在我的github:grouphandler.py如有问题请评论,如需转载请私信我。 后记本篇文章参考了我的两篇csdn博客https://blog.csdn.net/ygdxt/article/details/79766197https://blog.csdn.net/ygdxt/article/details/81101020在这里推荐两个python代码仓库:一个是PythonLearning,这里面有我学习python的课程学习资料、以及一些我实战编写的代码,另一个是PythonSpider,这里面主要是一些我写的python实现的爬虫。更多的请访问我的github,欢迎star,fork.另外欢迎关注微信公众号:inspurer 如果你觉得本篇文章不错,不妨打赏一下,谢谢。]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>Python</tag>
<tag>itchat</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Python 爬取学校教务系统]]></title>
<url>%2F2018%2F11%2F30%2Fpython%E7%88%AC%E5%8F%96%E5%AD%A6%E6%A0%A1%E6%95%99%E5%8A%A1%E7%B3%BB%E7%BB%9F%2F</url>
<content type="text"><![CDATA[写这个爬虫的缘由以前用java写过一个爬取学校的教务系统的爬虫 https://blog.csdn.net/ygdxt/article/details/81158321,最近痴迷Python爬虫,了解到许多强大的库,想再一次用学校的教务系统做下测试。这一次我首先想到的是新的教务系统,这个难度更大,因为有了验证码识别反爬,由于我是用的tessocr库识别验证码,(具体配置过程可以参考我之前的博客 python填坑之路:tesserocr配置)用Requests.get方法把验证码下载下来识别之后,同时因为我爬取网页是用的selenium做的模拟网页动作,这里就有一个同步性的问题,不能保证selenium请求网页上的验证码和requests请求的验证码是同一个,相当于selenium、requests分别请求了一次登陆网页,两个网页上的验证码显然是不同的。所以 怎么保证请求登录界面得到的网页上的验证码 和我们请求验证码服务器返回的验证码是同一个验证码是同一个是一个很迷人的问题, 我开始还以为可以从网页源代码上直接定位到这个验证码,结果显示这个验证码在登录界面的 的存在形式不是一个..png/jpg,而是通过src=“验证码服务器”来实现异步加载 同时,由于tessocr识别验证码的成功率可能只有50%,要提高验证率可能还要对接云打码,果断放弃了爬取新教务系统的想法,还是爬取原来的没有验证码的旧教务系统,其实新旧教务系统最大的区别就是登陆界面不一样,登陆之后都一样,貌似用了重定向ps:如果你对这个问题有什么好的解决办法,请不吝赐教 编码过程详细的代码解释就看注释吧,有什么问题欢迎交流 执行爬虫的主程序csu.py,里面有许多测试用的注释代码,就不删了from selenium import webdriver from selenium.webdriver.common.by import By from selenium.common.exceptions import TimeoutException from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.select import Select from config import * import time broswer = webdriver.Chrome() wait = WebDriverWait(broswer, 10) def search(): try: broswer.get("http://csujwc.its.csu.edu.cn/jsxsd/kscj/yscjcx_list") account = wait.until( EC.presence_of_element_located((By.CSS_SELECTOR, "#userAccount")) ) password = wait.until( EC.presence_of_element_located((By.CSS_SELECTOR, "#userPassword")) ) submit = wait.until( EC.element_to_be_clickable((By.CSS_SELECTOR, "#btnSubmit")) ) except TimeoutException: return search() #登录 account.send_keys(ACCOUNT) password.send_keys(PASSWORD) submit.click() #进入我的成绩界面 my_score = wait.until( EC.presence_of_element_located((By.CSS_SELECTOR,"body > div.wap > a:nth-child(3) > div")) ) my_score.click() #成绩和平均分 # my_rank = wait.until( # EC.presence_of_element_located((By.CSS_SELECTOR, "#LeftMenu1_divChildMenu > ul > li:nth-child(4) > a")) # ) # my_rank.click() # # rank = wait.until( # EC.presence_of_element_located((By.CSS_SELECTOR, "#dataList > tbody > tr:nth-child(2) > td:nth-child(3)")) # ) # #http://www.w3school.com.cn/cssref/selector_nth-child.asp nth-child(n)的用法 # average_score = wait.until( # EC.presence_of_element_located((By.CSS_SELECTOR, "#dataList > tbody > tr:nth-child(2) > td:nth-child(4)")) # ) # # print('您的平均成绩是:'+average_score.text+"\n排名:"+rank.text) #逐次展示 我的成绩八个子项 # css_selector = "#LeftMenu1_divChildMenu > ul > li:nth-child({0}) > a" # for i in range(8): # # 将滚动条移动到页面的顶部 # js = "var q=document.documentElement.scrollTop=0" # broswer.execute_script(js) # time.sleep(2) # # aviable_score = wait.until( # EC.presence_of_element_located((By.CSS_SELECTOR, css_selector.format(str(i+1)))) # ) # aviable_score.click() # # # #将滚动条移动到页面的底部 # for j in range(8): # js="var q=document.documentElement.scrollTop="+str(j*200) # broswer.execute_script(js) # time.sleep(1) #处理select https://www.cnblogs.com/imyalost/p/7846653.html yxcj = wait.until( EC.element_to_be_clickable((By.CSS_SELECTOR, "#LeftMenu1_divChildMenu > ul > li:nth-child(1) > a")) ) select_score_element = broswer.find_element_by_css_selector("#xnxq01id") select_score = Select(select_score_element) #得到下拉列表的所有子项 select_score_items = broswer.find_elements_by_css_selector("#xnxq01id option") select_score_items_text = [] for item in select_score_items: select_score_items_text.append(item.text) #print(item.text) scores_dic = {} for i in range(len(select_score.options)): #不加这两行会报错,原因: https://blog.csdn.net/ulebo/article/details/52128033 print("*****************************************************"+select_score_items_text[i]+ "*****************************************************") select_score_element = broswer.find_element_by_css_selector("#xnxq01id") select_score = Select(select_score_element) select_score.select_by_index(i) time.sleep(1) score_table = broswer.find_element_by_css_selector("#dataList") data = score_table.text.replace("+","") data = data.split("\n") datalist = [] for line in data: datalist.append(line.split()) scores_dic[select_score_items_text[i]] = datalist return scores_dic[select_score_items_text[0]] def main(): search() if __name__ =="__main__": main() ui.py程序的gui,直接运行这个就好,它会调用csu.py #coding=utf-8 import wx import wx.grid import csu class UI(wx.Frame): def __init__(self): wx.Frame.__init__(self,parent=None,title="成绩查询",size=(1050,560)) grid = wx.grid.Grid(self,pos=(10,0),size=(1050,500)) grid.CreateGrid(100,9) for i in range(100): for j in range(9): grid.SetCellAlignment(i,j,wx.ALIGN_CENTER,wx.ALIGN_CENTER) grid.SetColLabelValue(0, "序号") #第一列标签 grid.SetColLabelValue(1, "初修学期") grid.SetColLabelValue(2, "获得学期") grid.SetColLabelValue(3, "课程") grid.SetColLabelValue(4, "成绩") # 第一列标签 grid.SetColLabelValue(5, "学分") grid.SetColLabelValue(6, "课程属性") grid.SetColLabelValue(7, "课程性质") grid.SetColLabelValue(8, "获得方式") # 第一列标签 grid.SetColSize(0,50) grid.SetColSize(1,100) grid.SetColSize(2,100) grid.SetColSize(3,350) grid.SetColSize(4,50) grid.SetColSize(5,50) grid.SetColSize(6,50) grid.SetColSize(7,100) grid.SetColSize(8,100) grid.SetCellTextColour("NAVY") data = csu.search() data.remove(data[0]) print(data) for i,item1 in enumerate(data): for j,item2 in enumerate(item1): grid.SetCellValue(i,j,data[i][j]) pass app = wx.App() frame = UI() frame.Show() app.MainLoop() 想要运行代码,具体的配置过程请参考readme运行结果预览如图片不可加载,请点击https://blog.csdn.net/ygdxt/article/details/84591649 源代码地址https://github.com/inspurer/PythonSpider/tree/master/csu]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>Python</tag>
<tag>爬虫</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Python 爬取b站视频]]></title>
<url>%2F2018%2F11%2F25%2Fpython%E7%88%AC%E5%8F%96b%E7%AB%99%E8%A7%86%E9%A2%91%2F</url>
<content type="text"><![CDATA[python爬虫系列:上一篇python爬取图虫网图库今天突然来了兴趣想要爬取下载b站视频,话不多说,说干就干。 Usage下载仓库[email protected]:inspurer/PythonSpider.git 或者直接下载:https://github.com/inspurer/PythonSpider/tree/master/bilibili 替换随便打开一个b站的界面,比如将url复制到代码中去,运行代码,稍等一会儿,上述图中的视频就被下载下来了。 How to Code分析网页源码按f12浏览器开发者工具 ,通过一番审查,我们定位到视频的url在网页源代码的位置如下: window.__playinfo__={ "from":"local", "result":"suee", "quality":32, "format":"flv480", "timelength":408884, "accept_format":"flv720,flv480,flv360", "accept_description":["高清 720P","清晰 480P","流畅 360P"], "accept_quality":[64,32,15], "video_codecid":7, "video_project":true, "seek_param":"start", "seek_type":"offset", "durl":[{"order":1,"length":408884,"size":42782550,"ahead":"EhA=","vhead":"AWQAHv/hAB5nZAAerNlA2D3n//AoACfxAAADAAEAAAMAMA8WLZYBAAVo6+zyPA==", "url":"http://upos-hz-mirrorkodo.acgvideo.com/upgcxcode/48/61/45596148/45596148-1-32.flv?e=ig8euxZM2rNcNbRa7b4VhoMz7WhjhwdEto8g5X10ugNcXBlqNxHxNEVE5XREto8KqJZHUa6m5J0SqE85tZvEuENvNC8xNEVE9EKE9IMvXBvE2ENvNCImNEVEK9GVqJIwqa80WXIekXRE9IB5QK==&deadline=1543136253&dynamic=1&gen=playurl&oi=1862807981&os=kodo&platform=pc&rate=176800&trid=69ea1a81ac21448f9e2189ef479a2d6d&uipk=5&uipv=5&um_deadline=1543136253&um_sign=c479f3fd3075b359d0a04e5eb584ac55&upsig=1c05ca3838af92d2c1411cf3000e8345http://upos-hz-mirrorkodo.acgvideo.com/upgcxcode/48/61/45596148/45596148-1-32.flv?e=ig8euxZM2rNcNbRa7b4VhoMz7WhjhwdEto8g5X10ugNcXBlqNxHxNEVE5XREto8KqJZHUa6m5J0SqE85tZvEuENvNC8xNEVE9EKE9IMvXBvE2ENvNCImNEVEK9GVqJIwqa80WXIekXRE9IB5QK==&deadline=1543136253&dynamic=1&gen=playurl&oi=1862807981&os=kodo&platform=pc&rate=176800&trid=69ea1a81ac21448f9e2189ef479a2d6d&uipk=5&uipv=5&um_deadline=1543136253&um_sign=c479f3fd3075b359d0a04e5eb584ac55&upsig=1c05ca3838af92d2c1411cf3000e8345","backup_url":["http://upos-hz-mirrorcos.acgvideo.com/upgcxcode/48/61/45596148/45596148-1-32.flv?um_deadline=1543136253&platform=pc&rate=176800&oi=1862807981&um_sign=c479f3fd3075b359d0a04e5eb584ac55&gen=playurl&os=cos&trid=69ea1a81ac21448f9e2189ef479a2d6d"]}]} 最后的url就是我们想要的结果。如果在浏览器中查找不方便的话,我们可以把通过代码把网页源码输出到本地 response = requests.get(url='https://www.bilibili.com/video/av26522634', headers= self.getHtmlHeaders) print(response.status_code) if response.status_code == 200: print(response.text) 为了伪装成浏览器,我们需要在reqests添加Headers这个Headers需要我们去浏览器中手动获取切换到NetWork标签下,再选择Headers, self.getHtmlHeaders={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'zh-CN,zh;q = 0.9' } 这里只选择了几个关键的 解析得到视频地址根据上一步分析,我们得到了网页的源码,并在源码中定位到了视频地址,接下来,我们就用代码自动获取这个地址了 #用正则、json得到视频url;用pq失败后的无奈之举 pattern = r'\<script\>window\.__playinfo__=(.*?)\</script\>' result = re.findall(pattern, html)[0] temp = json.loads(result) #temp['durl']是一个列表,里面有很多字典 #video_url = temp['durl'] for item in temp['durl']: if 'url' in item.keys(): video_url = item['url'] 顺便获取下视频的名字: #用pq解析得到视频标题 doc = pq(html) video_title = doc('#viewbox_report > h1 > span').text() 然后组合返回下: return{ 'title': video_title, 'url': video_url } 下载视频通过在开发者工具中搜索关键词,比如上面得到的视频url,我们可以定位到在浏览器中真正下载视频的请求在哪然后把它的Headers添加到reqests中,就可以下载视频了 with open(filename, "wb") as f: f.write(requests.get(url=url, headers=self.downloadVideoHeaders, stream=True, verify=False).content) 愉快地观看本地视频如果你下载的视频在本地播放不了,请不要试图修改源代码中保存文件的格式由.flv改成.mp4,因为b站的视频本来就是flv格式的,需要用特殊的视频播放器播放,这里推荐一个无毒无害的KMPlayer,https://pan.baidu.com/s/1DBOaPGbdTXOvodbrZRhzmQ,提取码:fw0b 源代码工程所有源代码均已上传至github,https://github.com/inspurer/PythonSpider/tree/master/bilibili欢迎star,fork。如图片显示有问题请到csdn观看https://blog.csdn.net/ygdxt/article/details/84501500]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>Python</tag>
<tag>爬虫</tag>
<tag>b站</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Python 函数参数的填坑之路]]></title>
<url>%2F2018%2F11%2F22%2Fpython%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0%E7%9A%84%E5%A1%AB%E5%9D%91%E4%B9%8B%E8%B7%AF%2F</url>
<content type="text"><![CDATA[背景最近在看廖雪峰老师的python3教程之函数的参数受益匪浅,但是在实践的过程中,发现了一些不解之谜 两个错误import _thread import time def func1(x): while x: print(x) x = x -1 _thread.start_new_thread(function=func1,args=(5,),kwargs=None) time.sleep(6) 再看python3中start_new_thread()函数的声明 def start_new_thread(function, args, kwargs=None): 按照我们的理论,我们开启多线程的那句代码是完全没有问题的,可是事实上它报错: TypeError: start_new_thread() takes no keyword arguments 难道我们的理论有问题?带着这个疑问,我又遇到一个问题: import threading def func1(x): while x: print(x) x = x -1 threading.Thread(func1,(5,)).start() 再看python3中Thread类构造()函数的声明 def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None): 它居然又报错? AssertionError: group argument must be None for now 探讨过程(以下过程针对第二个错误,第一个错误道理类似)带着疑问,我看了Thread类的构造函数 def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None): """This constructor should always be called with keyword arguments. Arguments are: *group* should be None; reserved for future extension when a ThreadGroup class is implemented. *target* is the callable object to be invoked by the run() method. Defaults to None, meaning nothing is called. 。。。略 assert group is None, "group argument must be None for now" 。。。略 我们看到,第三行说明,本函数只接受关键字实参调用,所以我们之前的代码改成 import threading def func1(x): while x: print(x) x = x -1 threading.Thread(target=func1,args=(5,)).start() 就能顺利开启子线程了,那么它是如何实现只能接受关键字参数的呢?我们看到Thread类的构造函数定义中有一句这样的断言 assert group is None, "group argument must be None for now" 意思是,如果参数group为空,通过;如果非空,报错,并给出reasongroup argument must be None for now,如果我们按照之前的位置参数调用的话,由于group是第一个参数,一下在就被赋值,非空,抛出异常,这符合我们之前的实践。同时,我在网上搜集了许多资料,诸如修饰器之类的也能使函数只接受关键字参数 。 错误一探讨过程道理类似,在此不再赘述。 验证及结论编码 class MyThread: def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None): print('Thread sucess') def start_new_thread(function, args, kwargs=None): print('_thread sucess') MyThread() MyThread.start_new_thread(args=2,kwargs=3,function=1) 输出如下: Thread sucess _thread sucess 显而易见,我们之前所学的理论是正确的,只不过在具体的编码中,我们通过编码修改理论,使之看上去似乎和之前的理论相矛盾,千万不要被蒙蔽了。]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>Python</tag>
<tag>函数参数</tag>
</tags>
</entry>
<entry>
<title><![CDATA[罗素:我为什么而活]]></title>
<url>%2F2018%2F11%2F15%2F%E7%BD%97%E7%B4%A0-%E6%88%91%E4%B8%BA%E4%BB%80%E4%B9%88%E8%80%8C%E6%B4%BB%2F</url>
<content type="text"><![CDATA[中文译文对爱情的渴望,对知识的追求,对人类苦难不可遏制的同情心,这三种纯洁而无比强烈的激情支配着我的一生。这三种激情,就像飓风一样,在深深的苦海上,肆意地把我吹来吹去,吹到濒临绝望的边缘。 我寻求爱情,首先因为爱情给我带来狂喜,它如此强烈以致我经常愿意为了几小时的欢愉而牺牲生命中的其他一切。我寻求爱情,其次是因为爱情可以解除孤寂一—那是一颗震颤的心,在世界的边缘,俯瞰那冰冷死寂、深不可测的深渊。我寻求爱情,最后是因为在爱情的结合中,我看到圣徒和诗人们所想像的天堂景象的神秘缩影。这就是我所寻求的,虽然它对人生似乎过于美好,然而最终我还是得到了它。 我以同样的热情寻求知识,我渴望了解人的心灵。我渴望知道星星为什么闪闪发光,我试图理解毕达哥拉斯的思想威力,即数字支配着万物流转。这方面我获得一些成就,然而并不多。 爱情和知识,尽其可能地把我引上天堂,但是同情心总把我带回尘世。痛苦的呼唤经常在我心中回荡,饥饿的儿童,被压迫被折磨者,被儿女视为负担的无助的老人以及充满孤寂、贫穷和痛苦的整个世界,都是对人类应有生活的嘲讽。我渴望减轻这些不幸,但是我无能为力,而且我自己也深受其害。 这就是我的一生,我觉得值得为它活着。如果有机会的话,我还乐意再活一次。 英文原文《What I Have Lived For》 by Bertrand Russell Three passions, simple but overwhelmingly strong, have governed my life: the longing for love, the search for knowledge, and unbearable pity for the suffering of mankind. These passions, like great winds, have blown me hither and thither, in a wayward course, over a great ocean of anguish, reaching to the very verge of despair. I have sought love, first, because it brings ecstasy - ecstasy so great that I would often have sacrificed all the rest of life for a few hours of this joy. I have sought it, next, because it relieves loneliness–that terrible loneliness in which one shivering consciousness looks over the rim of the world into the cold unfathomable lifeless abyss. I have sought it finally, because in the union of love I have seen, in a mystic miniature, the prefiguring vision of the heaven that saints and poets have imagined. This is what I sought, and though it might seem too good for human life, this is what–at last–I have found. With equal passion I have sought knowledge. I have wished to understand the hearts of men. I have wished to know why the stars shine. And I have tried to apprehend the Pythagorean power by which number holds sway above the flux. A little of this, but not much, I have achieved. Love and knowledge, so far as they were possible, led upward toward the heavens. But always pity brought me back to earth. Echoes of cries of pain reverberate in my heart. Children in famine, victims tortured by oppressors, helpless old people a burden to their sons, and the whole world of loneliness, poverty, and pain make a mockery of what human life should be. I long to alleviate this evil, but I cannot, and I too suffer. This has been my life. I have found it worth living, and would gladly live it again if the chance were offered me.]]></content>
<categories>
<category>励志</category>
</categories>
<tags>
<tag>励志</tag>
<tag>鸡汤</tag>
</tags>
</entry>
<entry>
<title><![CDATA[李开复:追随我心]]></title>
<url>%2F2018%2F11%2F14%2F%E6%9D%8E%E5%BC%80%E5%A4%8D-%E8%BF%BD%E9%9A%8F%E6%88%91%E5%BF%83%2F</url>
<content type="text"><![CDATA[并不很久的以前,也就在1979年到1980年间,在哥伦比亚大学,两个政治科学系大一的新生,在课堂上总是没精打采。其中一个是来自台湾的华裔,喜欢窝在教室左后方的一隅,听得无趣,索性呼呼大睡。这个男孩叫李开复,此君并非厌学,而是对政治科学越来越不感兴趣。蹉跎到大二下学期,他终于决定快刀斩乱麻——转系,改学自己感兴趣的计算机。 兴趣是什么?兴趣就意味着天赋。李开复在计算机系如鱼得水,左右逢源,两年后毕业,成绩居全系之首。这样的学生用不着按部就班。在教授的推荐下,李开复进入在计算机领域独领风骚的卡内基•梅隆大学,直接攻读博士。计算机学院的院长找他谈话,劈头就问:“读博士的目的是什么?”李开复大声答:“我从大学带走的将是一篇改变世界的、顶尖的博士论文。”院长予以纠正,说:“你从这儿带走的最有价值的东西,不是一篇论文,而是你分析、思考的能力,研究、发现真理的经验,以及科学家的胸怀。这样,当你有一天改变研究方向,依然可以在任何一个新的领域出类拔萃。”李开复选定语音识别为攻读方向,经过一年“热恋”,他发现专家系统其冷如冰,远不如统计学有情有义。李开复决心“移情别恋”。他担心导师发怒,谁知得到的回答竟是:“开复,你对专家系统和统计的观点,我是不赞同的,但我可以支持你用统计的方法去做,因为我相信科学没有绝对的对错,我们都是平等的。而且,我更相信一个富有激情的人可以找到更好的解决方案。”李开复从导师的大度悟到科学的真谛,他全力以赴,放手一搏。3年过去了,李开复的研究成果及博士论文,引发了那年语音世界最大的冲击波。26岁的李开复功成名就,成为卡内基•梅隆大学最年轻的副教授。天之骄子,有尊严,有地位,有课题,有经费,出任大公司顾问,飞赴各地讲学,包括去他的祖籍之邦、魂之所系的祖国大陆。 “让世界因你而不同!”这是李开复埋在心底多年的梦想。1990年,苹果公司的一个邀请电话让李开复开始审视自己:“开复,你是想一辈子写一堆像废纸一样的学术论文,还是想真正地改变世界?”面对苹果公司的召唤,李开复旋即做出回应,走出象牙塔,加盟“改变世界”的大军。在苹果公司,李开复感受到了从纸上谈兵转入实战的无穷乐趣。1995年,33岁的李开复出任苹果公司的副总裁。 但是他仍然不满足,依然要跳槽,因为硅谷的另一家公司SGI发出了更有诱惑力的邀请——“你想做什么,然后我们根据你的兴趣对公司进行改组。”不是他们缺什么人才,让你去填补,而是诚恳地询问你需要什么平台,以便为你量身搭建。这样的机遇,李开复岂能错过!双方一拍即合, 1996年7月,李开复跳槽去了SGI。李开复奉行“自己设计自己”的人生信条,怎奈SGI是一家硬件公司,开复的长处却在软件开发,这就等于在篮球场上跑马,任是赤兔、骅骝,也撒不开四蹄。日复一日,李开复萌生去意。对于下一个选择,他立下两条标准:一是做软件,二是去中国。 机会来了。其实机会无处不在,就看你有没有做好准备。彼时,比尔•盖茨创立的微软王国要把触角伸向中国,李开复成为它的不二人选。时间:1998年金秋;职务:微软中国研究院院长。李开复在中国市场的开拓,值得写部书来描述,那是一种完全不同的创新理念、绝对领先的科学技术在神州大地生根发芽。微软只是起用了一个人,就开拓了中国市场;李开复只是“追随我心”,就一跃成为微软王国的副总裁。在你我想来,这该是李开复的最后一站。在微软占据高位,与比尔•盖茨亲密共事,坐拥财富和风光,“花迎喜气皆知笑,鸟识欢心亦解歌”。人生至此,夫复何求?李开复不这么想,他后来回忆:“我如同一部庞大机器上的零件,在中规中矩、没有任何发挥空间的环境下运行着。这是一个随时随地都可以被替换的光鲜零件。那种价值的缺失感以及精神上的落寞占据了我的内心。”微软既然已无成长空间,那就走吧!到哪儿去?他相中了Google。但他清醒地意识到,管理更多的人马,不是自己的所爱,他渴望从无到有的创新,而不是经营一个巨无霸。于是,在2009年9月,李开复又一次选择潇洒地离去。向总部递交辞呈之际,Google高管艾伦•尤斯塔斯试图用更优厚的条件予以挽留。李开复真诚地说:“我的人生还有一个缺憾没有实现,现在得去弥补。我可能创办一家‘创新工场’,和中国青年一起创造新的技术奇迹。” 如今,李开复正在按照他本人的意愿,在神州大地进行“创新工场”试验。他会成功吗?我想这是毫无疑问的,也是次要又次要的,那么,最主要的一点是什么呢?诚如他自己所言:“人生在世时间非常短,如果你总是不敢做想做的事情,那么一生过去了,你留下来的只有悔恨,只有懊恼。”“我步入丛林,因为我希望生活得有意义,我希望活得深刻,并汲取生命中所有的精华,然后从中学习,以免让我在生命终结时,才发现自己从来没有活过。”]]></content>
<categories>
<category>励志</category>
</categories>
<tags>
<tag>励志</tag>
<tag>励志故事</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Python 自动下载图虫网图库]]></title>
<url>%2F2018%2F11%2F14%2Fpython%E8%87%AA%E5%8A%A8%E4%B8%8B%E8%BD%BD%E5%9B%BE%E8%99%AB%E7%BD%91%E5%9B%BE%E5%BA%93%2F</url>
<content type="text"><![CDATA[如何使用下载工程源码点击下载或者git bash;git clone [email protected]:inspurer/PythonSpider.git 下载相关依赖在命令行下依此输入 pip install requests pip install pyquery 打开图虫网选择你喜欢的图库链接,比如https://tuchong.com/4293835/23849565/复制并替换到tuchong_gallery.py代码里面的gallery_url,解释一下这个链接的作用,前一个数字串是作者的id,后一个数字串是作者该图库的id注意,在打开这个图库时,复制地址前最好不要左右浏览 运行tuchong_gallery.py你就可以看到在下载这个图库的图片了图库保存在工程目录下,文件夹名为作者和图库的id每一张图片保存在该文件夹下,格式为:imageid.jpg 计划更新增加自动搜索]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>Python</tag>
<tag>爬虫</tag>
</tags>
</entry>
<entry>
<title><![CDATA[小程序json.parse错误]]></title>
<url>%2F2018%2F11%2F14%2F%E5%B0%8F%E7%A8%8B%E5%BA%8Fjson-parse%E9%94%99%E8%AF%AF%2F</url>
<content type="text"><![CDATA[错误详情今天查看上线的微信小程序后台,发现了一个这样的错误: Unexpected token in JSON at position 52; at pages/send/send onShow function; at api request success callback function 于是我打开调试工具查看源代码并且调试:VM792:1 thirdScriptError Unexpected token in JSON at position 52;at pages/send/send onShow function; at api request success callback function SyntaxError: Unexpected token in JSON at position 52 at JSON.parse (<anonymous>) at success (http://127.0.0.1:60162/appservice/pages/send/send.js:130:35) at http://127.0.0.1:60162/appservice/utils/bmob.js:2293:37 at wrappedResolvedCallback (http://127.0.0.1:60162/appservice/utils/bmob.js:2219:48) at http://127.0.0.1:60162/appservice/utils/bmob.js:2171:34 at Object._.each._.forEach [as _arrayEach] (http://127.0.0.1:60162/appservice/utils/underscore.js:161:17) at Bmob.Promise.resolve (http://127.0.0.1:60162/appservice/utils/bmob.js:2170:18) at wrappedResolvedCallback (http://127.0.0.1:60162/appservice/utils/bmob.js:2228:37) at http://127.0.0.1:60162/appservice/utils/bmob.js:2171:34 at Object._.each._.forEach [as _arrayEach] (http://127.0.0.1:60162/appservice/utils/underscore.js:161:17) 果不其然,小程序已然上线,这个错误一定不能忍 调试过程通过错误信息定位到出错的代码通过上面的报错信息:at success (http://127.0.0.1:60162/appservice/pages/send/send.js:130:35)定位到出错的代码是在130行:var jsonB = JSON.parse(jsonA); 上网浏览查询相关资料网上的说法不一而足,实在不知道该听信哪家之言不过都集中在json文件不能有注释、json字符串url有误、json字符串有特殊字符 定位原因排除了几种错误后还没有解决问题,有点心灰意冷,尝试着输出json字符串中的每一个字符 51 "。" 52 " " 53 "2" 等等,换行符确是是个特殊字符(ps,在js里面\r是回车符,\n是换行符,)(在小程序中,我这个jsonA是包含用户的键盘输入信息的) 解决办法jsonA = jsonA.replace('\n','') 后话小程序的预览可以查看: 点击查看小程序的所有源代码: github地址]]></content>
<categories>
<category>小程序</category>
</categories>
<tags>
<tag>小程序</tag>
<tag>json</tag>
</tags>
</entry>
<entry>
<title><![CDATA[【持续更新】hexo next主题优化手册]]></title>
<url>%2F2018%2F11%2F11%2Fhexo-next%E4%B8%BB%E9%A2%98%E4%BC%98%E5%8C%96%2F</url>
<content type="text"><![CDATA[前言开此贴的原因前几天博客崩了,重新搭建了这个博客站点。特开此贴记录next主题优化过程中遇到的问题,希望对大家有所帮助。 一些说明前期相关的Hexo安装、本地/远程部署教程可百度在此不再赘述。基于hexo-next v5.1.4,向上兼容,向下兼容性不确定,特此声明。我的博客本地根目录是D:\hexoblog站点配置文件全路径是D:\hexoblog\_config.ymlnext主题文件全路径是D:\hexoblog\themes\next\_config.yml hexo常见操作hexo new "postName" #新建文章hexo new page "pageName" #新建页面hexo clean #清除部署緩存hexo n == hexo new #新建文章hexo g == hexo generate #生成静态页面至public目录hexo s == hexo server #开启预览访问端口(默认端口4000,可在浏览器输入localhost:4000预览)hexo d == hexo deploy #将.deploy目录部署到GitHubhexo g -d #生成加部署hexo g -s #生成加预览 next主题优化next风格选择next有四种风格,在站点配置文件搜索字段Scheme Settings可以看到, # Scheme Settings # --------------------------------------------------------------- # Schemes #scheme: Muse #scheme: Mist #scheme: Pisces scheme: Gemini 我这里用的是四种:Gemini next菜单设置比如可以看到我的主页有首页、留言、分类、归档、标签等菜单,在站点配置文件下搜索menu:,可以看到 menu: home: / || home about: /about/ || user message: /message/ || comment tags: /tags/ || tags categories: /categories/ || th archives: /archives/ || archive #schedule: /schedule/ || calendar #sitemap: /sitemap.xml || sitemap #commonweal: /404/ || heartbeat home就是首页;message就是留言…一开始只有首页和归档,其余的需要我们手动创建,在站点根目录下打开命令行,输入hexo new page "about"并在主题配置文件menu:字段处取消对about的注释重新部署我们就可以看到主页有关于这个菜单了,其他的类似,修改D:\hexoblog\source\about\index.md,就可以修改关于界面了about: /about/ || user中的user是指关于菜单附件的图标用的是图标库里面名为user的图标 添加萌妹子动图在根目录下打开命令行输入npm install --save hexo-helper-live2d 修改站点配置文件(注意不是主题配置文件)在末尾加入: live2d: enable: true scriptFrom: local model: scale: 1 hHeadPos: 0.5 vHeadPos: 0.618 display: superSample: 2 width: 150 height: 300 position: right hOffset: 0 vOffset: -20 mobile: show: false react: opacityDefault: 0.5 opacityOnHover: 0. 实现文章首页”分类于”、”阅读次数”等效果效果图如下: 在根目录下打开命令行依次输入以下命令: npm install hexo-wordcount --save npm uninstall hexo-generator-index --save npm install hexo-generator-index-pin-top --save 打开主题配置文件打开相关开关: post_wordcount: item_text: true wordcount: true min2read: true totalcount: true 打开…/themes/next/layout/_macro/post.swig文件把里面的代码用下面的代码替换:点击下载 打开…/themes/next/languages/zh-Hans.yml文件搜索post字段,添加一行comments: 评论数,注意其余的不要改 设置某篇文章置顶前面的流程走完后,只需要在写文章的时候在文章前面加入top: true或者top: 100(100只是个例子,数字越大越靠前),就能实现置顶效果了 常见错误本地预览和同时发布到远程的浏览结果不一致这是由缓存造成的,需要先hexo clean,再hexo g -d部署到远程 markdown高级语法插入连续多行的代码块按一个tab键,然后贴代码,保证每一行代码前都要额外的tab键,同时最前面空一行。实现效果可见本问前面插入的连续行代码 设置文字大小和颜色和居中效果hello,world! hello,world! hello,world! hello,world! hello,world!上面的效果需要在markdwon中的代码是这样的: hello,world! <font color="#FF0000"> hello,world! </font> <font size=5> hello,world! </font> <font size=5 color="#FF0000">hello,world! </font> <center>hello,world!</center> 插入表格效果图: 左对齐标题 右对齐标题 居中对齐标题 短文本 中等文本 稍微长一点的文本 稍微长一点的文本 短文本 中等文本 markdown代码如下: | 左对齐标题 | 右对齐标题 | 居中对齐标题 | | :------| ------: | :------: | | 短文本 | 中等文本 | 稍微长一点的文本 | | 稍微长一点的文本 | 短文本 | 中等文本 | 感谢赞助所有赞赏过本站的人: 点击查看]]></content>
<categories>
<category>hexo</category>
</categories>
<tags>
<tag>hexo</tag>
<tag>next</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Windows下操作POP3]]></title>
<url>%2F2018%2F11%2F10%2FWindows%E4%B8%8B%E6%93%8D%E4%BD%9CPOP3%2F</url>
<content type="text"><![CDATA[Windows10下开启telnet服务在自学《计算机网络-自顶向下方法》这本书中,telnet这个服务命令出现了好多次, 开始在Ubuntu 12.0终端下输入telnet是有正确响应的,但是在windows 10命令行下输入提示找不到该命令,直到今天我才发现该服务在window 1o下是默认关闭的,需要手动打开开启步骤如下 1.用小娜以关键词功能找到开启和关闭Windows功能其实不一定要这样操作,找到开启和关闭Windows功能即可 2.勾选Telnet客户端并确定然后就可以愉快地在windows10玩耍telnet了 Windows下操作POP3pop3是一个邮件访问协议 1.在cmd下输入telnet pop3.163.com 110登录到qq的POP3服务器的110端口2.依次输入user csu_xiaotao和pass xxxxxxxxx登录到自己的邮箱需要注意的是,xxxxxxxxx是邮箱的授权码,不是登录密码 3.然后是一些常见的pop3命令(大小写敏感)1.list列出所有的收到的邮件,特别的`list n’列出第n封邮件其响应格式如下:n m其中n为第n封邮件,m为第n封邮件的字节大小 2.retr n下载第n封邮件其响应格式如下: 采用了特殊的编码格式,我们可能看不懂 3.dele n删除第n封邮件4.uidl n返回第n封邮件的唯一标识5.quit退出注意+OK代表操作成功;-ERR代表操作失败 图片之前是用的 MarkDown 图床,现在挂了,图片又找不到了。。。]]></content>
<categories>
<category>计算机网络</category>
</categories>
<tags>
<tag>pop3</tag>
<tag>telnet</tag>
</tags>
</entry>
<entry>
<title><![CDATA[打卡微信小程序]]></title>
<url>%2F2018%2F11%2F07%2F%E6%89%93%E5%8D%A1%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F%2F</url>
<content type="text"><![CDATA[这学期受某人所托,给学院做了一款打卡小程序。其效果如下: 一个类似论坛的社区,可发帖、评论、回复。 打卡可换算积分,一天只能打卡一次,且有今日打卡排行榜实时展示。 跑步也可换算积分,换算的规则男女有别。 这个小程序的上线成本比较高,需要营业执照,还有因为论坛的存在,上线之后还需要工信部的备案资质,否则不予更新代码,所以我已经停止对它的维护了。开源这个项目的代码: github地址,欢迎star、fork!!! 今天我主要讲述其中的打卡部分的制作,为了后期维护,我已经单独把这部分做成一个小程序,欢迎体验。 talk is cheap,show the code. 核心代码punch.jsvar app = getApp(); var date; var allowlog = 1; var Bmob = require('../../utils/bmob.js'); Page({ /** * 页面的初始数据 */ data: { newList: [], }, btn_click: function(e){ if (allowlog == 1){ allowlog = 0; wx.getStorage({ key: 'user_id', success: function (res) { var user_id = new Bmob.User(); user_id.id = res.data; wx.getStorage({ key: 'my_nick', success: function (ress) { var mydate = new Date(); var year = mydate.getFullYear(); var month = mydate.getMonth() + 1; var day = mydate.getDate(); var date = year + "年" + month + "月" + day + "日"; var hour = mydate.getHours(); //获取当前小时数(0-23) var minute = mydate.getMinutes(); //获取当前分钟数(0-59) var second = mydate.getSeconds(); //获取当前秒数(0-59) var time = hour + "时" + minute + "分" + second + "秒"; var avatar = wx.getStorageSync("my_avatar"); var Punch = Bmob.Object.extend("punch"); var punch = new Punch(); var me = ress.data; var query = new Bmob.Query(Punch); query.equalTo("nickname", me); query.equalTo("date", date); // 查询所有数据 query.find({ success: function (results) { console.log("共查询到 " + results.length + " 条记录"); if (results.length == 0) { if (hour >= 6) { if (hour < 8) { var intger; if (hour < 7) { if (minute <= 20) { intger = 3; } else if (minute <= 40) { intger = 2.5; } else { intger = 2; } } else if (hour < 8) { if (minute <= 20) { intger = 1.5; } else if (minute <= 40) { intger = 1; } else { intger = 0.5; } } wx.showToast({ title: '打卡成功+' + intger + "分", icon: 'success' }) wx.getStorage({ key: 'my_username', success: function (ress) { if (ress.data) { var my_username = ress.data; wx.getStorage({ key: 'user_openid', success: function (openid) { var openid = openid.data; var user = Bmob.User.logIn(my_username, openid, { success: function (users) { var score = users.get('score'); score = score + intger; users.set('score', score); users.save(null, { success: function (user) { }, error: function (error) { console.log(error) } }); } }); }, function(error) { console.log(error); } }) } } }) punch.set('nickname', me); punch.set('user_id', user_id); punch.set('date', date); punch.set('avatar', avatar) punch.set('time', time); console.log(me, user_id); punch.save(null, { success: function (result) { console.log('success'); allowlog = 1; }, error: function (result, error) { console.log(result, error, "failure") } }) } else { wx.showToast({ title: '已过打卡时间', icon: 'loading' }) } } else { wx.showToast({ title: '还没到打卡时间', icon: 'loading' }) } } else { allowlog = 1; wx.showToast({ title: '重复打卡', icon: 'loading' }) } }, error: function (error) { console.log("查询失败"); } }); } }) }, }) } else{ wx.showToast({ title: '点的太快了', icon: 'loading' }) } }, tempData: function () { var that = this; var Punch = Bmob.Object.extend("punch"); var query = new Bmob.Query(Punch); var mydate = new Date(); var year = mydate.getFullYear(); var month = mydate.getMonth() + 1; var day = mydate.getDate(); var date = year + "年" + month + "月" + day + "日"; query.equalTo("date", date); query.limit(100); var results = []; query.find({ success: function (result) { for (var i = 0; i < result.length; i++) { console.log('共有打卡记录:', result.length) var object = result[i]; object.set('time', object.createdAt.substring(11, 19)); object.set('rank', i + 1); results[i] = object; } console.log(results); that.setData({ list: results }); } }) }, onLoad: function () { this.tempData(); }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, /** * 生命周期函数--监听页面显示 */ onShow: function () { }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { this.tempData(); wx.stopPullDownRefresh(); }, onShareAppMessage: function () { return { title: '快来打卡赢积分', imageUrl: '../../static/images/tao.png' } }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { } }) pun.wxml<view class="title">今日打卡榜</view> <view class="item-box"> <view class="items"> <view wx:for="{{list}}" wx:key="{{index}}" class="item"> <view data-index="{{index}}" class="inner txt"> <i>{{item.rank}}</i> <image class="item-icon" mode="widthFix" src="{{item.avatar}}"></image> <i> {{item.nickname}}</i> <span class="item-data"> <i class="rankpace"> 打卡时间:{{item.time}}</i> <!-- <span class="rankxin">{{item.xin}}</span> --> </span> </view> </view> </view> </view><!--pages/ranking/ranking.wxml--> <button class="circle" bindtap="btn_click">开始打卡</button> punch.csspage { background: #fff; padding: 0 0rpx 0; width: 100%; height: 100%; box-sizing: border-box; background-size: cover; background-image: url(http://bmob-cdn-21956.b0.upaiyun.com/2018/11/08/e16028434063466d80d9d79f281ce145.jpg); } /* pages/leftSwiperDel/index.wxss */ view{ box-sizing: border-box; } .item-box{ width: 700rpx; height: 10rpx; margin: 0 auto; padding:40rpx 0; } .title{ margin-top: 12px; font-size: 20px; height: 12px; text-align: center; } .items{ width: 100%; } .item{ position: relative; border-top: 2rpx solid #eee; height: 120rpx; line-height: 120rpx; overflow: hidden; } .item:last-child{ border-bottom: 2rpx solid #eee; } .inner{ position: absolute; top:0; } .inner.txt{ background-color: #fff; width: 100%; z-index: 5; padding:0 10rpx; transition: left 0.2s ease-in-out; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; } .item-icon{ width: 64rpx; height: 64rpx; vertical-align: middle; margin-right: 16rpx; margin-left:13px; border-radius:50%; } .item-data{ float: right; margin-right:5%;} .rankpace{ color: #87CEFA; } .circle{ right: 35px; bottom: 35px; width: 110px; background-color: #87CEFA; height: 110px; padding-top: 28px; color: white; background-size: cover; position: fixed; z-index: 9999; font-size: 20px; text-align: center; border: 0 solid #ffffff; border-radius: 500px; box-shadow: 4px 1px 1px #cccccc; } 后话本小程序已上线,欢迎体验。可以扫描最上方的小程序码,也可以在微信搜索一见打卡 此小程序参考了我以前的代码仓库:https://github.com/inspurer/CampusPunchcard欢迎star,fork如果你也想开发一款这样的小程序,从代码到上线,欢迎联系[email protected],同时欢迎关注微信公众号: 月小水长]]></content>
<categories>
<category>小程序</category>
</categories>
<tags>
<tag>打卡</tag>
</tags>
</entry>
<entry>
<title><![CDATA[基于opencv人脸识别的员工考勤系统]]></title>
<url>%2F2018%2F09%2F25%2F%E5%9F%BA%E4%BA%8Eopencv%E4%BA%BA%E8%84%B8%E8%AF%86%E5%88%AB%E7%9A%84%E5%91%98%E5%B7%A5%E8%80%83%E5%8B%A4%E7%B3%BB%E7%BB%9F%2F</url>
<content type="text"><![CDATA[WorkAttendanceSystem一个基于opencv人脸识别的员工考勤系统,作者某双一流A类大学里的二流学生,写于2018/09/,python课设期间。 工程简介项目结构是V1.0版本的,V2.0的介绍请看文末更新版块项目结构mainui.py是主界面,调用face_img_register.py和face_recognize_punchcard.py其中face_img_register.py是录入人脸信息,face_recognize_punchcard.py是刷脸考勤face_feature_storage.py属于鸡肋文件,没什么用,舍不得删,毕竟有点参考价值。face_recognize_punchcard_lib.py和face_recognize_punchcard.py本质上差不多,但是前者是给face_img_register.py专有的依赖。防止录入两个同样的人脸建不同数据库的风险。 运行效果1. 主界面2. 人脸录入3. 刷脸考勤 其余的就不多做展示了,有什么问题欢迎[email protected]联系 更新V1.0版本2018/9/23更新mainui.py–>myapp.pyface_recognize_punchcard_lib.py等鸡肋文件放到useless文件夹里运行效率显著提高 2018/9/25更新解决同步性问题,新录入的人脸能立即被识别代码的运行速度少许下降 V2.0版本1. 全新设计的UI,更人性化的操作 2. 数据更加安全,用户不可见人脸数据和签到日志全部保存在inspurer.db数据库文件里,更加安全;而且对人脸数据进行了压缩,更加小巧。 3. 注意事项 打开摄像头时请左右晃动一下人脸,确保人脸识别开始。 人脸识别时做了拒绝处理,多张人脸时,只取距离屏幕最近的人脸。 新建录入时会自动录入十张人脸照片,也可手动点击完成录入立即完成,之后就会计算人脸数据并存储到数据库中,左边的信息栏会有相应的信息打印。 开始签到后,如不点击结束签到,就会一直对屏幕前的人脸进行签到,签到状态分三种,未识别的人脸,签到成功,签到成功但是迟到了(9.00后签到),重复签到(此时签到日志不会写入到数据库。 为确保程序稳定性,每一个菜单里的按钮尽量成对操作。 Thanks for your attention;can you fork it if helping you? Thanks again!CopyRight [email protected];send me for allowance if you want to transmit it 源代码地址github]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>人脸识别</tag>
</tags>
</entry>
<entry>
<title><![CDATA[数据结构之单链表]]></title>
<url>%2F2018%2F09%2F12%2F%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B9%8B%E5%8D%95%E9%93%BE%E8%A1%A8%2F</url>
<content type="text"><![CDATA[从今天起开始数据结构系列的分享,今天分享的是单链表。单链表大概是大概是每个数据结构初学者的必经之路,下面结合一个小小的工程来深入学习单链表的使用–简易客户管理系统。ps:如果还不清楚单链表是什么的小伙伴自行百度,在此不在赘述 #项目结构增删改查,增、删、改这三个部分同时包含了将变动后的信息写入到文件中的操作 #代码编写 ##项目基础代码俗话说得好,“万丈高楼平地起”,先来编写项目的预定义代码部分,主要是头文件包含、结构体定义、全局变量定义等 ###头文件包含#include<stdio.h> //C程序基础库#include<stdlib.h> //包含函数exit()#include<string.h> //包含函数strcmp() ###结构体定义 typedef struct item{ char name[20]; //保存客户姓名 char gender[20]; //保存客户性别 int age; //保存客户年龄 char tel[20]; //保存客户号码} guest;结构体定义不要多说了哈,这里typedef...guest是给结构体item起别名的意思,也就是struct item在这个源文件里面等价于guest typedef struct node { guest data; //数据域 struct node next; //指针域} link;这里是给指向结构体node的指针起别名 ###全局变量定义link T;//头指针这个头指针T是整个系统的索引,六个模块共有一个,虽然有尽量少定义全局变量的原则,但这里的全局变量T可以避免各个函数间复杂的参数传递问题,牺牲了空间,换取了运行时间的减少;同时要注意我在后面对T的初始化代码 //初始化头指针T=(link)malloc(sizeof(struct node));T->next = NULL;这里并没有给T安排数据域,T不是第一个存储客户信息的节点指针,T->next才是,初始化头指针时还没有存储客户信息的结点加入,所以T->next=NULL;,这是一个编程者应该养成的好习惯;为什么不给T安排数据域呢,这里主要考虑到后面的删除模块的编写,我们知道,删除一个结点,要先找到这个结点的前驱指针p和后驱指针q,然后p->next = q->next;,如果给T安排数据域的话,T的前驱是什么呢?就算不用上面我说的那套删除逻辑,用if...else...语句和另外一套逻辑完成对T的删除,代码明显复杂些。 ##项目核心代码 ###一、加载文件代码如下 void init() { link p,s; FILE *fp; int i = 0; s = p=(link)malloc(sizeof(struct node)); p->next = NULL; if((fp=fopen(“1.txt”,”r”))==NULL) { printf(“load error!”); exit(1); } while(!feof(fp)) { fscanf(fp,”%s\t%s\t%d\t%s\t\n”,p->data.name,p->data.gender,&p->data.age,p->data.tel); i++; if(i!=1) { s->next = p; s=p; } else{ T->next = p; } p=(link)malloc(sizeof(struct node)); p->next = NULL; } printf(“总人数i=====%d\n”,i); if(fclose(fp)) { printf(“Can’t close the file!\n”); exit(1); }}介绍下代码逻辑,新开辟内存空间,并使s、p指向它,打开文件,如果文件指针没有到文件尾,将从文件读取到的一个客户信息赋给p的数据域,如果是读取第一个客户信息,将p指向的结点连在头指针T后面,否则,将p连在s后面,因为这个时候s是p的前驱指针,连接成功后将p赋值给s,p又指向一个新开辟的结点…图示: ###二、增加客户代码如下: //添加void create() { link p,s; FILE *fp; int yn; s=T; while(s->next!=NULL) { s=s->next; } do { p=(link)malloc(sizeof(struct node)); printf(“请输入客户姓名:\n”); scanf(“%s”,p->data.name); printf(“请输入客户性别:\n”); scanf(“%s”,p->data.gender); printf(“请输入客户年龄:\n”); scanf(“%d”,&p->data.age); printf(“请输入客户联系方式:\n”); scanf(“%s”,p->data.tel); p->next=NULL; s->next=p; s=p; if((fp=fopen(“1.txt”,”at”))==NULL) { printf(“write error!\n”); exit(0); } printf(“写了一次\n”); fprintf(fp,”%s\t%s\t%d\t%s\n”,p->data.name,p->data.gender,p->data.age,p->data.tel); if(fclose(fp)) { printf(“can’t close the file!\n”); exit(0); } printf(“添加成功!\n”); printf(“是否继续添加请输入0或1:”); scanf(“%d”,&yn); } while(yn);}代码逻辑很简单,新增结点,并连在尾节点后面,同时写入文件,如果前一片代码看懂了,这不是什么大问题… ###三、删除客户代码如下 //删除int del() { link p,q; FILE *fp; char mod[25]; printf(“请输入需要删除的客户名称:\n”); scanf(“%s”,mod); p=T; while(p->next!=NULL&&strcmp(p->next->data.name,mod)!=0) p=p->next; if(p->next==NULL) { printf(“并无此人!\n”); return 0; } q = p; p = p->next; q->next = p->next; delete(p); printf(“删除成功!\n”); if((fp=fopen(“1.txt”,”wt”))==NULL) { printf(“error!\n”); exit(0); } p=T->next; while(p!=NULL) { printf(“%s”,p->data.name); fprintf(fp,”%s\t%s\t%d\t%s\t\n”,p->data.name,p->data.gender,p->data.age,p->data.tel); p = p->next; } if(fclose(fp)) { printf(“can’t close the file!\n”); exit(1); }}模块三、四、五、六道理类似,不再赘述附上代码地址:github 欢迎star如有疑问,欢迎进群讨论:]]></content>
<categories>
<category>数据结构</category>
</categories>
<tags>
<tag>单链表</tag>
</tags>
</entry>
<entry>
<title><![CDATA[前端入门第二天]]></title>
<url>%2F2018%2F08%2F17%2F%E5%89%8D%E7%AB%AF%E5%85%A5%E9%97%A8%E7%AC%AC%E4%BA%8C%E5%A4%A9%2F</url>
<content type="text"><![CDATA[前言许久未更新了,今天七夕,为了逃避现实,重启博客。本博客主要记录一些前端学习中的入门级问题。 正文Q1:HTML标签、元素、属性都是什么概念?HTML标签:HTML标签标记了HTML文档和HTML元素,HTML标签由开始标签和结束标签组成.开始标签为尖括号包围的元素名,结束标签为尖括号包围的斜杠和元素名。例如:<h2> My First Heading</h2> HTML元素:HTML文档是由html元素定义的.HTML的元素是指从开始标签到结束标签的所有代码..例如:<p>我是一个段落</p>表示一个html元素.可以看出,html元素主要包括html标签和纯文本.标签定义网页显示的格式,文本表示网页的内容.故此,网页 = html文档,而html文档则是由html元素定义的. HTML属性:HTML属性为HTML元素提供附件信息,例如在超链接标签<a href = “https://inspurer.github.io>月小水长的个人博客</a>使用了href属性来指定超链接的地址.属性总是以名称/值的形式出现,例如:name = “value”属性总是在开始标签中定义. Q2:meta标签都用来做什么的? 元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词。 标签位于文档的头部,不包含任何内容。 标签的属性定义了与文档相关联的名称/值对。 Q3: Web语义化是什么,是为了解决什么问题?简言之,web语义化的目的是提高计算机和人对web代码的可读性。 网上的解释很多,个人总结分三个阶段比较容易理解。1、原始的一些有实际含义的标签定义。浏览器和W3C组织推出的如h1~h6、thead、ul、ol的HTML标签用于在Web页面中组织对应的内容,如网页标题、表头、无序、有序列表,以达到更方便的协作及传播互联网内容的目的。搜索引擎很好的利用了这些语义化标签抓取内容,又鉴于搜索引擎的巨大流量推荐,Web前端不得不考虑SEO,从而两者实现有益的循环,共同推进着语义化标签的使用。 2、前端开发人员自定义的标签。但Web的发展超乎想象,起初定义的HTML语义化标签,不足以实现对Web页面各个部分的功能或位置描述,所以Web前端人员利用HTML标签的id和class属性,进一步对HTML标签进行描述,如对页脚HTML标签添加如id=”footer“或者class=”footer”的属性(值),以“无声”的方式 在不同的前端程序员或者前后端程序员间实现交流。 3、在第二步的推动下结合新技术出现的一些标签。W3C组织意识到了之前HTML版本的不足,推出的HTML5进一步推进了Web语义化发展,采用了诸如footer、section等语义化标签,弥补了采用id=”footer”或者class=”footer”形式的不足,以更好的推动Web的发展。正所谓:世上本没有路,走的人多了,也便成了路。 Q4: 表单标签都有哪些,对应着什么功能,都有哪些属性?还是W3School的这篇教程经典:HTML表单标签之input Q5: ol, ul, li, dl, dd, dt等这些标签都适合用在什么地方?举个例子.1.无序列表无序列表是一个项目的列表,此列项目使用粗体圆点(典型的小黑圆圈)进行标记。无序列表始于 <ul>标签。每个列表项始于 <li>。 2.有序列表同样,有序列表也是一列项目,列表项目使用数字进行标记。有序列表始于 <ol>标签。每个列表项始于<li> 标签。` Coffee Milk ` 3.定义列表自定义列表不仅仅是一列项目,而是项目及其注释的组合。自定义列表以 <dl>标签开始。每个自定义列表项以 <dt> 开始。每个自定义列表项的定义以<dd> 开始。]]></content>
<categories>
<category>前端</category>
</categories>
<tags>
<tag>前端</tag>
</tags>
</entry>
<entry>
<title><![CDATA[前端入门杂记]]></title>
<url>%2F2018%2F06%2F12%2F%E5%89%8D%E7%AB%AF%E5%85%A5%E9%97%A8%E6%9D%82%E8%AE%B0%2F</url>
<content type="text"><![CDATA[前言从今天开始在本教程上纪录当日学到的知识点,不追求百科全书式的纪录只记录那些我比较陌生的或者觉得比较容易混淆的 笔记正文 先来纪录一个坑,用notepad++写出第一个html文档时,代码如下保存为html文件,在火狐浏览器打开,发现文档的内容这几个字是乱码不是utf-8/cp36的问题,而是必须这个html文档必须要BOM头 太累了,后续更新…2018/6/13深夜]]></content>
<categories>
<category>前端</category>
</categories>
<tags>
<tag>前端</tag>
</tags>
</entry>
<entry>
<title><![CDATA[前端入门第一天]]></title>
<url>%2F2018%2F06%2F11%2F%E5%89%8D%E7%AB%AF%E5%85%A5%E9%97%A8%E7%AC%AC%E4%B8%80%E5%A4%A9%2F</url>
<content type="text"><![CDATA[前言前不久在网上看到一篇Hexo建站的教程,顺手给自己建了个个人博客 有还算扎实的c++/java/python/andorid基础,整个建站过程还算顺利从此沉迷web编程,但是我感觉用现成的框架,总有点那啥受制于人的感觉打算好好学一下前端,由于在实验室跟着老师做项目一直没有时间但是万万没想到,心心念念的前端,开始正式开始系统学习居然是在忙到炸的期末考试周在此要先pick一下百度前端技术学院,可以说是我的前端入门导师了哈哈哈,不bb了,正式开始。 首先我们要知道访问网站的具体过程比如,输入http://www.zhihu.com/question/22689579访问过程如下图所示浏览器和服务器交流,服务器和数据库交流(有时候数据库就在服务器那台机子上)浏览器给服务器发一个请求,服务器不是一看就知道怎么响应的。首先这些请求和响应要有一个通用的写法,也就是要有一个协议,常用的是HTTP协议。像最前面的图,服务器的响应写了一个状态码200 OK,是HTTP协议里约定俗成的一个东西,服务器写200 OK在响应里,表示“你请求的这个东西我有”,如果是404 Not Found,就是“你请求的这个东西我这里没有”。HTTP响应里还包括很多东西,比如Content-type表示服务器发过来的文件类型是什么(文本?动画?图片?音频?)形象化Http响应,大概这样: 然后我们来了解前端三剑客 html 接上图,服务器返回html(就是上图HTTP响应的body里的内容)文件 后,电脑拿到html后,浏览器就会对它进行解析渲染,html是一种文本标记语言,举个栗子: css 浏览器拿到这些代码之后,分析一下给你渲染好页面显示出来,但是如果没有用css,效果是这样的,按照浏览器默认的样式显示出列表、图片、超链接、输入框、按钮等等:是不是觉得默认样式有点看瞎狗眼呢……所以很多时候我们需要自定义样式,现行通用的规定样式的语言是CSS,我们可以用它写一些定义样式的代码,在 html 文件里用一个标签把这些规定样式的CSS代码与表达内容语义的HTML代码关联起来,然后你就能看到一个符合人类正常审美的页面了:插一句:CSS 代码的格式基本是属性 : 值 javascipt(js)有了表示内容和语义的 HTML,规定样式的 CSS,得到的是一个静态的页面,没什么动画(其实用 CSS 还是可以有一些动画的,不过这个跑题了),按 F5 才会刷新数据,于是我们有了 Javascript(js)来给页面添加一些动态的效果浏览器都会帮你实现一些 JS 可以用的工具(函数,对象什么的),你只要写一些js的代码,保存在xxx.js 里,在html文件中用 <script>关联进来就可以用了 在前端三剑客bb了怎么多,可以用一句很形象的话来归纳之:前台三剑客,html是名词,css是形容词,javascript是动词。三个互相配合才是一句子就问形不形象 立个Flag考虑到三周的期末周,就立一个这样的flag吧:暑假每天至少学习前端两个小时,争取下学期开始学完! 致谢最后实名pick一下小姐姐张秋怡,感谢她的精彩回答我只是个搬运工只不过经过自己的理解稍作了修改2018/6/12 00:31初稿欢迎评论啊]]></content>
<categories>
<category>前端</category>
</categories>
<tags>
<tag>前端</tag>
</tags>
</entry>
<entry>
<title><![CDATA[”月小水长“和“inspurer”的由来]]></title>
<url>%2F2018%2F06%2F07%2F%E6%9C%88%E5%B0%8F%E6%B0%B4%E9%95%BF%E7%9A%84%E7%94%B1%E6%9D%A5%2F</url>
<content type="text"><![CDATA[非凭空臆想,其有典故;宋苏轼在后赤壁赋有云:山高月小,水落石出曾日月之几何,而江山不可复识矣在此我引申出月小水长句,一为不怕贻笑大方而附庸风雅,二为吾全名肖涛之字析,月小为肖,水即三点水,长寿为涛,还算是能够自圆其说。至于inspurer,大一的时候了解到一家很厉害的中国企业inspur浪潮想不到中国除了华为还有在高新技术领域耕耘了这么深的企业,遂起名inspurer,寓意弄潮儿,想成为那种站在技术潮头的人儿呐~]]></content>
<categories>
<category>生活志</category>
</categories>
</entry>
</search>