-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.xml
360 lines (360 loc) · 98.6 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
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[PixiCAPI]]></title>
<url>%2Fblog%2F2020%2F07%2F08%2Fpixicapi%2F</url>
<content type="text"><![CDATA[本篇概述:这是一篇关于PixiC项目的API接口文档。 1./api/v2/get-info 获取指定pid的数据请求类型: POST 参数 字段名 数据类型 默认 说明 pid str / int - 必要,需要查询的插画pid pid必须为纯数字,不限定str/int类型,pid长度小于20; 响应数据 字段名 数据类型 说明 result json 对应pid插画的数据 请求参数示例 字段名 值 pid 75165182 响应示例 123456789101112131415161718192021222324{ "result": [ { "bookmarkCount": 4159, "commentCount": 16, "error": false, "id": 7029, "illustType": 0, "is_r18": 0, "likeCount": 2762, "message": "", "original": "https://i.pximg.net/img-original/img/2019/06/11/00/13/40/75165182_p0.jpg", "pageCount": 1, "pid": 75165182, "purl": "https://www.pixiv.net/artworks/75165182", "reverse_url": "https://pixiv.cat/75165182.jpg", "tag": "初音ミク/初音未来、VOCALOID、女の子/女孩子、チャイナ服/中国服装、VOCALOID1000users入り/VOCALOID 1000收藏、", "title": "初音ミク", "uid": 3779517, "userName": "BTraphen", "viewCount": 18485 } ]} json字段说明 字段 说明 bookmarkCount 收藏数 commentCount 评论数 error 接口是否出现错误,尚未使用错误码 id - illustType - is_r18 - likeCount 喜欢数 message 错误信息, error为True时, 此处为错误信息 original 反代原图链接 pageCount 页数 pid 作品pid purl 作品页面 reverse_url 反代链接 tag 标签组,各个标签以、分隔,原标签与翻译以/分隔 title 插画标题 uid 作者uid userName 作者昵称 viewCount 浏览数 2./api/v2/random 随机返回插画请求类型: POST 参数 字段名 数据类型 默认值 说明 num str / int - 返回的插画数量, 1~10范围内, 大于只会返回1条 extra str - 返回的插画中包含extra中指定的标签,最多指定2个,以“,”分隔 num必须为纯数字,不限定str/int类型,1<num<10; 指定num=10,extra=something,接口会返回满足extra条件的记录数(满足条件数据不满足10条则返回对应数量); 响应数据 字段名 数据类型 说明 result json 对应pid插画的数据 请求参数示例 字段名 值 num 10 extra 原创,学校生活 响应示例 123456789101112131415161718192021222324{ "result": [ { "bookmarkCount": 10975, "commentCount": 19, "error": false, "id": 30660, "illustType": 0, "is_r18": 0, "likeCount": 10250, "message": "", "original": "https://i.pximg.net/img-original/img/2017/12/18/00/07/45/66336051_p0.png", "pageCount": 1, "pid": 66336051, "purl": "https://www.pixiv.net/artworks/66336051", "reverse_url": "https://pixiv.cat/66336051.png", "tag": "オリジナル/原创、女の子/女孩子、学校生活、グレー系/greyscale、心象風景/mental scenery、オリジナル10000users入り/原创10000users加入书籤、", "title": "world end", "uid": 772547, "userName": "loundraw", "viewCount": 112081 } ]}]]></content>
<categories>
<category>python爬虫</category>
</categories>
<tags>
<tag>python</tag>
<tag>pixiv</tag>
<tag>PixiC</tag>
<tag>API</tag>
</tags>
</entry>
<entry>
<title><![CDATA[PixiC部署文档]]></title>
<url>%2Fblog%2F2020%2F06%2F24%2Fpixic-bu-shu%2F</url>
<content type="text"><![CDATA[本篇概述:这是一篇关于PixiC项目的部署文档,旨在帮助感兴趣的各位部署PixiC项目,获取Pixiv的插画和数据。 如果你有一定的基础,那么可以跳过部分节点,文档尽可能从0到1,详细的讲述部署过程。 PixiC部署文档Github仓库地址:PixiC (此文留存备份) 1、Python&MySQL 项目环境目前只有win系统的部署文档,用户大多数是win用户,所以目前PixiC未兼容win以外的系统。 Python 3.7.6 MySQL 5.7.14 Python Python版本尽可能和项目一致,当然高版本也是可以的. Python官方下载页面: https://www.python.org/downloads/ 蓝奏云: python-3.7.6-amd64.exe 如果你不需要用到数据库,下面MySQL这步可以跳过. 如何判断你需不需要用到数据库呢? 如果是只需要下载插画到本地或你根本不知道数据库是什么, 那么下面这一部分可以略过. MySQL MySQL可以使用WampServer,phpStudy,phpEnv等集成环境轻松安装, 也可以只安装MySQL数据库. MySQL版本尽量用最新或者稳定的,项目测试尚未更新MySQL版本.(建议采用最新版本) MySQL官方下载: https://www.mysql.com/downloads/ WampServer官网下载: https://www.wampserver.com/ 度盘: WampServer3.0.6 提取码: 3ug2 安装完数据库, 可以使用mysql-cmd来管理, 也可以使用数据库可视化/管理工具进行管理. (建议采用最新版本) 个人使用的是MySQL-front MySQL-front官方下载: https://mysql-front.en.softonic.com 蓝奏云: MySQL-Front_Setup_6.1.1.26.exe Tips 安装Python时记得勾选Add Python to Path以及注意安装路径. 第一个红框框选的位置为Python的安装目录(重点), 第二个为添加Python到环境变量. 安装完成后, Win + R, 输入cmd, 输入Python. 如图,则安装成功. 初次安装完python, 建议更新pip版本 1python -m pip install --upgrade pip 使用pip –version查看pip版本 1pip --version MySQL及MySQL管理工具安装完成如下: 2、Python依赖 安装PixiC需要的第三方库依赖 下载本项目到本地. 1git clone https://github.com/Coder-Sakura/PixiC.git 或者通过Download ZIP下载 下载或解压到本地后,切换到v2.0目录,,打开cmd(在地址栏输入cmd) 1pip install -r requirements.txt 如果pip更新下载过慢或失败,尝试使用国内豆瓣源 1pip install -r requirements.txt -i http://pypi.douban.com/simple --trusted-host pypi.douban.com 安装依赖时,出现 You should consider upgrading via the ‘python -m pip install –upgrade pip’ command. 字样时,说明你的pip需要更新,使用提示给出的更新命令。 1python -m pip install --upgrade pip 安装依赖完毕后,使用pip list检查是否安装成功。 1pip list 3、Chrome&Webdriver 通过Selenium驱动ChromeDriver,获取Chrome上Pixiv账户的Cookie,从而达到绕过Pixiv Google v3验证的目的。 简而言之,没有这一步的部署,根本获取不了你的Pixiv账号的信息,也就是没有登录(Pixiv对游客账号是有限制的),那么PixiC就无从谈起了。 Chrome Chrome官方下载: https://www.google.cn/intl/zh-CN/chrome/ 蓝奏云: ChromeSetup.exe 使用Chrome://version, 查看Chrome浏览器版本及个人资料路径(重点) ChromeDriver ChromeDriver仓库地址:http://chromedriver.storage.googleapis.com/index.html 根据Chrome版本号,下载对应的ChromeDriver。 上面是83.0.4103.61,那么这里选择对应的进行下载。 测试环境在win,这里选择chromedriver_win32.zip下载。 注意! chromedriver版本要与Chrome浏览器版本对应,如果PixiC中的Selenium驱动不了chromedriver,请检查前面二者的版本号。 解压完毕,将chromedriver.exe放在python.exe所在目录下(推荐) (Python的安装目录不一样,截图仅供参考) python.exe所在路径,在第一点的Tips中有描述。 或者可以通过以下方法找到 12import syssys.path sys.path中也有给出上面截图的路径。 测试Chromedriver是否正常工作 1234from selenium import webdriverdriver = webdriver.Chrome()driver.get("https://www.pixiv.net")driver.close() 复制到cmd窗口中执行或新建一个py脚本运行 测试结果: Chrome打开并访问Pixiv,之后关闭Chrome 4、配置文件 打开PixiC项目v2.0/config.py文件 使用sublime text(推荐)/notepad++/pycharm/vscode等等代码编辑器打开。 蓝奏云: Sublime Text3 v3.2.1中文免安装版 定制配置文件 在PixiC配置之前,先要明确自己利用PixiC的目的是下列哪一种? 下载Pixiv账号关注/收藏作品原图 包含1,存储数据到数据库/使用API对接酷q机器人等拓展应用 第一点的话,阅读简单配置即可。 第二点的话,请阅读简单配置及拓展,以及MySQL环境需要安装。 简单配置 目录路径 字段 说明 备注 ROOT_PATH Pixiv账号关注画师的作品下载目录 必填,ROOT_PATH= r’H:\follow’ BOOKMARK_PATH Pixiv账号收藏作品下载目录 必填,BOOKMARK_PATH= r’H:\bookmark’ PRO_DIR Chrome浏览器用户数据目录 必填,参照第三节Chrome&Webdriver进行填写 如果关注和收藏过多,ROOT_PATH和BOOKMARK_PATH建议选择容量剩余较大的硬盘的目录。这里给出下载容量参考: 355关注用户,3000收藏数限制,120G;5000收藏作品,全下载14G 2400关注用户,2000收藏数限制,747G 关于PRO_DIR字段,配置文件中注释有提供参考 用户信息 字段 说明 备注 USER_ID Chrome浏览器登录的Pixiv账号的uid 默认为空 COOKIE_UPDATE_ENABLED 控制是否更新本地cookie 首次运行设置为True pixiv账号的uid可以访问 https://www.pixiv.net/bookmark.php 。点击自己头像进入主页,查看地址栏,形如:https://www.pixiv.net/users/112233 ,112233即为uid。 COOKIE_UPDATE_ENABLED项首次运行设置为True以更新cookie到本地,后续运行设置为False可快速启动。 模块控制开关及轮询周期 字段 说明 备注 PIXIV_CRAWLER_ENABLED 关注用户作品爬虫模块开关 默认True,False即关闭 PIXIV_BOOKMARK_ENABLED 收藏作品爬虫模块开关 默认True,False即关闭 PIXIV_API_ENABLED API模块开关 默认False USERS_CYCLE 关注爬虫轮询间隔 默认43200秒 USERS_LIMIT 关注爬虫下载作品的收藏最低限制 默认3000收藏以上 BOOKMARK_CYCLE 收藏爬虫轮询间隔 默认7200秒 BOOKMARK_LIMIT 收藏爬虫下载作品的收藏最低限制 默认0收藏,全下载 PIXIV_CRAWLER_ENABLED和PIXIV_BOOKMARK_ENABLED默认开启,PIXIV_API_ENABLED如果需要开启,参考拓展配置。 拓展配置 API设置 字段 说明 备注 API_HOST 主机ip 默认本地,0.0.0.0/127.0.0.1 API_PORT 端口 默认1526 API_THREAD API线程数 默认8 RANDOM_LIMIT API-random接口-最大返回数 默认10 RANDOM_BOOKMARK_ENABLE API-random接口-是否开启收藏数筛选 默认True RANDOM_BOOKMARK_LIMIT API-random接口-返回插画最小收藏数 默认3000收藏数以上 数据库连接信息 字段 说明 备注 DB_ENABLE 数据库开关 默认为False,True为开启 DB_HOST 主机ip 默认本地,localhost/127.0.0.1 DB_PORT 端口 3306 DB_USER 用户名 DB_PASSWD 密码 DB_DATABASE 数据库库名 moe DB_CHARSET 数据库/表编码 utf8mb4 数据库连接信息根据实际填写,DB_ENABLE看个人需求。 不过注意: DB_ENABLE和PIXIV_API_ENABLED同时开启,都为True,可同时使用数据库及API DB_ENABLE为True,PIXIV_API_ENABLED为False,爬虫模块使用数据库进行存储 DB_ENABLE和PIXIV_API_ENABLED都为False,无法使用数据库及API DB_ENABLE为False,PIXIV_API_ENABLED为True,结果与上一点相同 DB_DATABASE和DB_CHARSET和v2.0/doc/create.sql一致,建议不修改 以上便是配置文件部分 5、运行 首次运行,配置好配置文件,在Chrome上登录Pixiv账号,关闭Chrome。 打开cmd,切换到v2.0目录下 / 或进入v2.0目录后再从地址栏打开cmd 输入命令: 1python scheduler.py 接下来享受自己关注画师的作品和收藏的作品下载到本地,或者数据存储进数据库里吧!]]></content>
<categories>
<category>python爬虫</category>
</categories>
<tags>
<tag>python</tag>
<tag>pixiv</tag>
<tag>PixiC</tag>
<tag>acg</tag>
</tags>
</entry>
<entry>
<title><![CDATA[MyBookShelf-python]]></title>
<url>%2Fblog%2F2019%2F11%2F12%2Fmybookshelf-python%2F</url>
<content type="text"><![CDATA[本篇概述:用python自定义阅读酷1000+书源并导出生成短链接 1、123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176import requestsimport timeimport refrom lxml import etree# 收藏post_url = 'http://ku.iszoc.com/index/sign.html'# 导出收藏为json文件的apiexport_url = 'http://ku.iszoc.com/user/Favorites/export.html'# 阅读酷书源最大页数search_url = "http://ku.iszoc.com/index/search.html"# 阅读酷书源收藏书源最大页数fa_index_url = "http://ku.iszoc.com/user/favorites/index.html"# 删除收藏的apidel_url = "http://ku.iszoc.com/user/Favorites/selectDel.html"# 请求头headers = { "Cookie":"PHPSESSID=c3a21362dc3036a515db860e095a1ca4; Hm_lvt_ea5e026ac2ed0205ce7a6417bbd1dcef=1571831331,1572157850,1572790358,1573480142; Hm_lpvt_ea5e026ac2ed0205ce7a6417bbd1dcef=1573481354", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3641.400 QQBrowser/10.4.3284.400"}def max(url): ''' 获取最大书源页数 ''' html = req_page_html(url=url) obj = etree.HTML(html) num = obj.xpath(".//ul[@class='pagination']//li/a/text()")[-3] return int(num)def req_page_html(url,num=3): ''' 封装函数以请求每一页书源网址(一页15个),返回resp.text ''' try: resp = requests.post(url,headers=headers,timeout=10).text except Exception as e: if num > 0: # 重试3次 return req_page_html(url,num=num-1) else: print(url) print(e) return respdef req(post_id,num=3): ''' 封装请求函数以收藏书源 ''' data = { "type":"yes", "id":post_id } try: resp = requests.post(post_url,headers=headers,data=data,timeout=10).text except Exception as e: if num > 0: # 重试3次 return req(post_id,num=num-1) else: print(post_id) print(e) return respdef parse_div(i,div): ''' 提取信息,主要是拿到收藏状态,其他写着玩,如需不要请注释 ''' r = re.compile("[ &nbsp\r\n ]") # 过滤的正则表达式 # 每个书源div下的5个span,有些有6个 span_list = div.xpath("./div[@class='layui-card-body']/span") # ================ ↓ 可注释 ↓ ================================== # 点击量 dianji_count = span_list[0].xpath("./span/text()")[0] dianji_count = re.sub(r,'',dianji_count).replace(" ","") # 评论量 comment_count = span_list[1].xpath("./span/text()")[0] comment_count = re.sub(r,'',comment_count) # 更新时间 update_time = span_list[3].xpath("./span/text()")[0] update_time = re.sub(r,'',update_time) update_time = update_time[:10] + ' ' +update_time[10:] # 作者 author = span_list[4].xpath("./span/text()")[0] author = re.sub(r,"",author) # 以下属性可能部分div没有 # 带发现 try: search = span_list[5].xpath("./span/text()")[0] except: search = "无带发现" search = re.sub(r,"",search) # 音频源 try: audio = span_list[5].xpath("./span/text()")[0] except: audio = "无音频源" audio = re.sub(r,"",audio) # ================ ↑ 可注释 ↑ ================================== # 收藏状态 bookmark = span_list[2].xpath("./span/text()")[0] bookmark = re.sub(r,"",bookmark) # 如注释收藏状态以外的部分,请使用下面该行 # return bookmark return [dianji_count,comment_count,bookmark,update_time,author,search,audio],bookmarkdef work(): for i in range(1,max(search_url)+1): url = 'http://ku.iszoc.com/index/search.html?page={}'.format(i) resp = req_page_html(url) etree_obj = etree.HTML(resp) div_list = etree_obj.xpath("//div[@class='layui-card-body']/div")[1:] # 第一个是公告 for div in div_list: # 每个书源的id post_id = div.xpath("./a/@href")[0].split('.')[0].split('/')[-1] mes_list,bookmark = parse_div(i,div) # print(post_id,bookmark) if bookmark == '未收藏': resp = req(post_id) if '收藏成功' in resp: print(i,post_id,'收藏成功') else: print(resp) print(i,post_id,'error') elif bookmark == '已收藏': print(i,post_id,'已收藏') time.sleep(0.5) # break time.sleep(5) # print('\n')def export(): ''' 获取收藏内的书源的value_id,并将所有id拼接起来 ''' value_id = '' for i in range(1,max(fa_index_url)+1): fa_url = 'http://ku.iszoc.com/user/favorites/index.html?page={}'.format(i) resp = req_page_html(fa_url) etree_obj = etree.HTML(resp) id_list = etree_obj.xpath("//input[@name='key[]']/@value") for _id in id_list: value_id += _id value_id += ',' # print(value_id) time.sleep(0.5) # break with open('1008_values_id_list.txt','w') as f: f.write(value_id) data = { 'id':value_id } # 批量删除所有收藏书源 # resp = requests.post(del_url,headers=headers,data=data,timeout=10).text # 批量导出所有收藏书源 resp = requests.post(export_url,headers=headers,data=data,timeout=10).text print(resp)if __name__ == '__main__': ''' 1、使用前清获取自己的cookie填入headers中的cookies字段中 2、如需删除所有收藏的书源,将下面三行注释 再将export()方法中post的url由export_url改为del_url即可 ''' print("="*30,"开始收藏","="*30) work() # 全部收藏 print("="*30,"收藏完成","="*30) print("="*30,"开始获取书源地址","="*30) export() # 拿到所以value id生成json print("="*30,"获取完成","="*30) 2、3、]]></content>
<categories>
<category>python</category>
</categories>
<tags>
<tag>python</tag>
<tag>MyBookShelf</tag>
</tags>
</entry>
<entry>
<title><![CDATA[MyBookShelf/阅读]]></title>
<url>%2Fblog%2F2019%2F10%2F27%2Fmybookshelf%2F</url>
<content type="text"><![CDATA[本篇概述:分享一款可以读书软件(阅读/MyBookShelf)。无广告,可自定义书源,界面简洁,专注阅读,没有多余的社交等功能,专为管理书籍而生。 1、概述MyBookShelf / 阅读 专注于管理书籍,并能用网络中自定义来源以获取书籍内容,开源简洁,支持Web服务管理书架。大小10M左右,麻雀虽小五脏俱全。 地址 Github地址:https://github.com/gedoor/MyBookshelf 官网:https://gedoor.github.io/MyBookshelf/ 书源分享平台:http://ku.iszoc.com/ 页面展示界面简洁,专注阅读。书源丰富,功能齐全,自定义书源,自定义排版( 图片来源官网/github)]]></content>
<categories>
<category>软件分享</category>
</categories>
<tags>
<tag>软件分享</tag>
<tag>Others</tag>
</tags>
</entry>
<entry>
<title><![CDATA[1024小关卡]]></title>
<url>%2Fblog%2F2019%2F10%2F24%2F1024%2F</url>
<content type="text"><![CDATA[本篇概述:菜鸟教程公众号在1024当天所发的一个 ” 程序员节闯关瓜分 1024 红包 “ 的活动。 1、文章页面展示点击 2、逐个击破1、打开网站 www.runoob.com 查找第一个字母 —— i ctrl + U 打开源码没发现什么,也没什么明确提示 F12 打开调试工具,很明显看见个关键字 / console 页签也有打印 2、第二个字母 md5 加密 —— l123456import stringimport hashlibfor i in string.ascii_letters: res = hashlib.md5(i.encode()).hexdigest() if res == '2db95e8e1a9267b7a1188556b2013b33': print(i) 3、第三个字母对应的ASCII为111 —— o123# chr() 查看ascii码对应的字符 # chr(65) Achr(111) 4、第四个字母在二维码中 —— v 扫描即可,v 盲猜,ilov erunoob,都是套路 5、第五个字母 —— e RGB(238,238,238) RGB颜色代码转十六进制 ——> 结果:#EEEEEE 网站: RGB颜色值与十六进制颜色码转换工具 6、第6-8个字母是个单词,图片的数字为二进制 —— r u n 01110010 01110101 01101110 123456789101112int('01110010',2)int('01110101',2)int('01101110',2)# 114 117 110# ascii码# 用chr()转换下chr(114)chr(117)chr(110)# r u n 7、第七个—— oo图片里的是一段js代码,还有正则。 reg 的意思是: (\w),匹配字母及下划线并分到一个捕获组里; \1,是向后引用第二个捕获组并匹配和分到一个捕获组。( \0是第一个,也就是正则表达式 ) 这段正则就是捕获字母或下划线重复的部分 1234567import reh = 'abcdefghijklmnoopqrstuvwxyz'r = r'(\w)(\1)'# js代码里的正则/g不知道啥意思p = re.compile(r)m = re.findall(p,h) 结果,m = [(‘o’, ‘o’)] 8、第八个字母 —— b Yg== 等于号结尾,很明显是base家族编码 1234import base64print(base64.b64decode(b'Yg=='))# base32解码就是将b64decode变成b32decode,base16同理. 3、请求 以上得到是:iloverunoob; 拼接 http://test.runoob.com/runoob1024.php?key=iloverunoob]]></content>
<categories>
<category>python</category>
</categories>
<tags>
<tag>python</tag>
<tag>其他</tag>
</tags>
</entry>
<entry>
<title><![CDATA[python操作csv文件]]></title>
<url>%2Fblog%2F2019%2F09%2F26%2Fcsv%2F</url>
<content type="text"><![CDATA[本篇概述:csv文档操作及部分函数示例 1、简介 CSV 模块是python内置的标准库 1import csv # 引入方式 CSV格式的文件是电子表格和数据库最常见的输入输出文件格式,对了多种来源的CSV文件,编写一个统一的CSV模块来统一处理是极为有效率的。 2、函数介绍1.csv.reader() 读取 csvfile : 必须是可迭代对象,或者是文件 dialect:编码风格,默认是 excel 风格;需要指定其他风格可查看csv.list_dialects() 12print(csv.list_dialects())# ['excel', 'excel-tab', 'unix'] fmtparams:格式化参数,用于覆盖 dialect 指定的风格 12345678import csvwith open('t.csv','r') as f: ls = csv.reader(f,dialect='excel') # 默认是excel for l in ls:print(l)# ['标题1', '标题2', '标题3', '标题4']# ['1', '2', '3', '4']# ['1', '1'] 2.csv.writer() 写入 同csv.reader() 12345678import csv# w是写入,存在则覆盖,慎用# 这里为了举例使用with open('t.csv','w') as f: w = csv.writer(f) w.writerow([0,1]) w.writerows([['John',18],['Joe',19]]) writerow 单行写入 writerows 多行写入 但是以上代码执行后存在一个问题:每次写入数据都会换行再写入 解决: 1234567import csv# w是写入,存在则覆盖,慎用with open('t.csv','w',newline='') as f: w = csv.writer(f) w.writerow([0,1]) w.writerows([['John',18],['Joe',19]]) 结果: 分析: newline 参数是控制文本模式下( 即w、w+、a、a+等) 一行文本结束的字符,可以是None,\n,\t等 3.csv.list_dialects() 查看所有支持的编码风格,包括用户自定义的 123import csvprint(csv.list_dialects())# ['excel', 'excel-tab', 'unix'] 4.csv.register_dialect(name, [dialect, ]**fmtparams) 创建自定义的 dialect name:自定义的 dialect 名字 其余的是dialect格式参数,包括:delimiter(分隔符,默认的就是逗号)、quotechar、quoting等 12345678# 创建一个test1的dialect,分隔符用"|"csv.register_dialect('test1',delimiter='|')# 引用with open('t.csv','r') as f: ls = csv.reader(f,'test1') pass 5.csv.unregister_dialect() name:dialect的名字 12345678910import csvprint(csv.list_dialects())['excel', 'excel-tab', 'unix']csv.register_dialect('test1',delimiter='|')print(csv.list_dialects())['excel', 'excel-tab', 'unix', 'test1']csv.unregister_dialect('test1')print(csv.list_dialects())['excel', 'excel-tab', 'unix'] 6.csv.DictWriter() 以字典形式写入 csvfile:必须是可迭代对象,或者是文件 fieldnames:字段名 123456789import csvwith open('t.csv','w',newline='') as f: fileheader = ['name','age'] w = csv.DictWriter(f,fileheader) w.writeheader() data = [['Ame',18],['Jack',22],['Bob',26]] for d in data: w.writerow({'name':d[0],'age':d[1]}) 结果:]]></content>
<categories>
<category>python</category>
</categories>
<tags>
<tag>python</tag>
<tag>csv</tag>
</tags>
</entry>
<entry>
<title><![CDATA[解决pixiv登录机制添加Google V3验证]]></title>
<url>%2Fblog%2F2019%2F08%2F29%2Fpixiv-new-login%2F</url>
<content type="text"><![CDATA[本篇概述:本文主要解决爬虫登录pixiv问题。8月份 pixiv 添加 recaptcha_v3(Google V3版本验证) 1、Google V3验证? 何为 Google 验证码(reCAPTCHA v3)? reCAPTCHA v3 会以嵌入js的方式,给网站后台返回一个分数,这个分数是用于判断用户是否是机器人,分数的范围是0~1,分数约接近0,越像机器人; 2、使用之前文章中的代码模拟登录 Pixiv文章地址:Python爬虫-pixiv关注画师作品[1] 结果 json 数据格式化一下 ↓ 3、分析 我反复登录了几次,网页上并发现没有出现上图的 “I’m not a robot” 但是在登录抓包却看到 recaptcha_v3_token的值不为空,以前这个字段我记得是空的。 打开登录页面,f12打开调试工具–Network,点击XHR分页,可以看到每隔一段时间,通过 reload 重新请求一个 recaptcha_v3_token (稍微等待一下,一会儿就会看到第二个reload出来了) ↓ 登录的 from data,这个 recaptcha_v3_token ↓ 截个图,看看请求 recaptcha_v3_token 要 post 的字段 ↓ 4、解决方案1、手动抓包,在 headers 加入cookie 字段 图太长,手动省略 ↓ 2、selenium 抓取 (略) 个人比较喜欢用纯代码实现,虽然 selenium 也是要写代码。 3、selenium + requests (正文) [Warning]:该方法食用前,请先确保手动在 Chrome 上登录 pixiv selenium 自动保存 cookies requests 读取 cookies 并维持会话 Talk is cheap , Show me code 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263from selenium import webdriverimport osimport jsonimport requestsfrom requests.cookies import RequestsCookieJar# user data目录pro_dir = r'C:\Users\Hatsune Miku\AppData\Local\Google\Chrome\User Data'def get_cookie(): ''' 获取本地cookies ''' # 添加配置 chrome_options = webdriver.ChromeOptions() # 静默模式 chrome_options.add_argument('--headless') chrome_options.add_argument('--no-sandbox') chrome_options.add_argument('--start-maximized') # 添加user data目录 chrome_options.add_argument('user-data-dir='+os.path.abspath(pro_dir)) driver = webdriver.Chrome(chrome_options=chrome_options) # 访问后,获取cookies driver.get('https://www.pixiv.net/') cookies = driver.get_cookies() # 保存cookies with open("pixiv_cookies.txt", "w") as fp: json.dump(cookies, fp) driver.close()def read_cookie(): ''' 读取cookies ''' jar = RequestsCookieJar() with open("pixiv_cookies.txt", "r") as fp: cookies = json.load(fp) for cookie in cookies: jar.set(cookie['name'], cookie['value']) return jardef rep(jar): ''' 携带cookies对象并验证 ''' # 此为个人关注画师页面 url = 'https://www.pixiv.net/bookmark.php?type=user' headers = { 'referer': 'https://accounts.pixiv.net/login', 'origin': 'https://accounts.pixiv.net', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) ' 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'} html = se.get(url,headers=headers,cookies=jar) return htmlif __name__ == '__main__': get_cookie() se = requests.session() # 定义session对象 jar = read_cookie() html = rep(jar) with open('bookmark.html','w+',encoding='utf8') as fp: fp.write(html.text) os.system('start bookmark.html') # 打开文件 结果展示 代码运行结束,会打开一个个人关注画师网页(selenium运行中的警报再想办法处理了) 可以将上面代码稍作修改,然后再封装成一个获取 cookies 对象的函数,后面直接携带这个 cookies 就行了 剩下的,想要拿收藏的插画√、关注的画师√、排行榜插画√ 都是可以的。]]></content>
<categories>
<category>python</category>
</categories>
<tags>
<tag>python</tag>
<tag>爬虫</tag>
<tag>lxml</tag>
<tag>requests</tag>
<tag>pixiv</tag>
<tag>selenium</tag>
</tags>
</entry>
<entry>
<title><![CDATA[PythonDailyQuestion-0613]]></title>
<url>%2Fblog%2F2019%2F06%2F15%2Fpythondailyquestion-0613%2F</url>
<content type="text"><![CDATA[本篇概述:0612-每日一问 Tipsgithub:https://github.com/Elegant-Smile/PythonDailyQuestion 1、基础题 从标准输入读取两个整数并打印两行,其中第一行输出两个整数的整除结果;第二行输出两个整数的带小数的除法结果。 123456print('exp:12 24')nums = input('input tow nums:')a,b = nums.split(' ')print(int(a)//int(b))print('%.2f'%(int(a)/int(b))) 2、基础题 使用turtle库,绘制一个风轮效果,其中,每个风轮内角为45度,风轮边长150像素。提示:turtle.goto(x,y)函数,能够将turtle画笔移动到坐标(x,y) 3、提高题 列表中有一个数字出现的次数超过列表长度的一半,请找出这个数字。例如,输入一个长度为 9 的列表[1, 2, 3, 2, 2, 2, 5, 4, 2]。数字 2 出现了5次,超过列表长度的一半,因此输出2。如果不存在则输出0。 12345678910111213# 也可以自己指定数组,这里随机生成import randomlens = int(input('The len is :'))t = []for i in range(lens): t.append(random.choice(range(lens)))print('数组为',t)for i in list(set(t)): if t.count(i) > lens//2: print(i)]]></content>
<categories>
<category>每日一问</category>
</categories>
<tags>
<tag>python</tag>
<tag>每日一问</tag>
</tags>
</entry>
<entry>
<title><![CDATA[PythonDailyQuestion-0612]]></title>
<url>%2Fblog%2F2019%2F06%2F15%2Fpythondailyquestion-0612%2F</url>
<content type="text"><![CDATA[本篇概述:0612-每日一问 Tipsgithub:https://github.com/Elegant-Smile/PythonDailyQuestion 1、概念题 请简述python中有哪些方式实现字符串格式化? 12345a = 'hello'b = 'world'print(a,b)print('%s %s'%(a,b))print('{} {}'.format(a,b)) 2、基础题 温度的刻画有两个不同体系:摄氏度(Celsius)和华氏度(Fahrenheit)。请编写程序将用户输入华氏度转换为摄氏度,或将输入的摄氏度转换为华氏度。转换算法如下:(C表示摄氏度、F表示华氏度) C = ( F - 32 ) / 1.8 F = C * 1.8 + 32要求如下:(1) 输入输出的摄氏度可采用大小写字母C结尾,温度可以是整数或小数,如:12.34C指摄氏度12.34度;(2) 输入输出的华氏度可采用大小写字母F结尾,温度可以是整数或小数,如:87.65F指摄氏度87.65度;(3) 输出保留小数点后两位,输入格式错误时,输出提示:输入格式错误;(4) 使用input()获得测试用例输入时,不要增加提示字符串。 1234567891011121314def change(t): if t[-1].upper() == 'C': t = float(t[:-1])*1.8+32 print('%.2fF'%t) elif t[-1].upper() == 'F': t = float(t[:-1])-32/1.8 print('%.2fC'%t) else: print('格式错误') if __name__ == '__main__': # print('Exp:12.34C、87.65F') Temperature = input('The Temperature is:') change(Temperature) 3、提高题 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。 1234567891011print('exp整数数组:123456')int_list = list(input('Input The Integer Array:'))even_list = [] # 偶数for i in int_list: if int(i)%2 == 0: int_list.remove(i) even_list.append(i)int_list.extend(even_list)print(int_list)]]></content>
<categories>
<category>每日一问</category>
</categories>
<tags>
<tag>python</tag>
<tag>每日一问</tag>
</tags>
</entry>
<entry>
<title><![CDATA[PythonDailyQuestion-0611]]></title>
<url>%2Fblog%2F2019%2F06%2F14%2Fpythondailyquestion-0611%2F</url>
<content type="text"><![CDATA[本篇概述:0611-每日一问 Tipsgithub:https://github.com/Elegant-Smile/PythonDailyQuestion 1、基础题 给定任意一个整数,打印出该整数的十进制、八进制、十六进制(大写)、二进制形式的字符串。 12345678910int_num = int(input('input the integer'))# 转二进制print('二进制形式为 : {}'.format(bin(int_num)))# 转八进制print('八进制形式为 : {}'.format(oct(int_num)))# 转十进制print('十进制形式为 : {}'.format(int(int_num)))# 转十六进制print('十六进制形式为 : {}'.format(hex(int_num).upper())) 2、基础题 给用户三次输入用户名和密码的机会,要求如下: 如输入第一行输入用户名为‘Kate’,第二行输入密码为‘666666’,输出‘登录成功!’,退出程序; 当一共有3次输入用户名或密码不正确输出“3次用户名或者密码均有误!退出程序。”。 1234567891011121314151617import sysadmin_username,admin_password = 'Kate','666666'count = 0while True: if count == 3: sys.exit() username = input('Input Your Username: ') password = input('Input Your Password: ') if all([username==admin_username, password==admin_password]): print('登录成功') sys.exit() else: print('用户名或密码错误\n') count += 1 3、提高题 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法 注:先后次序不同 算作是不同的结果 12345678# 递归,参考def jump(n): if n == 1 or n == 2: return n return jump(n-1) + jump(n-2)if __name__ == '__main__': print(jump(8))]]></content>
<categories>
<category>每日一问</category>
</categories>
<tags>
<tag>python</tag>
<tag>每日一问</tag>
</tags>
</entry>
<entry>
<title><![CDATA[PythonDailyQuestion-0610]]></title>
<url>%2Fblog%2F2019%2F06%2F14%2Fpythondailyquestion-0610%2F</url>
<content type="text"><![CDATA[本篇概述:0610-每日一问 Tipsgithub:https://github.com/Elegant-Smile/PythonDailyQuestion 1、基础题 恺撒密码是古罗马恺撒大帝用来对军事情报进行加解密的算法,它采用了替换方法对信息中的每一个英文字符循环替换为字母表序列中该字符后面的第三个字符,即,字母表的对应关系如下: 原文:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 密文:D E F G H I J K L M N O P Q R S T U V W X Y Z A B C 对于原文字符P,其密文字符C满足如下条件:C=(P+3) mod 26 上述是凯撒密码的加密方法,解密方法反之,即:P=(C-3) mod 26 假设用户可能使用的输入包含大小写字母a~zA~Z、空格和特殊符号,请编写一个程序,对输入字符串进行恺撒密码加密,直接输出结果,其中空格不用进行加密处理。使用input()获得输入。 123456789101112131415161718# 首先知道2个函数ord() # str -> asciichr() # ascii -> strord('a')# 97chr(ord('a'))# a# a位移1位# ord('a')=97,ord('b')=98chr(ord('a')+((98-97)+1)%26)# b# z位移1位# ord('a')=97,ord('z')=122chr(ord('a')+((122-97)+1)%26)# a 12345678910word = 'za %test' # 加密字符串offset = 3 # 偏移量target = ''for w in word: if 'a' <= w <= 'z': target += chr( ord('a') + ((ord(w)-ord('a')) + offset )%26 ) elif 'A'<= w <='Z': target += chr( ord('A') + ((ord(w)-ord('A')) + offset )%26 ) else: target += w 2、提高题 请实现一个函数用来找出字符串中第1个只出现1次的字符。例如:当从字符串中只读出前两个字符”go”时,第1个只出现次的字符是”g”。当从该字符串中读出前六个字符”google”时,第1个只出现1次的字符是“l”。 1234567import sysa = input('input the word:')for a1 in a: if a.count(a1) == 1: print('第一个只出现一次的字符为{}'.format(a1)) sys.exit()print('没有只出现一次的字符')]]></content>
<categories>
<category>每日一问</category>
</categories>
<tags>
<tag>python</tag>
<tag>每日一问</tag>
</tags>
</entry>
<entry>
<title><![CDATA[(更新动图)Python爬虫-pixiv关注画师作品[3]]]></title>
<url>%2Fblog%2F2019%2F06%2F12%2Fpixiv-three%2F</url>
<content type="text"><![CDATA[本篇概述:第二篇的续作,主要是各种图片类型的下载和文件夹创建; github地址、文中代码不一定能直接执行,粘贴过来可能缩进有问题。 1、分析——如何判断类型? 单图 ↓ 多图 ↓ 动图 仔细观察就会发现: 单图 url : 56309403_p0_square1200.jpg,有p0;pageCount:1 多图 url : 56527887_p0_square1200.jpg,有p0;pageCount:3 动图 url : 57027347_square1200.jpg,无p0;pageCount:1 2、代码——匹配类型123456789101112131415161718def painter_picture(self): ''' 上次的code ''' if pageCount == 1: # 有p0 # 2016/05/23/19/25/26/57027442_p0 # 无p0 # 2016/05/23/19/18/47/57027347 if small_url[51:-15][-2:] == 'p0': print('作品类型:单图\n') self.img_single(small_url,folder_path,folder_id) # 单图 else: print('作品类型:动图\n') self.img_gif(folder_path,folder_id) # 动图 else: print('作品类型:多图\n') self.img_multi(small_url,folder_path,folder_id,pageCount) # 多图 PS:拼接 url 时不要问为啥这么麻烦,看这里 本篇记录的是自己刚学python爬虫第一个爬虫项目的代码,这篇的代码可以说是仅仅是为了实现功能写出来的。 现在也有想法要重构,重构好之后发篇完整的出来,不过没有那么快而已。 现在找到了作品的详细信息接口,后面再更新了,这里用的是之前的方法。 回首看自己2个月前的代码,一点都不优雅。o(╥﹏╥)o 3、分析——创建画师文件夹及作品文件夹 首先指定一个下载目录 下载目录下为每个画师创建一个文件夹,形如:{id}–{name} 画师文件夹下为每个作品创建一个文件夹,形如:{id} 4、代码——文件夹1、创建画师文件夹 此处解决了画师更改名字,会导致该画师所有作品重下。 具体看代码吧,解释也挺麻烦的 123456789101112131415161718# 执行 mkdir_painter() 应在 attention_html() 的 painter_information 循环中# self.father_folder = self.mkdir_painter(painter_id,name)def mkdir_painter (self,painter_id,name): name = re.sub('[\/:*?"<>|]','_',name) folder_name = painter_id + '--' + name # 画师改名字!会导致重下 for folder in os.listdir(self.path): if painter_id == folder.split('--')[0]: print(u'[名字叫{0}文件夹已存在!]'.format(folder_name)) father_folder = os.path.join(self.path,folder) os.chdir(father_folder) ##切换到目录 return father_folder print(u'[建了一个{0}文件夹!]'.format(folder_name)) father_folder = os.path.join(self.path,folder_name) os.makedirs(father_folder) os.chdir(father_folder) ##切换到目录 return father_folder 2、创建作品文件夹12345678910111213def mkdir_works(self,folder_id): folder_path = os.path.join(self.father_folder,folder_id) isExists = os.path.exists(folder_path) if not isExists: print(u'\n[在',self.father_folder,'下建了一个', folder_id, u'文件夹!]') os.makedirs(folder_path) os.chdir(folder_path) ##切换到目录 return folder_path else: print(u'\n[在',self.father_folder,'下已经有', folder_id, u'文件夹!]') os.chdir(folder_path) ##切换到目录 return folder_path 5、单图下载12345678910111213141516171819202122232425262728def img_single(self,small_url,folder_path,folder_id): work_name = folder_id + small_url[-4:] # p站的图片有jpg和png的,但是从works_url获取到的只有小图jpg的url jpg_judge_path = folder_path + '\\' + work_name png_judge_path = folder_path + '\\' + folder_id + '.png' # 判断是否是上次因为jpg不行而下载png的图片,如果是的话,expand_name 用 .png 替换进行比对是否重复 if os.path.exists(jpg_judge_path) == True and os.path.getsize(jpg_judge_path) != 58: # 判断jpg print(jpg_judge_path,'已存在且字节数不为58!') else: if os.path.exists(png_judge_path) == True and os.path.getsize(png_judge_path) != 58: # 判断png print(png_judge_path,'已存在且字节数不为58!') else: try: small_date = small_url[51:-15] #动图的small_url没有p0 head = 'https://i.pximg.net/img-original/img/' img_url = head + small_date + small_url[-4:] #.jpg img_html = self.request(img_url) self.down(img_html,work_name,jpg_judge_path) # time.sleep(2) if os.path.getsize(jpg_judge_path) == 58: print('{}格式不对,准备重下'.format(work_name)) img_url = head + small_date + '.png' img_html = self.request(img_url) self.down_conversion(img_html,folder_id,jpg_judge_path,png_judge_path) except: print(work_name,'下载失败') 6、多图下载1234567891011121314151617def img_multi(self,small_url,folder_path,folder_id,pageCount): for img_num in range(0,pageCount): work_name = folder_id + '-' + str(img_num) + small_url[-4:] jpg_judge_path = folder_path + '\\' + work_name if os.path.exists(jpg_judge_path) == True and os.path.getsize(jpg_judge_path) != 58: print(jpg_judge_path,'已存在且字节数不为58!') else: multi_url = 'https://www.pixiv.net/member_illust.php?mode=manga_big&illust_id=' +folder_id + '&page=' + str(img_num) self.headers['User-Agent'] = random.choice(self.user_agent_list) try: multi_html = self.request(multi_url) multi_html_soup = BeautifulSoup(multi_html.text, 'lxml') img_url = multi_html_soup.find('img')['src'] #要请求src的地址再写入 img_html = self.request(img_url) self.down(img_html,work_name,jpg_judge_path) except: print(work_name,'下载失败') 7、动图P站动图其实只是多个图片设置页面停留时间而已,所以需要我们手动合成。 1.在动图的源文件地址(是个 zip 文件),里面有关于每个图片的 delay (也就是页面停留时间)和图片文件。2.下载 zip,解压,用 imageio 进行合成,指定合成 gif 的帧率为 delay 就行了 但是存在一个问题,有些动图的每个图片设置的页面停留时间不同,这就让人很难搞了 12345678910111213141516171819202122232425262728293031323334353637import imageio# from PIL import Image# 记得没有用到PIL,但防止意外,我就先放这里了# 获取压缩包网址zip_url = 'https://www.pixiv.net/ajax/illust/' +folder_id + '/ugoira_metazip_html = self.request(zip_urlzip_json = json.loads(zip_html.text)zip_originalSrc = zip_json["body"]["src"]# 计算帧率delay = 1/(zip_json["body"]["frames"][0]['delay']/1000) #80(ms)/1000 -> 0.08(s)print('帧率:',delay)# 下载zipheaders['Referer'] = 'https://www.pixiv.net/member_illust.php?mode=medium&illust_id=' + folder_idgif_html = self.request(zip_originalSrc)zip_name = folder_id + '.zip'f = open(zip_name, 'ab')f.write(gif_html.content)f.close()# 解压zipf = zipfile.ZipFile(zip_name,'r') for file in f.namelist(): f.extract(file,".")f.close()print('解压完成')os.remove(zip_name) # 删除压缩包gif_name = folder_id + '.gif' # gif图片nameframes = [] # 用来存储要进行合成gif的图片files = os.listdir(folder_path) # 扫描当前作品目录下的文件print('开始合成')for image_num in range(1,len(files)): frames.append(imageio.imread(files[image_num]))imageio.mimsave(gif_name, frames, 'GIF', fps = delay) # 间隔print(folder_id,'动图下载完成!')# 删除解压出的图片for file in files: os.remove(file) 8、最后 鸽了挺久的,觉得大部分东西代码和实践都说得清楚,毕竟不是教程贴ヽ(ー_ー)ノ github地址、文中代码不一定能直接执行,复制粘贴的。]]></content>
<tags>
<tag>python</tag>
<tag>爬虫</tag>
<tag>lxml</tag>
<tag>requests</tag>
<tag>pixiv</tag>
</tags>
</entry>
<entry>
<title><![CDATA[PythonDailyQuestion-0603]]></title>
<url>%2Fblog%2F2019%2F06%2F04%2Fpythondailyquestion-0603%2F</url>
<content type="text"><![CDATA[本篇概述:0603-每日一问 Tipsgithub:https://github.com/Elegant-Smile/PythonDailyQuestion 1、基础题 列表sent = [‘she’, ‘sells’, ‘sea’, ‘shells’, ‘by’, ‘the’, ‘sea’, ‘shore’]。编写代码执行以下任务:a. 输出所有 sh 开头的单词b. 输出所有长度超过 4 个字符的词 12sent = ['she', 'sells', 'sea', 'shells', 'by', 'the', 'sea', 'shore']print([s for s in sent if s.startswith('sh') and len(s)>4]) 2、提高题 在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。 123456789101112131415161718import randomx = []n = input('数组长度为:')# 1. 生成数组for i in range(int(n)): x.append(random.choice(range(n)))# 2. 生成数组while len(x) != n: x.append(random.choice(range(n))) if len(x) == n: break# 输出第一个重复的数字 for x1 in x: if x.count(x1) >= 2: print('第一个重复的数字为',x1) break]]></content>
<categories>
<category>每日一问</category>
</categories>
<tags>
<tag>python</tag>
<tag>每日一问</tag>
</tags>
</entry>
<entry>
<title><![CDATA[PythonDailyQuestion-0530]]></title>
<url>%2Fblog%2F2019%2F05%2F31%2Fpythondailyquestion-0530%2F</url>
<content type="text"><![CDATA[本篇概述:0530-每日一问 Tipsgithub:https://github.com/Elegant-Smile/PythonDailyQuestion 1、基础题 设计一个复利计算函数invest()它包含三个参数:amount(资金),rate(年利率),time(投资时间)。键盘输入每个参数后,输出结果:返回每一年的资金总额比如,amount = 10000 , rate = 8% ,time = 5 (复利计算公式原理自行百度) 12345678910def invest(): amount = int(input('input your amount:')) rate = float(input('rate is:')) time = int(input('your cycle is:')) for i in range(1,time+1): amount *= (1+rate) print('第{}年 : {}'.format(i,amount)) if __name__ == "__main__": invest() 2、提高题 请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy则经过替换之后的字符串为We%20Are%20Happy。 123456# 1.print('We Are Happy'.replace(' ','%20'))# 2.import reprint(re.sub(r' ','%20','We Are Happy'))]]></content>
<categories>
<category>每日一问</category>
</categories>
<tags>
<tag>python</tag>
<tag>每日一问</tag>
</tags>
</entry>
<entry>
<title><![CDATA[PythonDailyQuestion-0529]]></title>
<url>%2Fblog%2F2019%2F05%2F31%2Fpythondailyquestion-0529%2F</url>
<content type="text"><![CDATA[本篇概述:0529-每日一问 Tipsgithub:https://github.com/Elegant-Smile/PythonDailyQuestion 1、基础题12345809*x=800*x+9*x x代表的是两位数 8*x的结果为2位数 9*x的结果为3位数求x及809×x结果 代码如下: 1234for x in range(10,100): if (10<=8*x<=100) and (100<=9*x<=1000): print(809*x)# 9708 2、提高题 1.对文件”命运.txt”进行字符频次统计,并将所有字符按照频次高低排序,将排序后的字符及其频次输出到文件”命运-频次排序.txt” 字符包括中文、英文、标点等,但不包括空格和回车输出格式要求:(1)字符与频次之间采用冒号 :分隔(2)一个字符一行,比如理:224斯:120卫:100 12345678910111213141516f = open(r'命运.txt','r')m = f.read().replace('\n','')target = {}for word in m: target[word] = target.get(word,0) + 1# print(target)# 排序target = sorted(target.items(),key=lambda x:x[1],reverse=True)with open('命运-频次排序.txt','w',encoding='utf8') as output: for tar,count in target: output.write('{}:{}\n'.format(tar,count))f.close() 命运.txt下载 链接:https://www.lanzous.com/b757208/ 密码:f0il]]></content>
<categories>
<category>每日一问</category>
</categories>
<tags>
<tag>python</tag>
<tag>每日一问</tag>
</tags>
</entry>
<entry>
<title><![CDATA[PythonDailyQuestion-0528]]></title>
<url>%2Fblog%2F2019%2F05%2F31%2Fpythondailyquestion-0528%2F</url>
<content type="text"><![CDATA[本篇概述:0528-每日一问 Tipsgithub:https://github.com/Elegant-Smile/PythonDailyQuestion 1、基础题 从键盘输入4个数字,各数字采用空格分隔,对应为变量x0,y0,x1,y1。计算(x0,y0)和(x1,y1)两点之间的距离,输出结果保留1位小数。比如,键盘输入:0 1 3 5,屏幕输出:5.0 1234a = input('input your number:').split()x0,y0,x1,y1 = int(a[0]),int(a[1]),int(a[2]),int(a[3])target = float(((y0-y1)**2+(x0-x1)**2)**0.5)print(target) 2、提高题 键盘输入小明学习的课程以及考试分数信息,信息之间采用空格分隔,每个课程一行,空格回车结束录入,示例格式如下:数学 90语文 95英语 86物理 84生物 87输出得分最高和最低的课程名称、考试分数,以及所有课程的平均分(保留2位小数)格式如下:最高分课程是语文 95,最低分课程是物理 84,平均分是88.4 12345678910111213141516171819c_s_list = {} # class & scoresum = 0 # 均值while True: a = input('input your class && score:') if a == 'esc': for key,value in c_s_list.items(): print(key,value) sum += int(value) # 均值 max_min = sorted(c_s_list.items(),key=lambda s:s[1]) print('\n得分最高的课程名称:{}考试分数:{}'.format(max_min[-1][0],max_min[-1][1])) print('得分最低的课程名称:{}考试分数:{}'.format(max_min[0][0],max_min[0][1])) print('均值:%.1f'%(sum/len(c_s_list))) break else: b = a.split() c_s_list[b[0]] = b[1]]]></content>
<categories>
<category>每日一问</category>
</categories>
<tags>
<tag>python</tag>
<tag>每日一问</tag>
</tags>
</entry>
<entry>
<title><![CDATA[OS模块实战-1-目录统计]]></title>
<url>%2Fblog%2F2019%2F05%2F09%2Fos-mo-kuai-shi-zhan-1%2F</url>
<content type="text"><![CDATA[本篇概述:OS模块实战-1-目录统计]]></content>
<categories>
<category>python</category>
</categories>
<tags>
<tag>python</tag>
<tag>OS</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Python模块之OS]]></title>
<url>%2Fblog%2F2019%2F05%2F09%2Fmodel-os%2F</url>
<content type="text"><![CDATA[本篇概述:os模块常用方法汇总 os模块——操作系统的接口12import osdir(os) 1、os.listdir(path)☆123# 如果path=None,则返回当前目录下的文件夹和文件名字的列表;否则返回指定path的件夹和文件名字的列表os.listdir()os.listdir(path) 2、os.chdir(path)☆12# 切换到pathos.chdir(path) 3、os.getcwd()☆1os.getcwd() 4、os.path.join()☆12345# 拼接路径path1 = 'C:\\Users\\Hatsune Miku\\Desktopath2 = 'test1.py'os.path.join(path1,path2)# C:\\Users\\Hatsune Miku\\Desktop\\test1.py 5、os.path.exists(path)☆1234# 判断路径是否存在,返回True或Falseos.path.exists('.')os.path.exists('.\\ssss')# True False 6、os.path.abspath(path)☆12345# 返回path的绝对路径。os.path.abspath('.') # 返回当前目录# C:\\Users\\Hatsune Miku\\Desktopos.path.abspath('.\\1102')# 'C:\\Users\\Hatsune Miku\\Desktop\\1102 7、os.path.split(path)☆123456789# 将路径分解为文件夹和文件名,返回的是元组os.path.split('C:\\Users\\Hatsune Miku\\Desktop\\test1.py')# ('C:\\Users\\Hatsune Miku\\Desktop', 'test1.py')# 仅分离文件夹路径时需要注意的是,所以需要在文件夹后加上/os.path.split('C:\\Users\\Hatsune Miku\\Desktop\\')os.path.split('C:\\Users\\Hatsune Miku\\Desktop')# ('C:\\Users\\Hatsune Miku\\Desktop', '')# ('C:\\Users\\Hatsune Miku', 'Desktop') 8、os.path.dirname(path)☆123# 返回path中的文件夹部分,结果不包含'\',返回的是stros.path.dirname('C:\\Users\\Hatsune Miku\\Desktop\\test1.py')# C:\\Users\\Hatsune Miku\\Desktop 9、os.path.basename(path)☆123# 返回path中的文件名部分os.path.basename('C:\\Users\\Hatsune Miku\\Desktop\\test1.py')# test1.py 10、os.path.getmtime(path)123# 文件夹或文件的最后修改时间,返回的是从新纪元到访问时的秒数os.path.getmtime('C:\\Users\\Hatsune Miku\\Desktop\\test1.py')# 1556017564.1900363 11、os.path.getatime(path)123# 文件夹或文件的最后访问时间os.path.getmtime('C:\\Users\\Hatsune Miku\\Desktop\\test1.py')# 1555867584.470328 12、os.path.getacime(path)123# 文件夹或文件的创建时间os.path.getatime('C:\\Users\\Hatsune Miku\\Desktop\\test1.py')# 1555867584.470328 13、os.path.getsize(path)☆123456789# 文件夹或文件的大小,若是文件夹返回0,是文件则返回字节数os.path.getsize('C:\\Users\\Hatsune Miku\\Desktop\\test1.py')# 2419# 46.6M的文件,字节数为48877195print(48877195/float(1024*1024))print('%.2f'%(48877195/float(1024*1024)))# 46.61292552947998# 46.61 14、os.makedirs()☆12# 创建文件夹os.makedirs('C:\\Users\\Hatsune Miku\\Desktop\\testtesttest') 15、os.system()1234# 运行sheel命令,无返回值os.system('ipconfig')a = os.system('ipconfig')# 0 16、os.popen()123456# 执行命令并把 执行的cmd的输出结果 返回# os.popen(cmd,mode,bufsize) 命令,权限,需要的缓冲大小a = os.popen('ipconfig')a.read()# a 返回一个文件描述符号为fd的打开的文件对象# a.read()是字符串 17、os.remove(path)☆12# 删除文件路径os.remove(path) 18、os.rename(src,dst)12# 将文件或目录src重命名为dst# 将'tess1'文件夹重命名为'test2' 19、os.getenv()12# 获得环境变量os.getenv('path') 20、os.walk()1234567891011121314151617181920212223242526# os.walK()是一个简单易用的目录遍历器,用于在目录树中游走输出在目录中的文件名# 返回的是一个三元元组,(root,dirs,files)# root 当前遍历的目录路径# dirs 当前目录下的文件夹(列表)# files 当前目录下的文件(列表)# .代表当前目录路径for root,dirs,files in os.walk('.'): print(root) print(dirs) print(files) # 先返回当前目录的三元元组,再返回子目录的,有子子目录则亦然 # 计算一个文件夹的大小 ↓ # 首先遍历当前目录然后是子目录 # 遍历目录时可以先通过os.path.join拼接路径,用os.path.getsize()获得文件的大小,使用遍历则获得一个文件夹下的所有文件的大小——>即这个文件夹的大小 # 1.size = 0for root,dirs,files in os.walk(path): for name in files: size += os.path.getsize(os.path.join(root, name)) # 2.size = 0for root,dirs,files in os.walk(path): size += sum([os.path.getsize(os.path.join(root, name)) for name in files])]]></content>
<categories>
<category>python</category>
</categories>
<tags>
<tag>python</tag>
<tag>OS</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Others-你相信这个世界能加速吗?]]></title>
<url>%2Fblog%2F2019%2F04%2F25%2Frang-xia-zai-su-du-de-dao-jie-fang%2F</url>
<content type="text"><![CDATA[本篇概述:重新整理了一下关于度盘的黑科技 整理的时候发现 度盘下载器 的作者不维护了╮(╯▽╰)╭,今天也换了多个文件试了下貌似都是HTTP响应超时字样,详见https://www.linesoft.top/archives/4/ 毕竟也是陪伴多年的好朋友,献上一朵❀❀(绝对不是因为其他3作更好用一点的原因) 那么以下3作推荐给大家 加速世界——你相信这个世界能加速吗?加速通道 1加速通道 2加速通道 3proxyee-down 简介:Proxyee Down 是一款开源的免费 HTTP 高速下载器,底层使用netty开发,支持自定义 HTTP 请求下载且支持扩展功能,可以通过安装扩展实现特殊的下载需求。使用手册 预览: github地址:github 直接下载地址(建议看一遍使用手册):地址 PanDownload 简介:百度盘第三方下载工具 预览: 地址:PanDownload 密码:co50 SpeedPan 简介:SpeedPan又名速盘,一款百度网盘满速下载工具利器 预览: 地址:SpeedPan 密码:7rn6]]></content>
<categories>
<category>软件分享</category>
</categories>
<tags>
<tag>软件分享</tag>
<tag>Others</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Python-Mysql基本使用]]></title>
<url>%2Fblog%2F2019%2F04%2F22%2Fpy-mysql%2F</url>
<content type="text"><![CDATA[本篇概述:记录python——mysql的一些操作 1、MySQLdbpython连接mysql用的模块。MySQLdb主要还是聚焦于如何和数据库进行连接和进行基本的操作,操作的体现形式主要还是进行SQL语句的执行。 安装 1pip3 install mysqlclient 2、基本使用1、数据库连接123456import MySQLdb# 连接数据库 ——> 主机host,端口,用户,密码,数据库,编码conn = MySQLdb.connect(host='localhost',port=3306,user='你的账号',passwd='你的密码',db='你要操作的数据库',charset='utf8')# 连接成功后,创建一个游标对象用于操作数据库# 获取到游标后再进行数据库操作cur = conn.cursor() 2、查询12345678910111213141516171819202122# 查询cur.execute("SELECT VERSION()") # 这里不返回结果,只是执行version = cur.fetchall()# 返回的是元组 (('5.7.14',),)# fetchall() 是返回所有匹配 的元组,接收全部的返回结果行# fetchone() 只返回一个匹配的元组,然后游标后移# 我这里用了自己数据库中的一个表演示fetchall()和fetchone()# 1. fetchall()cur.execute("SELECT * from test")a = cur.fetchall()print(a,len(a))# 这里数据量太大,结果就不放出来了# 2. fetchone()cur.execute("SELECT * from test")data = cur.fetchone()i = 0while i<10: print(data) i += 1 data = cur.fetchone() 附图 3、插入12345678910111213141516171819202122232425262728# 插入# sql语句,%s占位sql = "INSERT INTO test(date,tag,title,link) VALUES(%s,%s,%s,%s)"# 1. 插入一条execute() data是元组data = ('19/02/14', 'Android', 'Android\xa0fdget()\xa0优化导致的\xa0binder\xa0UAF\xa0漏洞(CVE-2019-2000)\xa0:', 'https://bugs.chromium.org/p/project-zero/issues/detail?id=1719')try: cur.execute(sql,data) # 事务commit后才会真正插入数据 conn.commit()except Exception,e: # 出错回滚 conn.rollback()finally: cur.close() conn.close() # 断开数据库连接 # 2. 批量插入executemany()datas = [('19/02/14', 'Android', 'Android\xa0fdget()\xa0优化导致的\xa0binder\xa0UAF\xa0漏洞(CVE-2019-2000)\xa0:', 'https://bugs.chromium.org/p/project-zero/issues/detail?id=1719'),('19/02/14', 'IoTDevice', '以家庭路由为例讲解 IoT 逆向工程:', 'http://va.ler.io/myfiles/dva/iot-rev-engineering.pdf')]try: cur.executemany(sql,datas) conn.commit()except Exception,e: # 出错回滚 conn.rollback()finally: cur.close() conn.close() # 断开数据库连接 4、修改,更新12345678910# sqlsql = "UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = '%c'" % ('M')try: cur.execute(sql) conn.commit()except: conn.rollback()finally: cur.close() conn.close() 5、删除12345678910# sql 删除数据,年龄大于20sql = "DELETE FROM EMPLOYEE WHERE AGE > %s" % (20)try: cur.execute(sql) conn.commit()except: conn.rollback()finally: cur.close() conn.close()]]></content>
<categories>
<category>python</category>
</categories>
<tags>
<tag>python</tag>
<tag>mysql</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Python爬虫/GUI编程之签名生成器]]></title>
<url>%2Fblog%2F2019%2F04%2F19%2Fsignature-generator%2F</url>
<content type="text"><![CDATA[本篇概述:主要记录爬虫+GUI制作签名生成器 1、爬虫实现 暂时留空,本篇先解析代码 2、GUI实现 暂时留空,本篇先解析代码 3、代码github地址:https://github.com/Coder-Sakura/Signature-generator 1. uustv.py ——> 爬虫模块点我可以将内容伸缩哦~ ٩(๑>◡<๑)۶ 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061import requestsimport timefrom bs4 import BeautifulSoupfrom tkinter import messageboxfrom tkinter import * # PhotoImageclass Spider(object): # 初始化,包括请求头,url,支持的字体、字号,需要生成签名的文字 def __init__(self): self.headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36', } self.url = 'http://m.uustv.com/' self.values = ['个性签','连笔签','潇洒签','草体签','合体签','商务签','可爱签'] self.font = ['jfcs.ttf','qmt.ttf','bzcs.ttf','lfc.ttf','haku.ttf','zql.ttf','yqk.ttf'] self.v_f = dict(zip(self.values,self.font)) self.word = '' self.fonts = '' self.size = 60 # 接受GUI页面传来的参数,首先检查是否为空,其次是选择的字体大小 def check(self,part,enter,numberChosen,sizesChosen): self.part = part self.word = enter.get() self.fonts = numberChosen.get() # 文字 self.size = sizesChosen.get() if not enter.get(): messagebox.showinfo('提示','请输入需要生成签名的文字') else: if self.fonts in self.v_f: self.fonts = self.v_f[self.fonts] # 文字转换成字体格式名称 # messagebox.showinfo('提示',word) # messagebox.showinfo('提示',fonts) self.post_img() # 发送请求,获取图片地址,并捕获图片数据返回 def post_img(self): data = { 'word': self.word, 'sizes': self.size, 'fonts': self.fonts, 'fontcolor': '#000000'} html = requests.post(url=self.url,data=data,headers=self.headers) html_soup = BeautifulSoup(html.text,'lxml') img_url = self.url + html_soup.find('div',attrs={'class':'tu'}).find('img')['src'] print(img_url) img_html = requests.get(url=img_url,headers=self.headers) img_html.encoding = 'utf8' self.down(img_html) # 下载图片 def down(self,img_html): f = open('{}.gif'.format(self.word),'wb') f.write(img_html.content) f.close() self.view_img() # 将图片展示到GUI页面 def view_img(self): image = PhotoImage(file='{}.gif'.format(self.word)) label2 = Label(self.part,image=image) label2.bm = image label2.grid(row=3,columnspan=2) 2. uustv_gui.py点我可以将内容伸缩哦~ ٩(๑>◡<๑)۶ 123456789101112131415161718192021222324252627282930313233343536373839404142434445from tkinter import *from tkinter.ttk import Comboboxfrom uustv import *class GUI(object): def __init__(self): self.window_title = '签名生成器--网络精英--2019.04.12' self.label_text = '输入签名字样' self.button_text = '点击生成' self.values = ['个性签','连笔签','潇洒签','草体签','合体签','商务签','可爱签'] self.sizes = [10,20,30,40,50,60,70] # GUI def parts(self): # 部件 part = Tk() # 封装对象 part.title(self.window_title) # 标题 part.geometry('545x330') # 窗口大小 # 定义label,文字区域,只能看不能点,设置文字,文字字体和文字大小 label1 = Label(part,text='设计字样',font=('华文行楷',20)) label1.grid() # 定义布局格式,grid()表示网格格式 # 输入框 enter = Entry(part,font=('微软雅黑',20)) enter.grid(row=0,column=1) # 字体样式选择 numberChosen = Combobox(part, width=12, state='readonly') numberChosen['values'] = self.values numberChosen.current(0) numberChosen.grid(row=1,column=0) # 字体大小选择 sizesChosen = Combobox(part, width=12, state='readonly') sizesChosen['values'] = self.sizes sizesChosen.current(5) sizesChosen.grid(row=1,column=1) # 按钮,当按下按钮时,携带参数至指定函数 button = Button(part,text='点击生成',font=('微软雅黑',20),command=lambda: Spider().check(part,enter,numberChosen,sizesChosen)) button.grid(row=2,column=0) part.mainloop()gui = GUI()gui.parts() 3. 生成软件123456789# 1.首先安装pyinstallerpip3 install pyinstaller# 2.在2个py的所在目录调出cmd,输入以下命令:pyinstaller -F -w uustv.py uustv_gui.py# 在生成的文件夹中找到dict文件夹,其下有exe文件,便是最终的签名生成器# 3.如果需要自定义软件图标,需要自己准备好适当尺寸的ico格式图片# 打包的时候使用-i xxx.ico 来指定自定义的ico图标]]></content>
<categories>
<category>python</category>
</categories>
<tags>
<tag>python</tag>
<tag>爬虫</tag>
<tag>tkinter</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Python爬虫-pixiv关注画师作品[2]]]></title>
<url>%2Fblog%2F2019%2F03%2F30%2Fpixiv-two%2F</url>
<content type="text"><![CDATA[本篇概述:上篇的后续;主要是分析数据接口,拿到关注画师的所有作品的详细信息 1、分析——关注界面 关注界面(默认公开) https://www.pixiv.net/bookmark.php?type=user&rest=show 这里关注画师全在公开界面,虽然非公开获取也是ok的 公开和非公开只是,https://www.pixiv.net/bookmark.php?type=user&rest=show 后面分别是rest=show 和 rest=hide F12 查看 Elements ,寻找画师列表和页数 画师列表全在一个 class=members 的 div 中 画师信息在user-data中,有作者 id、主页 url、作者 name 最大页数在一个 class=_pager-complex 的 div,倒数第二个li 2、代码——bs4匹配1234# 找到最大页数max_num = attention_html_soup.find('div', attrs={'class', '_pager-complex'}).find_all('li')[-2].text # 画师个人信息painter_information = attention_html_soup.find('div', attrs={'class', 'members'}).find_all('div', attrs={'class', 'userdata'}) 3、代码——获取关注画师的信息123456789101112131415161718192021#获取关注画师界面的信息def attention_html(self): # self.return_to = 'https://www.pixiv.net/bookmark.php?type=user&rest=show&p=' # p 是页数 attention_html = self.request(self.return_to) attention_html_soup = BeautifulSoup(attention_html.text, 'lxml') #获取最大页数 max_num = attention_html_soup.find('div', attrs={'class', '_pager-complex'}).find_all('li')[-2].text print('最大页数为%s' % (max_num)) for num in range(1,int(max_num)+1): attention_html_url = self.return_to + str(num) # 构造每个页面的 url attention_html = self.request(attention_html_url) attention_html_soup = BeautifulSoup(attention_html.text,'lxml') painter_information = attention_html_soup.find('div', attrs={'class', 'members'}).find_all('div', attrs={'class', 'userdata'}) #画师个人信息 for painter in painter_information: # userdata下的a标签中的data-user_id = 作者id painter_id = painter.a['data-user_id'] # userdata下的a标签中的data-user_name = 作者name name = painter.a['data-user_name'] print('{0}:{1}'.format(name,painter_id)) print('已获取所有关注画师的作品信息!!!!') 对于文笔不好的人来说,还是上代码来的舒服 毕竟 talk is cheap, show me code ! 4、分析——画师个人主页及数据流向 这里说下,为什么不获取 user-data 里面的 href 属性? 正常流程不应该是拿到 href 然后访问 url,获取源码,然后拿到作品信息。 原因是:这里用的是Ajax请求,所以源码中并没有我们想要的数据 我们可以直接通过接口拿到这个画师的所有作品的数据。 该画师有73个作品,但是点击进入主页发现只有小小的一部分 勾上 Preserve log,点击查看全部 新加载的页面显示了所有的作品(虽然分为2页) 与之前的 XHR 比较,接下来的目标在红框标出来的三个文件(不一定全是我们的目标) 点击第一个illust,发现 Preview 里是标签 tags (json数据) 点击第二个illust,Preview 里是作品信息 (json数据) 确定了第二个 illust 是目标之后,模仿它进行请求 但是发现他的 url 是一串巨长的字符串,由 一页的所有作品 id 和 is_manga_top=0 拼接而成 url 中作品 id 的拼接顺序是由新到旧(也就是数字大的在前面) 1url = https://www.pixiv.net/ajax/user/1117751/profile/illusts?ids%5B%5D=73742388&ids%5B%5D=71855085&ids%5B%5D=71849582&ids%5B%5D=71685985&ids%5B%5D=68213121&ids%5B%5D=67765964&ids%5B%5D=67758280&ids%5B%5D=67757922&ids%5B%5D=67619936&ids%5B%5D=67404010&ids%5B%5D=66856979&ids%5B%5D=65998170&ids%5B%5D=65834643&ids%5B%5D=65393332&ids%5B%5D=63861794&ids%5B%5D=63761535&ids%5B%5D=63617575&ids%5B%5D=63475838&ids%5B%5D=63090307&ids%5B%5D=62347061&ids%5B%5D=62200016&ids%5B%5D=62178209&ids%5B%5D=61785521&ids%5B%5D=61656195&ids%5B%5D=61489588&ids%5B%5D=60732958&ids%5B%5D=60588424&ids%5B%5D=60384884&ids%5B%5D=59959669&ids%5B%5D=59706889&ids%5B%5D=59656129&ids%5B%5D=59541311&ids%5B%5D=59180046&ids%5B%5D=58977788&ids%5B%5D=58919004&ids%5B%5D=58029173&ids%5B%5D=57027442&ids%5B%5D=57027347&ids%5B%5D=56527887&ids%5B%5D=56525716&ids%5B%5D=56309403&ids%5B%5D=56110382&ids%5B%5D=55934890&ids%5B%5D=55680445&ids%5B%5D=54917440&ids%5B%5D=54900477&ids%5B%5D=54900429&ids%5B%5D=54900380&is_manga_top=0 下一步目标:既然有所有作品 id 拼接成的 id ,说明是有接口获取所有作品 id 的。 5、模仿请求 在 XHR 中继续寻找,发现一个叫 all 文件,点开 Preview (json数据) all 的 Request URL: https://www.pixiv.net/ajax/user/1117751/profile/all ,/user/后面的数字是作者的 id 在 Preview 中发现 illusts (插画)属性 ,下面的应该就是作品 id 了,可以自己复制一个去验证一下。 补充:有些画师在 manga (漫画)属性也是有值的,所以这里需要和前面的 illusts 属性合并 Request URL 放到浏览器中去访问,将访问结果复制到 json.cn 进行格式化 6、代码——获取关注画师的所有作品信息 获得关注画师的信息,比如 id、name 通过 https://www.pixiv.net/ajax/user/[画师id]/profile/all 来获取画师的所有作品 id (单图 动图 多图 都在 illusts 属性中,漫画虽然是单图和多图,但在 manga属性 中) 接着通过构造作品 id 和 is_manga_top=0 的 url 去请求作品的详细信息 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485# 获取关注画师界面的信息def attention_html(self): # self.return_to = 'https://www.pixiv.net/bookmark.php?type=user&rest=show&p=' # p 是页数 attention_html = self.request(self.return_to) attention_html_soup = BeautifulSoup(attention_html.text, 'lxml') # 获取最大页数 max_num = attention_html_soup.find('div', attrs={'class', '_pager-complex'}).find_all('li')[-2].text print('最大页数为%s' % (max_num)) for num in range(1,int(max_num)+1): attention_html_url = self.return_to + str(num) # 构造每个页面的 url attention_html = self.request(attention_html_url) attention_html_soup = BeautifulSoup(attention_html.text,'lxml') painter_information = attention_html_soup.find('div', attrs={'class', 'members'}).find_all('div', attrs={'class', 'userdata'}) #画师个人信息 for painter in painter_information: # userdata下的a标签中的data-user_id = 作者id painter_id = painter.a['data-user_id'] # userdata下的a标签中的data-user_name = 作者name name = painter.a['data-user_name'] print('{0}:{1}'.format(name,painter_id)) # 构造url来获取作者的所有作品 id ajax_url = 'https://www.pixiv.net/ajax/user/{0}/profile/all'.format(painter_id) self.painter_picture(painter_id,ajax_url,name) print('获取所有关注画师信息完成!!!!') # 执行 painter_picture() 应在 attention_html() 的 painter_information 循环中# self.painter_picture(painter_id,ajax_url,name)def painter_picture(self,painter_id,ajax_url,name): ajax_html = self.request(ajax_url) # 使用json.loads()方法加载进来 ajax_json = json.loads(ajax_html.text) ajax_illusts = ajax_json["body"]["illusts"] ajax_manga = ajax_json["body"]["manga"] # 判断是否有 manga 类型的作品 if len(ajax_manga) == 0: total_data_dict = dict(ajax_illusts) else: # 合并 manga 和 illusts,并转换为字典 total_data_dict = dict(ajax_illusts, **ajax_manga) # 字典格式:id:None,所以取字典的keys,并转化为list total_data = list(total_data_dict.keys()) # 这里为什么要排序呢? # 返回的json里id是从小到大,我们只要[::-1]反转,不就大到小了吗? # 但是有些画师的作品是有分illusts和manga的,大概就是普通作品(单、多、动)和漫画类型 # 为了防止没拿到漫画类型作品的id,我使用dict(,**)来合并字典 # 这样做是追加到前一个字典的尾部,所以我们必须排序才能正确请求到每一页的48个作品 # 这里用的是冒泡排序(从小到大),刚好学到就用了 for x in range(len_total-1): for y in range(len_total-1-x): if total_data[y] > total_data[y+1]: total_data[y],total_data[y+1] = total_data[y+1],total_data[y] # 从大到小排序的作品id total_data = total_data[::-1] # 按每48个分组,画师每页显示48个作品 limit_num = 48 # after_grouping_list = [[xxx,xxx,xxx],[48个id],[...]...] after_grouping_list = [total_data[i:i+limit_num] for i in range(0,len(total_data),limit_num)] print('画师',name,'作品有:',len(after_grouping_list),'页') # 开始根据作品id来拼接url(就是那个一大串的url) count = 0 # 每拼接完48个+1 for grouping_list in after_grouping_list: ids_big = 'https://www.pixiv.net/ajax/user/{}/profile/illusts?'.format(painter_id) for work_id in grouping_list: ids = 'ids%5B%5D=' + work_id + '&' ids_big = ids_big + ids works_url = ids_big + 'is_manga_top=0' count += 1 print('第%s页的works_url:%s' % (count,works_url)) # 发起请求获得第count页作品的详细信息 works_html = self.request(works_url) works_json = json.loads(works_html.text) works_data = works_json["body"]["works"].values() for x in works_data: title = x['title'] folder_id = x['id'] tags = x['tags'] small_url = x['url'] pageCount = x['pageCount'] print('\n作品id:{0}\t作品页数:{1}'.format(folder_id,pageCount)) print('作品标题:{0}'.format(title)) print('作品标签:{0}'.format(tags)) print('作品250*250图片地址:{0}'.format(small_url)) works_data = works_json[“body”][“works”].values() 因为 keys() 是作品 id,values() 里面也有,所以直接 values() 就好了 7、最后 本篇主要是分析数据接口,拿到关注画师的所有作品的详细信息 那么下篇再根据单图动图多图进行图片下载,预计文件存储、其他的小功能和最后的代码汇总得放在下下篇了。 へ( ̄  ̄;へ)]]></content>
<categories>
<category>python</category>
</categories>
<tags>
<tag>python</tag>
<tag>爬虫</tag>
<tag>lxml</tag>
<tag>requests</tag>
<tag>pixiv</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Python爬虫-pixiv关注画师作品[1]]]></title>
<url>%2Fblog%2F2019%2F03%2F27%2Fpixiv-one%2F</url>
<content type="text"><![CDATA[本篇概述:大概有几篇是关于pixiv关注画师的作品抓取的思路和代码,后面大概还会有p站个人收藏的爬虫(这个比较简单) 1、pixiv介绍 Pixiv 这是一个墙外的网站,需要正确的扶梯姿势和科学上网 当然也可以参考我的方法(nginx + 修改 hosts 文件) 地址:点击前往 密码:3235 (建议 hosts 文件取自己需要的那部分) 为什么选 pixiv 呢?其实在12月份的时候我刚开始学 python,这个 pixiv 的小项目是我自己突发奇想要做的,那时候是新年前一周左右,对于那时候的我来说,pixiv 反爬难度一般般,但比较难的数据接口分析、构造url、文件操作、代理、图片合成等(自己一个人盯了这个网站几天,最后完成超级兴奋!) Pixiv登录绕过——2020.7.22更新使用Selenium获取在Chrome浏览器上登录的Pixiv账号的cookie,从而绕过Google V3人机验证 链接:http://00102400.xyz/blog/2019/08/29/pixiv-new-login/ nginx+ 改host上P站教程——2019.5.24更新已失效——2020.7.22 下载上面链接中的压缩包,解压 复制hosts文件中的代码,追加到当前电脑的hosts文件中 当前电脑的hosts文件在C:\Windows\System32\drivers\etc目录下,如果没找到的话可以搜索一下或者用everything软件(强烈建议!)进行搜索. 打开调试工具(这个功能全).bat 选择对应的数字序号 Tip 如果正常启动不行的话,可以尝试以下代码 123netstat -aon | findstr ":443"# 找到占用了443端口的程序的PID# 可能是本机虚拟机占用了这个端口 或者手动修改nginx的端口,具体修改流程百度 2、Target 登录账号关注的画师的作品 思路: 首先是模拟登录(PC 用过 pixiv 的同学都知道在未登录的时候 pixiv 会对用户做一些限制,所以我们要先模拟登录) 其次保持会话连接(可以考虑 cookie 保存,这里采用的是 requests 的 session 会话连接) (基于图片网站,可能是动态加载,那么需要分析接口或者是 selenium 模拟) 最后才进行网页内容分析,然后抓取保存下来 3、登录模拟实现流程 一、查找登录接口 第一次找关于登录接口的时候,一个login都没看到,只看到一个 www.pixiv.net ,可惜是get请求的页面。 在拜读了 Chrome使用技巧 、Chrome开发者工具使用小技巧 后,算是对 chrome 的调试工具有个大概了解的印象,知道了 preserve log 勾选后,可以保留网络日志,于是发现了真正的登录请求 分析参数 password:个人密码 pixiv_id:个人id post_key:不明字符串 source:pc即电脑端(截图没截全,把return_to漏掉了。。。) return_to:是登录成功后跳转的页面,这个可以自己填,貌似默认是 https://www.pixiv.net/ 那么接下来就是找post_key了 首先pixiv非常友好,所以应该不是js加密,而是在页面中随机生成的。 12345# 其次在点击登录的时候就跳转 url1 ↓# url1 = https://accounts.pixiv.net/login?lang=zh&source=pc&view_type=page&ref=wwwtop_accounts_index# 但是登录请求的 url 是 url2 ↓# url2 = https://accounts.pixiv.net/api/login?lang=zh# 所以猜想 post_key 应该是在前者中生成的。 F12 打开,在 Elements 中 Ctrl + F 查看 post_key 接下来用 BeautifulSoup 匹配 12self.post_key = post_key_soup.find('input') ['value'] # 因为是第一个input标签,而find返回的是第一个符合要求的结果 接着向 url2 发去 post 请求 12345678data = { 'pixiv_id': self.pixiv_id, 'password': self.password, 'return_to': self.return_to, 'post_key': self.post_key}rep = se.post(self.login_url, data=data, headers=self.headers,verify=False)# login_url是上面的 url2# 我这里 return_to 写的是个人关注画师的那个页面的 url 登录代码0702更新代码, 123456789101112131415161718192021222324import requestsfrom bs4 import BeautifulSoupse = requests.session()def login(): base_url = 'https://accounts.pixiv.net/login?lang=zh&source=pc&view_type=page&ref=wwwtop_accounts_index' login_url = 'https://accounts.pixiv.net/api/login?lang=zh' headers = { 'referer': 'https://accounts.pixiv.net/login?lang=zh&source=pc&view_type=page&ref=wwwtop_accounts_index', 'origin': 'https://accounts.pixiv.net', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) ' 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'} post_key_html = se.get(base_url) post_key_soup = BeautifulSoup(post_key_html.text, 'lxml') post_key = post_key_soup.find('input')['value'] print(post_key) #捕获postkey data = { 'pixiv_id': 'xxxx', 'password': 'xxxx', 'return_to': 'https://www.pixiv.net/bookmark.php?type=user&rest=show&p=', 'post_key': post_key } rep = se.post(login_url, data=data, headers=headers,verify=False) print(rep.text) 顺便吐槽下 HTTPS 的证书报警问题 12from requests.packages.urllib3.exceptions import InsecureRequestWarning #强制取消警告requests.packages.urllib3.disable_warnings(InsecureRequestWarning) 4、最后 先到这吧,后面继续写解析关注画师页面(页数),寻找数据接口,单图动图多图下载估计写不到了 へ( ̄  ̄;へ)]]></content>
<categories>
<category>python</category>
</categories>
<tags>
<tag>python</tag>
<tag>爬虫</tag>
<tag>lxml</tag>
<tag>requests</tag>
<tag>pixiv</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Next主题集成 algolia 站内搜索插件]]></title>
<url>%2Fblog%2F2019%2F03%2F26%2Falgolia%2F</url>
<content type="text"><![CDATA[本篇概述:Next主题集成algolia 一、简述 今天添加并完善了下blog的站内搜索(既然next有集成,为何不用呢?) 主要是参考了几篇超级详细的文章 大赞:Hexo+Next集成Algolia搜索、知乎、hexo-algolia 二、如何更新?123456# 删除 public 文件夹hexo clean# 搜集站点的内容并通过 API 发送给 Algoliahexo algolia# 如遇到 ERROR [Algolia] Please set an `HEXO_ALGOLIA_INDEXING_KEY` environment variable to enable content indexing.# export HEXO_ALGOLIA_INDEXING_KEY=[你的API Key] 三、问题枪毙名单1. Not enough rights to update an object near 解决方法:修改Algolia的ACL访问控制列表 将ACL修改为以上所示,文章里的ACL和现在的界面不一样,不知道是我用得少的原因(雾),找了几分钟左右。 2. Please provide an Algolia index name in your hexo _config.yml flle 解决方法:修改index名称 index名称就是在以下这个界面输入的那个index name 3. ERROR [Algolia] Please set an HEXO_ALGOLIA_INDEXING_KEY environment variable to enable content indexing. 这个通常是在hexo algolia的时候出现的问题 其实在上面的文章也有说到,这里简单说一下 1export HEXO_ALGOLIA_INDEXING_KEY=[你的API Key] API Key 是 Search-Only API key 4.ERROR >> You might have used an Admin Key or an invalid Key.第三点中用的是export命令,有时候会出现这个问题,解决方法: 1set HEXO_ALGOLIA_INDEXING_KEY=[你的API Key] 使用set命令设置即可。]]></content>
<categories>
<category>hexo</category>
</categories>
<tags>
<tag>hexo</tag>
<tag>algolia</tag>
<tag>博客搜索功能</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Python爬虫之Xpath]]></title>
<url>%2Fblog%2F2019%2F03%2F13%2Fxpath%2F</url>
<content type="text"><![CDATA[本篇概述:Xpath语法,lxml解析html 一、什么是Xpath? XPath 是 XML 路径语言,主要是在 XML 和 HTML 文档中查找我们想要的信息的语言。 XML 和 HTML 一样也是标记语言,但是 XML 用来传输和存储数据,而 HTML 用来显示数据 二、Xpath工具 Google:Xpath Helper (Google 插件可到下载Crx4Chrom(英文)、插件网、Chrome插件网 下载) Firefox:Try Xpath 每个浏览器一般在应用中心或拓展里都可以下载 Xpath Helper 界面 三、Xpath语法1、路径表达式语法、相对/绝对路径 表达式 路径表达式及描述 节点名称 bookstore,选取 bookstore 下的所有子节点(标签) / /bookstore,从根节点下选取所有 bookstore 节点(子元素) // //bookstore,从全局节点中选择 bookstore 节点 @ //div[@price=‘a’],选择所有 price 属性为 a 的 div . ./input,选择当前节点下的 input 2、谓语html 节点中第一个节点为 1,第二个为 2(需要区分) 表达式 描述 //ul/li[1] 选择 ul 下的第一个 li //ul/li[last()-0] 选择 ul 下的最后一个 li //ul/li[last()-1] 选择 ul 下的倒数第二个 li //ul/li[position()<4] 选择 ul 下前面的 3 个子元素 //ul/li[position()>1] 选择第二个到最后的所有子元素 //li[position()>1] [position()<11] 在(2,+∞)中选择前十个 text() 获取函数文本 @class 获取标签的class 通配符 * /bookstore/*,通配符,匹配 bookstore 下的所有子元素 @* //div[@*],选择所有带有属性的 div 运算符 “|“ —> //title | //ul[@class=‘item_con_list’],选择 title 和对应的 ul 四、使用lxml&xpath解析html123456html1 = etree.parse(index.html) # 可以通过读取html文件的方式html2 = etree.HTML(text) # 也可以将字符串解析为HTML文档result1 = etree.tostring(html2) # 将字符串序列化成HTML文档,会自动补全result2 = html2.xpath('表达式') # 使用xpath语法 五、Example 以腾讯招聘网为例 我们要获取到职位名称、职位类别、人数、地点和发布时间等内容 2019.08.23 网站已变化 1//table//tr 选择到了13个子元素,分别是表头,翻页和底部其他招聘 那么可以往上找父元素,扩大范围 1//table[@class='tablelist']//tr[@class='even'] | //table[@class='tablelist']//tr[@class='odd'] 使用以上表达式,避开表头和翻页 上述表达式虽然精确但是有点冗长,鉴于网站规律性,可以采用以下表达式 1//table[@class='tablelist']//tr[position()>1][position()<11] 上面的表达式写在程序里不加text()来取的话,会返回类似 的结果。 123456789101112from lxml import etreeimport requestsheaders = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'}url = 'https://hr.tencent.com/position.php?lid=2218&start=0#a'html = requests.get(url=url,headers=headers)# html.text未经过编码的字符串,unicode字符串etree_obj = etree.HTML(html.text) # HTML解析的是字符串,所以html.textresult1 = etree_obj.xpath("//table[@class='tablelist']//tr[position()>1][position()<11]//text()")result2 = etree_obj.xpath("//table[@class='tablelist']//tr[position()>1][position()<11]")print(result1)print(result2) 结果可以看到有许多的转义字符,比如:\r、\t 最后将代码处理一下,照此方法可以获取到腾讯招聘的所有职位信息(后面有个坑,比如职位类别是空数据的话,XPath匹配到会自动放弃) 1234567891011121314from lxml import etreeimport requestsheaders = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'}url = 'https://hr.tencent.com/position.php?lid=2218&start=0#a'html = requests.get(url=url,headers=headers)# html.text未经过编码的字符串,unicode字符串etree_obj = etree.HTML(html.text) # HTML解析的是字符串,所以html.textresult = etree_obj.xpath("//table[@class='tablelist']//tr[position()>1][position()<11]//text()")print(result)result2 = [x.strip() for x in result if x.strip() != '']print(result2)result3 = [print(result2[x],result2[x+1],result2[x+2],result2[x+3],result2[x+4]) for x in range(0,len(result2),5)]print(result3) 结果图 本篇代码Github地址:https://github.com/Coder-Sakura/exp/tree/master/xpath]]></content>
<categories>
<category>python</category>
</categories>
<tags>
<tag>python</tag>
<tag>爬虫</tag>
<tag>Xpath</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Git入门]]></title>
<url>%2Fblog%2F2019%2F03%2F03%2Fgit-note%2F</url>
<content type="text"><![CDATA[本篇概述:主要记录git的命令和一些git的知识 一、github介绍github(基佬站)是一个开源代码托管平台(其中当然也有私有项目),也作为一个版本控制系统,让你对代码的版本控制更加简单,不用去担心代码写错了怎么办?有没有备份?专心自己的项目就好。 本文没有关于桌面版的git安装、环境变量配置的教程(安装配置的话百度有很多教程) 二、github功能 可以在上面找到许多开源项目、脚本甚至可以在上面找到一些课程 托管项目。只要连上互联网就可以同步到自己的项目代码或多人跟进项目 利用github和一些开源的博客系统可以搭建个人博客(本博客是hexo+github搭建的) 三、git命令 设置用户名和邮箱,不设置会报“please tell me who you are.”,–global参数表示全局 123git config --global user.name "Your Name" git config --global user.email "email@example.com"git config --list # 检查设置 初始化本地文件夹为git仓库(会生成.git隐藏文件,主要是用于版本控制) 1git init 本地版本管理 123456789101112git add ./[name] # 跟踪文件进入暂存区,.表示当前目录所有文件,也可以指定文件git status # 命令用于显示工作目录和暂存区的状态git commit -m '提交说明' # 将暂存区里的改动给提交到本地的版本库git log --pretty=oneline # 查看最近到最远的提交日志,oneline表示每条输出一行# $ git log --pretty=oneline# f3e98b7f4495c78bf98f2661fad2ae745cd60b63 (HEAD -> master, origin/master) proxy# f3e9....这串就是这次提交的版本号git reset --hard [版本号] # 回退/前进到某个指定版本,版本号可以在git log中找到# 也有快捷的回退命令git reset --hard HEAD^ # 回退到上个版本git reset --hard HEAD^^ # 回退到上上个版本git reset --hard HEAD~100 # 回退到上100个版本 将本地文件提交到github 123456789101112git init git add ./(name) git commit -m 'message'git remote add origin [github仓库地址] # 如果出现错误:fatal: remote origin already exists# 执行 git remote rm origin #删除分支# 再执行 git remote add origin [github仓库地址] #再添加 git push origin master # 推送到github仓库# 如果出现failed to push som refs to…….# 需要将github仓库的文件同步下来先# git pull origin master # pull拉文件下来# 再执行 git push origin master # push推文件上去 四、2019/03/30删除远程仓库的文件,并上传新的文件 12345678910111213# 新建一个文件夹git initgit remote add origin [仓库地址] # git remote rm origingit pull origin master# 然后在本地删除文件git add *git commit -m "del all"git push origin master# 放入新的文件git add *git commit -m "create new file"git push origin master 五、12git remote -v# 查看远程仓库地址]]></content>
<categories>
<category>git</category>
</categories>
<tags>
<tag>git</tag>
</tags>
</entry>
<entry>
<title><![CDATA[python爬虫之代理]]></title>
<url>%2Fblog%2F2019%2F02%2F28%2Fproxy%2F</url>
<content type="text"><![CDATA[本篇概述:代理原理作用,requests设置代理方法以及爬取免费代理的脚本实例 一、代理原理 根据自己理解解读: 客户端设置了代理信息后,客户端向对应的代理站点发出请求(向xxx网站发起请求) 代理站点收到请求之后,就会执行对应的响应动作(执行动作) 代理站点获得xxx网站的响应(得到站点响应) 代理站点根据客户端要求返回对应信息(客户端要求返回Source code,则返回Source code) 二、代理作用 突破自身ip访问限制,比如访问国外站点 爬取对ip访问频率有一定限制的站点 提高访问速度 隐藏真实ip 三、代理网站免费代理ip列表: 含国外ip 方法SEO顾问,89代理,小幻http代理,云代理 不含 西刺,快代理 付费代理尚未了解,此处留空 四、requests设置代理方法requests中有预设好的参数接收代理信息 proxies,这个参数接收的是一个字典对象 因为不知道访问的网站使用的是http协议还是https协议,所以proxies最好2种都有设置 12345proxies = { 'http':92.255.255.78:54628, 'https':92.255.255.78:54628}resp = requests.get(url=url1,headers=headers,proxies=proxies) 五、脚本示例github地址:https://github.com/Coder-Sakura/exp/tree/master/seo_ip 本来我是打算用89代理的api接口,但是测试之后发现可靠性有点低,并且外网ip比较少,所以转用SEO (本次抓取代理ip主要是用在我自己做 pixiv 的小项目上,爬取关注画师的所有作品和自己的收藏作品,后续会整理出来,初学爬虫,有错还请指正) 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556import requestsimport randomimport timefrom lxml import etreefrom bs4 import BeautifulSoupfrom requests.packages.urllib3.exceptions import InsecureRequestWarning # 用于强制取消警告from requests.adapters import HTTPAdapter # 用于强制取消警告requests.packages.urllib3.disable_warnings(InsecureRequestWarning) # 强制取消警告class seo_ip(): def __init__(self): self.headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) ' 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'} self.agent_ip_list = [] def Agent(self,ip_agent_url): html = requests.get(url=ip_agent_url,headers=self.headers,verify=False,timeout=5) html_soup = BeautifulSoup(html.text, 'lxml') # 去除第一个和前25个,26-50为国外ip ip_list = html_soup.find('tbody').find_all('tr')[26:] items = [] print('搜索完成,代理信息如下:') for item in ip_list: ip_port = list(item)[0].get_text() + ':' +list(item)[1].get_text() # list(ip_port)[0]为ip,[1]为端口,[2]响应时间,[3]位置,[4]最后验证时间 print('ip: %s ,响应时间: %ss ,ip位置: %s' % (ip_port,list(item)[2].get_text(),list(item)[3].get_text())) items.append(ip_port) #存储爬取到的ip(需要添加) return items def judge(self,items): # 检验ip活性 # https://ip.seofangfa.com/ print('正在进行代理池ip活性检测......') for item in items: try: proxy = { 'http':item, 'https':item } # 遍历时,利用百度,设定timeout,未响应则断开连接 judge_url = 'https://www.baidu.com/' response = requests.get(url=judge_url,headers=self.headers,proxies=proxy,verify=False,timeout=5) self.agent_ip_list.append(item) print(item,'可用...') except: print(item,'不可用...') print('代理池ip活性检测完毕...\n代理池总量:',len(self.agent_ip_list),'\n代理池:',self.agent_ip_list) def work(self): ip_agent_url = 'https://ip.seofangfa.com/' items = self.Agent(ip_agent_url) self.judge(items)seo_ip = seo_ip()seo_ip.work() 没有导入这2个库的话,会因为ssl证书而出现警告,如图: from requests.packages.urllib3.exceptions import InsecureRequestWarning from requests.adapters import HTTPAdapter 六、附图 最后附上运行图]]></content>
<categories>
<category>proxy</category>
</categories>
<tags>
<tag>python</tag>
<tag>爬虫</tag>
<tag>proxy</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Python第三方库安装[pip、whl]]]></title>
<url>%2Fblog%2F2019%2F02%2F12%2F212%2F</url>
<content type="text"><![CDATA[本篇概述:python第三方库安装 一、pip安装 pip3 install [库名] 或 pip install [库名] [2019.02.28更新] 针对 ‘pip’ 不是内部命令,也不是可运行的程序的情况: 原因:环境变量 Path 未配置完成 找到 python 的安装目录,将 python 的安装目录 和 Python安装目录\Scripts 添加到 环境变量 Path 中即可; 环境变量Path:计算机属性 -> 高级系统设置 -> 高级 -> 环境变量 二、whl安装点我可以将内容伸缩哦~ ٩(๑>◡<๑)۶ 如果pip安装不行,可以考虑whl安装(轮子大法好!) Python常用库whl文件下载 如何知道本机安装的python支持哪个版本的轮子? 首先要知道系统是多少位的?(在cmd中输入)1systeminfo | findstr "系统类型" 结果:x64-based PC = (64位 AMD64) 12import pip._internalprint(pip._internal.pep425tags.get_supported()) X86-based PC = (32位 WIN32) 12import pipprint(pip.pep425tags.get_supported()) 选择对应的轮子 输入上面的代码后,会返回一个list,list里面就是当前系统支持的whl版本 比如 ‘cp37’, ‘cp37m’, ‘win_amd64’,cp37对应的是python3.7版本; cp37m 对应的是依赖于python3.7应用程序二进制接口; win_amd64对应的是64位系统编译的。 打开上面的网址,ctrl + F ,这里使用 mysqlclient 作为示范 根据刚刚的结果,下载以下版本的轮子即可。 mysqlclient‑1.4.2‑cp37‑cp37m‑win_amd64.whl 库名 - 版本号 - 对应python版本 - 依赖 - 系统位数 安装轮子 进入到轮子目录,cmd打开,pip install [名字].whl 即可 [2019.02.28更新] 针对 pip install [名字].whl 安装不成功的情况 可以将whl文件的后缀名.whl更改为.zip,然后解压 在解压目录下进行 python setup.py install 运行安装[通常whl文件解压后都有setup.py] 对于没有 setup.py 的,直接将解压目录放入libs文件夹中 whl文件是已经编译好的文件,作用主要是为了方便我们进行 python 的第三方库安装和使用 三、Anaconda Anaconda包括Conda、Python以及一大堆安装好的科学包和依赖项。(Conda是一个开源的包和环境的管理器) 从 Anaconda官网 下载,图形化安装,十分简单,而且网上的教程也多。]]></content>
<categories>
<category>python</category>
</categories>
<tags>
<tag>python</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Hello World]]></title>
<url>%2Fblog%2F2019%2F02%2F09%2Fhello-world%2F</url>
<content type="text"><![CDATA[Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Quick StartCreate a new post1$ hexo new "My New Post" More info: Writing Run server1$ hexo server More info: Server Generate static files1$ hexo generate More info: Generating Deploy to remote sites1$ hexo deploy More info: Deployment]]></content>
</entry>
</search>