由于项目中要用到词库,而下载的搜狗词库是.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()

 

posted on 2016-08-04 13:00  绽放的四叶草  阅读(19336)  评论(2编辑  收藏  举报