Python解析v2ray订阅地址

标签: Python 分类: Python 创建时间:2020-01-18 06:53:11 更新时间:2025-01-17 10:39:22

通过参考文章,以及查阅相关语法,最终我使用python3执行以下相关代码,获得了v2ray订阅地址并进行了解析。

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
#!/usr/bin/python3
# -*- coding: UTF-8 -*-

# from urllib.request import urlopen
import urllib.request
import base64
import json
import urllib.parse

## 获取订阅地址
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'}
subscribe_url = '你的订阅地址'
req = urllib.request.Request(url=subscribe_url, headers=headers)
return_content = urllib.request.urlopen(req).read()

## print(return_content)
## 解析订阅地址内容
lens = len(return_content)
lenx = lens - (lens % 4 if lens % 4 else 4)
try:
result = base64.decodestring(return_content[:lenx])
share_links=result.splitlines()
## 解析vmess协议
schemes_allow = ['vmess', 'ss', 'socks']
configs = []
for share_link in share_links:
share_link=bytes.decode(share_link)
url=share_link.split("://")
## 解析协议
scheme=url[0]
print(scheme)
if scheme not in schemes_allow:
print(scheme+"不支持")
continue
## 解析内容
net=url[1]
net=str.encode(net)
lens = len(net)
lenx = lens - (lens % 4 if lens % 4 else 4)
resultJson = base64.decodestring(net)
configs.append(json.loads(bytes.decode(resultJson)))
print(configs)
except Exception as e :
print(e)
pass
参考文章:
1.V2Ray 订阅解析 (代码在这里,经过改造和错误修改之后,最终产生了新的代码)

问题

(1) urllib.error.HTTPError: HTTP Error 403: Forbidden

设置headers,模拟浏览器请求。

(2) Python解码base64遇到Incorrect padding错误

将base64.b64decode(return_content),用decodestring代替。
我刚开始使用了下面的方法,对某些情况下有用,对于有些地方不适应,比如我解析了trojan的地址

1
2
3
4
5
6
7

lens = len(strg)
lenx = lens - (lens % 4 if lens % 4 else 4)
try:
result = base64.decodestring(strg[:lenx])
except:
pass

对于特殊的情况还可以使用下面的方式进行:

1
2
3
base64.b64decode(strg, '-_')
# or
base64.urlsafe_b64decode(base64_url)

(3) invalid share link
这是其实是:url.scheme not in schemes_allow: raise RuntimeError('invalid share link')这段代码返回的错误。

1
2
3
4
schemes_allow = ['vmess', 'ss', 'socks']

## 返回False
print(b'vmess' in schemes_allow)

以b开头的字符串,是bytes类型的字符串。

(4) expected bytes-like object, not str
随着修改代码,又出现了新的问题。

生成json并写入文件中:

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
#!/usr/bin/python3
# -*- coding: UTF-8 -*-

# from urllib.request import urlopen
import urllib.request
import base64
import json
import urllib.parse

## 解析base64字符串
def base64StrFun(base64Str):
try:
base64Str=base64.urlsafe_b64decode(base64Str)
except:
lens = len(base64Str)
lenx = lens - (lens % 4 if lens % 4 else 4)
base64Str= base64.decodestring(base64Str[:lenx])
return base64Str

## 解析Vmess协议节点
def parseVmess(nodeStr):
return

## 解析SSR协议节点
def parseSSR(nodeStr):
result=base64StrFun(nodeStr)
result=bytes.decode(result)
print(result)

## 暂时不解析
result='{}'
return result

## 解析Trojan协议节点
def parseTrojan(nodeStr):
result=base64StrFun(nodeStr)
result=bytes.decode(result)
print(result)
return result

## 获取订阅地址
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'}
## v2ray订阅地址
subscribe_url = '你的'

## Trojan订阅地址
## subscribe_url='你的'

## SSR订阅地址
## ubscribe_url='你的'

req = urllib.request.Request(url=subscribe_url, headers=headers)
return_content = urllib.request.urlopen(req).read()

## 解析订阅地址内容
try:
result=base64StrFun(return_content)
print(result)
share_links=result.splitlines()
## 解析vmess协议
schemes_allow = ['vmess', 'ss', 'socks']
configs = []
print(share_links);
for share_link in share_links:
share_link=bytes.decode(share_link)
url=share_link.split("://")
## 解析内容
net=url[1]
net=str.encode(net)

## 解析协议
scheme=url[0]
if scheme == "trojan" :
nodeStr=parseTrojan(net)
elif scheme == "ssr":
nodeStr=parseSSR(net)
else :
nodeStr= base64StrFun(net)
nodeStr=bytes.decode(nodeStr)

## 加入json数组
configs.append(json.loads(nodeStr))
print(configs)
## 将结果写入文件中
with open("record.json","w") as dump_f:
json.dump(configs,dump_f)

except Exception as e :
print(e)
pass

问题
写入的json文件中文出现乱码,也不算乱码,就是中文被编码成了unicode编码。。

只需要在使用json.dump(configs,dump_f,ensure_ascii=False) 就可以了。

(4) Temporary failure in name resolution

编辑/etc/resolv.conf文件,添加如下内容(问题也没有解决)

1
2
3
nameserver   202.96.209.133
nameserver 61.129.88.123
nameserver 114.114.114.114
文章目录
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。