由于项目中要用到词库,而下载的搜狗词库是.scel格式,所以就用python脚本将搜狗词库.scel格式文件转化为.txt格式文件。
1 #!/bin/python 2 # -*- coding: utf-8 -*- 3 4 5 import struct 6 import sys 7 import binascii 8 import pdb 9 10 try: 11 reload(sys) 12 sys.setdefaultencoding('utf-8') 13 except: 14 pass 15 16 # 搜狗的scel词库就是保存的文本的unicode编码,每两个字节一个字符(中文汉字或者英文字母) 17 # 找出其每部分的偏移位置即可 18 # 主要两部分 19 # 1.全局拼音表,貌似是所有的拼音组合,字典序 20 # 格式为(index,len,pinyin)的列表 21 # index: 两个字节的整数 代表这个拼音的索引 22 # len: 两个字节的整数 拼音的字节长度 23 # pinyin: 当前的拼音,每个字符两个字节,总长len 24 # 25 # 2.汉语词组表 26 # 格式为(same,py_table_len,py_table,{word_len,word,ext_len,ext})的一个列表 27 # same: 两个字节 整数 同音词数量 28 # py_table_len: 两个字节 整数 29 # py_table: 整数列表,每个整数两个字节,每个整数代表一个拼音的索引 30 # 31 # word_len:两个字节 整数 代表中文词组字节数长度 32 # word: 中文词组,每个中文汉字两个字节,总长度word_len 33 # ext_len: 两个字节 整数 代表扩展信息的长度,好像都是10 34 # ext: 扩展信息 前两个字节是一个整数(不知道是不是词频) 后八个字节全是0 35 # 36 # {word_len,word,ext_len,ext} 一共重复same次 同音词 相同拼音表 37 38 # 拼音表偏移, 39 startPy = 0x1540; 40 41 # 汉语词组表偏移 42 startChinese = 0x2628; 43 44 # 全局拼音表 45 46 GPy_Table = {} 47 48 # 解析结果 49 # 元组(词频,拼音,中文词组)的列表 50 GTable = [] 51 52 53 def byte2str(data): 54 '''''将原始字节码转为字符串''' 55 i = 0; 56 length = len(data) 57 ret = u'' 58 while i < length: 59 x = data[i] + data[i + 1] 60 t = unichr(struct.unpack('H', x)[0]) 61 if t == u'\r': 62 ret += u'\n' 63 elif t != u' ': 64 ret += t 65 i += 2 66 return ret 67 68 69 # 获取拼音表 70 def getPyTable(data): 71 if data[0:4] != "\x9D\x01\x00\x00": 72 return None 73 data = data[4:] 74 pos = 0 75 length = len(data) 76 while pos < length: 77 index = struct.unpack('H', data[pos] + data[pos + 1])[0] 78 # print index, 79 pos += 2 80 l = struct.unpack('H', data[pos] + data[pos + 1])[0] 81 # print l, 82 pos += 2 83 py = byte2str(data[pos:pos + l]) 84 # print py 85 GPy_Table[index] = py 86 pos += l 87 88 # 获取一个词组的拼音 89 90 91 def getWordPy(data): 92 pos = 0 93 length = len(data) 94 ret = u'' 95 while pos < length: 96 index = struct.unpack('H', data[pos] + data[pos + 1])[0] 97 ret += GPy_Table[index] 98 pos += 2 99 return ret 100 101 102 # 获取一个词组 103 def getWord(data): 104 pos = 0 105 length = len(data) 106 ret = u'' 107 while pos < length: 108 index = struct.unpack('H', data[pos] + data[pos + 1])[0] 109 ret += GPy_Table[index] 110 pos += 2 111 return ret 112 113 114 # 读取中文表 115 def getChinese(data): 116 # import pdb 117 # pdb.set_trace() 118 119 pos = 0 120 length = len(data) 121 while pos < length: 122 # 同音词数量 123 same = struct.unpack('H', data[pos] + data[pos + 1])[0] 124 # print '[same]:',same, 125 126 # 拼音索引表长度 127 pos += 2 128 py_table_len = struct.unpack('H', data[pos] + data[pos + 1])[0] 129 # 拼音索引表 130 pos += 2 131 py = getWordPy(data[pos: pos + py_table_len]) 132 133 # 中文词组 134 pos += py_table_len 135 for i in xrange(same): 136 # 中文词组长度 137 c_len = struct.unpack('H', data[pos] + data[pos + 1])[0] 138 # 中文词组 139 pos += 2 140 word = byte2str(data[pos: pos + c_len]) 141 # 扩展数据长度 142 pos += c_len 143 ext_len = struct.unpack('H', data[pos] + data[pos + 1])[0] 144 # 词频 145 pos += 2 146 count = struct.unpack('H', data[pos] + data[pos + 1])[0] 147 148 # 保存 149 GTable.append((count, py, word)) 150 151 # 到下个词的偏移位置 152 pos += ext_len 153 154 155 def deal(file_name): 156 print '-' * 60 157 f = open(file_name, 'rb') 158 data = f.read() 159 f.close() 160 161 if data[0:12] != "\x40\x15\x00\x00\x44\x43\x53\x01\x01\x00\x00\x00": 162 print "确认你选择的是搜狗(.scel)词库?" 163 sys.exit(0) 164 # pdb.set_trace() 165 166 print "词库名:", byte2str(data[0x130:0x338]) # .encode('GB18030') 167 print "词库类型:", byte2str(data[0x338:0x540]) # .encode('GB18030') 168 print "描述信息:", byte2str(data[0x540:0xd40]) # .encode('GB18030') 169 print "词库示例:", byte2str(data[0xd40:startPy]) # .encode('GB18030') 170 171 getPyTable(data[startPy:startChinese]) 172 getChinese(data[startChinese:]) 173 174 175 if __name__ == '__main__': 176 177 # 将要转换的词库添加在这里就可以了 178 o = [u'明星【官方推荐】.scel',] 179 180 181 for f in o: 182 deal(f) 183 184 # 保存结果 185 f = open('amuse.txt', 'w') 186 for word in GTable: 187 # GTable保存着结果,是一个列表,每个元素是一个元组(词频,拼音,中文词组),有需要的话可以保存成自己需要个格式 188 # 我没排序,所以结果是按照上面输入文件的顺序 189 #f.write(unicode(word).encode('GB18030')) # 最终保存文件的编码,可以自给改 190 f.write(word[2]) 191 f.write('\n') 192 f.close()