一、Python3 的数据类型
数字 number
字符串 string
列表 list
元组 tuple
集合 set
字典 dict
一、Python3 的数据类型
数字 number
字符串 string
列表 list
元组 tuple
集合 set
字典 dict
asyncio 资料备忘
CPU Bound -- Multi Processing I/O Bound Fast I/O Limited Number of Connections -- Multi Threading I/O Bound Slow I/O Many Connections -- Asyncio
协程 coroutine
import asyncio import datetime async def getNow(): return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") async def getRuntime(): v = await getNow() print(v) asyncio.run(getRuntime()) # 使用async关键字 声明异步方法 # 使用await关键字 等待协程执行完成 # 使用asyncio.run(某个async方法) 执行
Python3 多线程 threading 备忘录
t.setDaemon(True) // 线程声明为守护线程,必须在start() 方法调用之前设置 t.start() // 开始线程活动 t.join() // 在子线程完成运行之前,这个子线程的父线程将一直被阻塞
方法与属性 描述 current_thread() 返回当前线程 active_count() 返回当前活跃的线程数,1个主线程+n个子线程 get_ident() 返回当前线程 enumerate() 返回当前活动 Thread 对象列表 main_thread() 返回主 Thread 对象 settrace(func) 为所有线程设置一个 trace 函数 setprofile(func) 为所有线程设置一个 profile 函数 stack_size([size]) 返回新创建线程栈大小;或为后续创建的线程设定栈大小为 size TIMEOUT_MAX Lock.acquire(), RLock.acquire(), Condition.wait() 允许的最大超时时间
对于Thread类,它的定义如下: threading.Thread(self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None) # 参数group是预留的,用于将来扩展; # 参数target是一个可调用对象,在线程启动后执行; # 参数name是线程的名字。默认值为“Thread-N“,N是一个数字; # 参数args和kwargs分别表示调用target时的参数列表和关键字参数;
Thread类定义了以下常用方法与属性: 方法与属性 : 说明 start() : 启动线程,等待CPU调度 run() : 线程被cpu调度后自动执行的方法 getName()、setName()和name : 用于获取和设置线程的名称 setDaemon() : 设置为后台线程或前台线程(默认是False,前台线程)。如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止。如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程执行完成后,程序才停止 ident : 获取线程的标识符。线程标识符是一个非零整数,只有在调用了start()方法之后该属性才有效,否则它只返回None is_alive() : 判断线程是否是激活的(alive)。从调用start()方法启动线程,到run()方法执行完毕或遇到未处理异常而中断这段时间内,线程是激活的 isDaemon()方法和daemon属性 : 是否为守护线程 join([timeout]) : 调用该方法将会使主调线程堵塞,直到被调用线程运行结束或超时。参数timeout是一个数值类型,表示超时时间,如果未提供该参数,那么主调线程将一直堵塞到被调线程结束。
Python在threading模块中定义了几种线程锁类,分别是: Lock 互斥锁 RLock 可重入锁 Semaphore 信号 Event 事件 Condition 条件 Barrier 阻碍
需求描述,
采集网络公开的shadowsocks线路,玩具类型,项目编号P1SS
技术分析
一般情况下,一个普通的shadowsocks文件如下 ss://YWVzLTI1Ni1jZmI6MTIzNDU2IUAjJDpAMTAxLjc5LjU1LjIwMTo4MDg3#US 1. ss://是协议标识 2. YWVzLTI1Ni1jZmI6MTIzNDU2IUAjJDpAMTAxLjc5LjU1LjIwMTo4MDg3是信息内容正文 3. #US是注释内容
将信息正文的内容转码
YWVzLTI1Ni1jZmI6MTIzNDU2IUAjJDpAMTAxLjc5LjU1LjIwMTo4MDg3 --> b'aes-256-cfb:123456!@#$:@101.79.55.201:8087' 可以发现是一个bytes类型的字符串
既然得到一个字符串,则可以对字符串,进行切割,获得其中的数据
// 最后一个@字符进行切分字符串 >>> s = 'aes-256-cfb:123456!@#$:@101.79.55.201:8087' >>> s.rsplit('@',1) ['aes-256-cfb:123456!@#$:', '101.79.55.201:8087'] // 可以切分得到1 加密算法:密码 // 可以切分得到2 IP:端口
// 切分 加密算法:密码 >>> s = 'aes-256-cfb:123456!@#$:' >>> s.split(':',1) ['aes-256-cfb', '123456!@#$:'] >>> // 切分 IP:端口 >>> s = '101.79.55.201:8087' >>> s.split(':',1) ['101.79.55.201', '8087'] >>>
通过3步的字符串的切分,即可以获取到需要的4个数据信息,校验一下,就可以进行入库的操作
采集源头,分类 1. ss list,一个包含JSON数据信息的列表 [ { "remarks": "NL1", "server": "5.253.207.85", "server_port": "49396", "method": "aes-256-gcm", "password": "BdRWC38L5JUDMTYNNxJGcUwB", "plugin": "", "plugin_opts": {} }, { "remarks": "NL2", "server": "5.253.207.86", "server_port": "49396", "method": "aes-256-gcm", "password": "BdRWC38L5JUDMTYNNxJGcUwB", "plugin": "", "plugin_opts": {} }, ... ] 2. ss sub,一个base64转码的字符串 base64encode( ss://238917498723...\n ss://238472938749...\n ... ) 3. ss content,一个字符串,其中包含一段ss://298739879287的字符
架构为 前/后/库 分离
数据库 <==> API服务器 <== invoker采集服务器 <==> 采集跳板 <==> 数据源1/2/3/... 数据库 <==> API服务器 <==> checker检测服务器 <==> 检测跳板 <==> 检测站CN1/US1 数据库 <==> API服务器 ==> publish发布服务器 <==> 发布跳板 <==> WEB站Web1/Web2
需要一个每日5万次的IP查询服务,目前市面上的IP查询服务,大多很贵,这个有2个办法可以解决。
本次使用ip-database项目,搭配纯真数据库的IP库,搭建可靠的本地IP查询服务,感谢纯真库,提供持久免费的更新。
项目地址 https://github.com/itbdw/ip-database
服务端操作系统 Debian 9
安装php服务
root@debian:~# apt-get install php
下载项目之后,随意测试一个IP,看是否可以运行 root@debian:~/ip-database-2.0.9/tests# php ip.php -i 101.84.1.1 {"ip":"101.84.1.1","country":"中国","province":"上海","city":"","county":"","isp":"电信","area":"中国上海电信"} root@debian:~/ip-database-2.0.9/tests#
纯真IP数据库 DAT文件更新 https://github.com/out0fmemory/qqwry.dat/archive/refs/heads/master.zip
把上面的封装到API里面,API地址为 http://198.211.9.196:41011/IPService ,参数为ip,封装的纯真数据库的版本v20210902,本地API文件run_IP_LOOKUP.py
请求示例1,请求一个国内IP地址的信息:
curl http://198.211.9.196:41011/IPService?ip=101.84.1.1 CN-上海-电信
请求示例2,请求一个海外IP地址的信息:
curl http://198.211.9.196:41011/IPService?ip=17.57.145.0
美国
请求示例3,请求一个错误的IP地址:
curl http://198.211.9.196:41011/IPService?ip=1.2.3.400
404
判断一个IP是否是归属于亚洲,https://ftp.apnic.net/stats/apnic/delegated-apnic-latest
2G网络制式
移动 :GSM
联通 :GSM
电信 :CDMA1X
3G网络制式
移动 :TD-SCDMA 国产标准
联通 :WCDMA 欧洲标准
电信 :CDMA2000
4G网络制式
移动 :TD-LTE
联通 :TD-LTE和FDD-LTE混合
电信 :TD-LTE和FDD-LTE混合
5G网络制式 三网一致,基站数量,覆盖,信号的频点不同而已
需求,IP地址查询服务,需要一个简略的国家位置的信息,需要两位的国家代码,对应的中文标识
国家代码标记,参考的是 https://zh.wikipedia.org/wiki/ISO_3166-1
我需要的是2位的字母代码,中文名称,只需要复制出其中这两列
AD 安道尔 AE 阿联酋 AF 阿富汗 AG 安地卡及巴布達 AI 安圭拉 AL 阿尔巴尼亚 AM 亞美尼亞 AO 安哥拉 AQ 南极洲 AR 阿根廷 AS 美属萨摩亚 AT 奥地利 AU 澳大利亚 AW 阿鲁巴 AX 奥兰 AZ 阿塞拜疆 BA 波黑 BB 巴巴多斯 BD 孟加拉国 BE 比利時 BF 布吉納法索 BG 保加利亚 BH 巴林 BI 布隆迪 BJ 贝宁 BL 圣巴泰勒米 BM 百慕大 BN 文莱 BO 玻利维亚 BQ 荷兰加勒比区 BR 巴西 BS 巴哈马 BT 不丹 BV 布韦岛 BW 博茨瓦纳 BY 白俄羅斯 BZ 伯利兹 CA 加拿大 CC 科科斯-基林-群島 CD 刚果民主共和国 CF 中非 CG 刚果共和国 CH 瑞士 CI 科特迪瓦 CK 庫克群島 CL 智利 CM 喀麦隆 CN 中国 CO 哥伦比亚 CR 哥斯达黎加 CU 古巴 CV 佛得角 CW 库拉索 CX 圣诞岛 CY 賽普勒斯 CZ 捷克 DE 德國 DJ 吉布提 DK 丹麥 DM 多米尼克 DO 多米尼加 DZ 阿尔及利亚 EC 厄瓜多尔 EE 爱沙尼亚 EG 埃及 EH 西撒哈拉 ER 厄立特里亚 ES 西班牙 ET 衣索比亞 FI 芬兰 FJ 斐济 FK 福克蘭群島 FM 密克羅尼西亞聯邦 FO 法罗群岛 FR 法國 GA 加彭 GB 英國 GD 格瑞那達 GE 格鲁吉亚 GF 法属圭亚那 GG 根西 GH 加纳 GI 直布罗陀 GL 格陵兰 GM 冈比亚 GN 几内亚 GP 瓜德罗普 GQ 赤道几内亚 GR 希臘 GS 南乔治亚和南桑威奇群岛 GT 危地马拉 GU 關島 GW 几内亚比绍 GY 圭亚那 HK 香港 HM 赫德岛和麦克唐纳群岛 HN 洪都拉斯 HR 克罗地亚 HT 海地 HU 匈牙利 ID 印尼 IE 爱尔兰 IL 以色列 IM 马恩岛 IN 印度 IO 英屬印度洋領地 IQ 伊拉克 IR 伊朗 IS 冰岛 IT 意大利 JE 泽西 JM 牙买加 JO 约旦 JP 日本 KE 肯尼亚 KG 吉尔吉斯斯坦 KH 柬埔寨 KI 基里巴斯 KM 科摩罗 KN 圣基茨和尼维斯 KP 朝鲜 KR 韩国 KW 科威特 KY 开曼群岛 KZ 哈萨克斯坦 LA 老挝 LB 黎巴嫩 LC 圣卢西亚 LI 列支敦斯登 LK 斯里蘭卡 LR 利比里亚 LS 賴索托 LT 立陶宛 LU 卢森堡 LV 拉脫維亞 LY 利比亞 MA 摩洛哥 MC 摩納哥 MD 摩尔多瓦 ME 蒙特內哥羅 MF 法属圣马丁 MG 马达加斯加 MH 马绍尔群岛 MK 北馬其頓 ML 马里 MM 缅甸 MN 蒙古 MO 澳門 MP 北马里亚纳群岛 MQ 马提尼克 MR 毛里塔尼亚 MS 蒙特塞拉特 MT 馬爾他 MU 模里西斯 MV 馬爾地夫 MW 马拉维 MX 墨西哥 MY 马来西亚 MZ 莫桑比克 NA 纳米比亚 NC 新喀里多尼亞 NE 尼日尔 NF 诺福克岛 NG 奈及利亞 NI 尼加拉瓜 NL 荷蘭 NO 挪威 NP 尼泊爾 NR 瑙鲁 NU 纽埃 NZ 新西蘭 OM 阿曼 PA 巴拿马 PE 秘魯 PF 法屬玻里尼西亞 PG 巴布亚新几内亚 PH 菲律賓 PK 巴基斯坦 PL 波蘭 PM 圣皮埃尔和密克隆 PN 皮特凯恩群岛 PR 波多黎各 PS 巴勒斯坦 PT 葡萄牙 PW 帛琉 PY 巴拉圭 QA 卡塔尔 RE 留尼旺 RO 羅馬尼亞 RS 塞爾維亞 RU 俄羅斯 RW 卢旺达 SA 沙烏地阿拉伯 SB 所罗门群岛 SC 塞舌尔 SD 苏丹 SE 瑞典 SG 新加坡 SH 圣赫勒拿-阿森松和特里斯坦-达库尼亚 SI 斯洛維尼亞 SJ 斯瓦尔巴和扬马延 SK 斯洛伐克 SL 塞拉利昂 SM 圣马力诺 SN 塞内加尔 SO 索馬利亞 SR 苏里南 SS 南蘇丹 ST 聖多美和普林西比 SV 薩爾瓦多 SX 荷屬聖馬丁 SY 叙利亚 SZ 斯威士兰 TC 特克斯和凯科斯群岛 TD 乍得 TF 法属南部和南极领地 TG 多哥 TH 泰國 TJ 塔吉克斯坦 TK 托克勞 TL 东帝汶 TM 土库曼斯坦 TN 突尼西亞 TO 汤加 TR 土耳其 TT 千里達及托巴哥 TV 图瓦卢 TW 台湾 TZ 坦桑尼亚 UA 烏克蘭 UG 乌干达 UM 美國本土外小島嶼 US 美國 UY 乌拉圭 UZ 乌兹别克斯坦 VA 梵蒂冈 VC 圣文森特和格林纳丁斯 VE 委內瑞拉 VG 英屬維爾京群島 VI 美屬維爾京群島 VN 越南 VU 瓦努阿圖 WF 瓦利斯和富图纳 WS 萨摩亚 YE 葉門 YT 马约特 ZA 南非 ZM 尚比亞 ZW 辛巴威
{ "AF":"阿富汗", "AX":"奥兰", ... } 生成一个静态化的字典文件,方便在程序中查询匹配
桌面操作系统为ubuntu 20.04.3 LTS
安装的虚拟化软件为vmware workstation 16.1.2 build-17966106
打开时候的报错信息为
Could not open /dev-vmmon: No such file or directory. Please make sure that the kernel module ‘vmmon’ is loaded.
官方解释的原因是,uefi启动模式下,vmmon and vmnet两个是非开源的模块,没有通过linux内核认证,没有随系统自动启动。
最快捷的解决办法:重启电脑,进入BIOS设置,关闭secure boot选项,重启,正常进入Ubuntu 20.04桌面,就可以用vmware workstation了
VM官方,还提供了一个通过给模块签名,用mokutil导入的方式,临时办法。参考附录1的官方链接。
附录1
参考链接 VMWare官方 https://kb.vmware.com/s/article/2146460
参考链接 VMWare官方 https://kb.vmware.com/s/article/1002411
需求描述
从网络上,采集了10多万个HTTP/HTTPS/SOCKS4/SOCKS5的普通代理,有时候,其中一些的IP归属的地区,还是蛮不错的,想要用它作为落地IP
网络链路,客户端v – 服务端v – 普通socks5
服务器的配置
参考
出站配置 https://www.v2fly.org/config/outbounds.html
协议配置 https://www.v2fly.org/config/protocols/socks.html
完成
服务端的配置文件
{ "log": { "access": "./access.log", "error": "./error.log", "loglevel": "info" }, "inbound": { "port": 18125, "protocol": "vmess", "settings": { "clients": [ { "id": "9299c14f-b3e0-e937-2ec8-5992a8cc3211", "level": 1, "alterId": 4 } ] } }, "outbound": { "protocol": "socks", "settings": { "servers": [ { "address": "117.27.*.153", "port": 1080, "users": [] } ] } }, "routing": { "strategy": "rules", "settings": { "rules": [ { "type": "field", "ip": [ "0.0.0.0/8", "10.0.0.0/8", "100.64.0.0/10", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24", "192.0.2.0/24", "192.168.0.0/16", "198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "::1/128", "fc00::/7", "fe80::/10" ], "outboundTag": "blocked" } ] } } } # 其中117.27.*.153为socks5的IP,1080为socks5的端口。
客户端配置
{ "inbound": { "listen": "127.0.0.1", "port": 10808, "protocol": "socks", "settings": { "auth": "noauth", "udp": false, "ip": "127.0.0.1" } }, "outbound": { "protocol": "vmess", "settings": { "vnext": [ { "address": "183.23.78.5", "port": 18888, "users": [ { "id": "9299c14f-b3e0-e937-2ec8-5992a8cc3211", "level": 1, "alterId": 4 } ] } ] } } } # 其中183.23.78.5为SERVER的IP,18888为SERVER的端口。
附录1
发现一个有趣的现象,有人直接把socks5暴露在国内的IP上,实际落地IP是在海外,相当于,其已经打通了一个管道。比如,福建电信的socks5://117.27.*.153:1080就是这样的情况,使用它的时候,它实际的IP是在美国的甲骨文机房IP-221.141.*.130,你们城里人真会玩!
赞助