写在前面
最近在做URL多分类的问题,需要提取URL的特征。本文主要是介绍使用Python获取URL的基础信息,一共有15维包括
- ‘URL总长度’
- ‘URL中“.”的个数’
- ‘URL中含有大写英文字母的个数’
- ‘URL中含有小写英文字母的个数’
- ‘URL中含有阿拉伯数字的个数’
- ‘URL中含有特殊字符(“#”“_”“@”等)的个数’
- ‘分隔符“/”的个数’
- 分隔符“/”之间字符的最大长度
- ‘大写字母所占比重’
- ‘数字所占比重’
- ‘小写字母所占比重’
- ‘特殊字符所占比重’
- ‘数字字母转换频次’
- ‘最大连续字母’
- ‘最大连续数字’,
这些基础特征在URL分类的时候本文主要介绍选取这些特征的原因和Python获取特征的代码。
选取这些特征的原因
这里先介绍完整的URL中各部分的组成:
协议://主机名(域名):端口号/路径/文件名?查询字符串#锚点
例如我在百度上搜索‘有什么好吃的’之后,出现的网址如下:
https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E6%9C%89%E4%BB%80%E4%B9%88%E5%A5%BD%E5%90%83%E7%9A%84&fenlei=256&rsv_pq=0xae549e09000c5918&rsv_t=9afft3JWM000pNxBu%2FSF%2FdTmncD7UaostY637razel0UpdboCUQ3gNZwqb3P&rqlang=en&rsv_enter=1&rsv_dl=tb&rsv_sug3=20&rsv_sug1=16&rsv_sug7=101&rsv_sug2=0&rsv_btype=i&inputT=4126&rsv_sug4=4865
主要部分如下:
- 协议:HTTPS
- 主机名:www.baidu.com
- s:search
- &:不同参数的间隔符,最后的一长串都是查询的参数
接下来介绍选取这些特征的原因:
- ‘URL总长度’:这是URL最基础的特征,一般来说良性网址和恶意网址的URL长度不同,恶意网址的URL长度要长一点。
- ‘URL中“.”的个数’:域名中以‘.’做分隔符,‘.’的个数也就是域名有多少段,一般来说恶意网址中点的个数较多。
上面的特征都比较好理解,这里简单介绍下数字字母转换频次
3. 数字字母转换频次:是指数字和字母转换的次数。例如www.bai2du.com
这里转化频次就是两次。(i和2,2和d)
完整代码
import string
def getBasicFeatures(url):
specialLetter = "@#_-"
BigLetNum = 0
SamLetNum = 0
DigNum = 0
SlashNum = url.count('/');
specialNum = 0
MAXSlashNum = 0
Slxiabiao = []
for i in range(0, len(url) - 1):
if url[i] in specialLetter:
specialNum += 1
elif url[i].isupper():
BigLetNum += 1
elif url[i].islower():
SamLetNum += 1
elif url[i].isdigit():
DigNum += 1
elif url[i] == '/':
Slxiabiao.append(i)
if len(Slxiabiao) > 1:
SlNum = []
for i in range(1, len(Slxiabiao)):
SlNum.append(Slxiabiao[i] - Slxiabiao[i - 1])
MAXSlashNum = max(SlNum) - 1
FruofBigLet = int(100 * BigLetNum / len(url))
FruofSamLet = int(100 * SamLetNum / len(url))
FruofDigNum = int(DigNum * 100 / len(url))
FruofspecialNum = int(specialNum * 100 / len(url))
twelvecharacter = {
'URL总长度': len(url), 'URL中“.”的个数': url.count("."),
'URL中含有大写英文字母的个数': BigLetNum,
'URL中含有小写英文字母的个数': SamLetNum, 'URL中含有阿拉伯数字的个数': DigNum,
'URL中含有特殊字符(“#”“_”“@”等)的个数': specialNum,
'分隔符“/”的个数': SlashNum, '分隔符“”之间字符的最大长度': MAXSlashNum,
'大写字母所占比重': FruofBigLet, '小写字母所占比重': FruofSamLet,
'数字所占比重': FruofDigNum, '特殊字符所占比重': FruofspecialNum}
return twelvecharacter
def ZhuanHuanPingci(url):
urlwhole = url
count = 0
length = len(urlwhole)
for i in range(length):
if urlwhole[i] in string.digits and i + 1 < length and (
urlwhole[i + 1] in string.ascii_lowercase or urlwhole[i + 1] in string.ascii_uppercase):
count += 1
else:
if (urlwhole[i] in string.ascii_lowercase or urlwhole[i] in string.ascii_uppercase) and i + 1 < length and \
urlwhole[
i + 1] in string.digits:
count += 1
return {
'数字字母转换频次': count}
# 最大连续字母和最大连续数字
def MaxNumofCon(url):
lett = []
letNum = 0
digi = []
digNum = 0
for i in range(0, len(url) - 1):
if i == 0:
if url[0].isalpha():
lett.append(1)
if url[0].isdigit():
digi.append(1)
else:
if url[i].isalpha():
if url[i - 1].isalpha():
lett[letNum] += 1
else:
if len(lett) == 0:
lett.append(1)
else:
letNum += 1
lett.append(1)
elif url[i].isdigit():
if url[i - 1].isdigit():
digi[digNum] += 1
else:
if len(digi) == 0:
digi.append(1)
else:
digNum += 1
digi.append(1)
digi.append(0)
lett.append(0)
MaxNum = {
'最大连续字母': max(lett), '最大连续数字': max(digi)}
return MaxNum
if __name__ == '__main__':
#######****** 以下注释部分是读取大量来自csv的URL,这里我们简单以百度为例*****###
# header = ['URL','URL总长度', 'URL中“.”的个数', 'URL中含有大写英文字母的个数', 'URL中含有小写英文字母的个数',
# 'URL中含有阿拉伯数字的个数',
# 'URL中含有特殊字符(“#”“_”“@”等)的个数', '分隔符“/”的个数', '分隔符“”之间字符的最大长度',
# '最大连续字母', '最大连续数字',
# '注册地', '邮箱', '创建时间', '更新时间', '到期时间','type']
# header = ['URL', 'URL总长度', 'URL中“.”的个数', 'URL中含有大写英文字母的个数', 'URL中含有小写英文字母的个数',
# 'URL中含有阿拉伯数字的个数',
# 'URL中含有特殊字符(“#”“_”“@”等)的个数', '分隔符“/”的个数', '分隔符“”之间字符的最大长度',
# '大写字母所占比重', '小写字母所占比重', '数字所占比重', '特殊字符所占比重', '数字字母转换频次',
# '最大连续字母', '最大连续数字', 'type']
# with open('test_basic.csv', 'w', newline='', encoding='utf-8-sig') as f:
# writer = csv.DictWriter(f, fieldnames=header) # 提前预览列名,当下面代码写入数据时,会将其一一对应。
# writer.writeheader() # 写入列名
#
# with open('test.csv', 'r') as csf:
# reader = csv.reader(csf)
# for row in reader:
# # url,num=row
# url = row[0]
# dic1 = getBasicFeatures(url)
# dic2 = ZhuanHuanPingci(url)
# dic3 = MaxNumofCon(url)
# # dic4 = get_whois_info(url)
# allDic = {}
# allDic.update({'URL': url})
# allDic.update(dic1)
# allDic.update(dic2)
# allDic.update(dic3)
# # allDic.update({'type': num})
# print(url)
# # print(alllist)
# alllist = []
# alllist.append(allDic)
# with open('test_basic.csv', 'a', newline='', encoding='utf-8') as f:
# writer = csv.DictWriter(f, fieldnames=header) # 提前预览列名,当下面代码写入数据时,会将其一一对应。
# writer.writerows(alllist) # 写入数据
url='www.baidu.com'
dic1 = getBasicFeatures(url)
dic2 = ZhuanHuanPingci(url)
dic3 = MaxNumofCon(url)
allDic = {
}
allDic.update({
'URL': url})
allDic.update(dic1)
allDic.update(dic2)
allDic.update(dic3)
print(allDic)
#{'URL': 'www.baidu.com', 'URL总长度': 13, 'URL中“.”的个数': 2, 'URL中含有大写英文字母的个数': 0, 'URL中含有小写英文字母的个数': 10, 'URL中含有阿拉伯数字的个数': 0, 'URL中含有特殊字符(“#”“_”“@”等)的个数': 0, '分隔符“/”的个数': 0, '分隔符“”之间字符的最大长度': 0, '大写字母所占比重': 0, '小写字母所占比重': 76, '数字所占比重': 0, '特殊字符所占比重': 0, '数字字母转换频次': 0, '最大连续字母': 5, '最大连续数字': 0}