解析搜狗词库(python)#!/usr/bin/python
# -*- coding: utf-8 -*-
import struct
import sys
import binascii
import pdb
#搜狗的scel词库就是保存的⽂本的unicode编码,每两个字节⼀个字符(中⽂汉字或者英⽂字母)
禀请#找出其每部分的偏移位置即可
#主要两部分
#1.全局拼⾳表,貌似是所有的拼⾳组合,字典序
# 格式为(index,len,pinyin)的列表
# index: 两个字节的整数代表这个拼⾳的索引
# len: 两个字节的整数拼⾳的字节长度
现代诗《遇见》# pinyin: 当前的拼⾳,每个字符两个字节,总长len
#
#2.汉语词组表
# 格式为(same,py_table_len,py_table,{word_len,word,ext_len,ext})的⼀个列表
# same: 两个字节整数同⾳词数量
# py_table_len: 两个字节整数
# py_table: 整数列表,每个整数两个字节,每个整数代表⼀个拼⾳的索引
#
# word_len:两个字节整数代表中⽂词组字节数长度
# word: 中⽂词组,每个中⽂汉字两个字节,总长度word_len
# ext_len: 两个字节整数代表扩展信息的长度,好像都是10
# ext: 扩展信息前两个字节是⼀个整数(不知道是不是词频) 后⼋个字节全是0
#
# {word_len,word,ext_len,ext} ⼀共重复same次同⾳词相同拼⾳表
#拼⾳表偏移,
startPy = 0x1540;
#汉语词组表偏移
startChine = 0x2628;
#全局拼⾳表
GPy_Table ={}
#解析结果
#元组(词频,拼⾳,中⽂词组)的列表
GTable = []
def byte2str(data):
李微然
'''将原始字节码转为字符串'''
i = 0;
length = len(data)
ret = u''
while i < length:
x = data[i] + data[i+1]
t = unichr(struct.unpack('H',x)[0])
if t == u'\r':
ret += u'\n'
elif t != u' ':
ret += t
i += 2
return ret
#获取拼⾳表
def getPyTable(data):
if data[0:4] != "\x9D\x01\x00\x00":
return None
data = data[4:]
pos = 0
length = len(data)
while pos < length:
index = struct.unpack('H',data[pos]+data[pos+1])[0]
#print index,
pos += 2
l = struct.unpack('H',data[pos]+data[pos+1])[0]
#print l,
镇干部玩弄村妇pos += 2
py = byte2str(data[pos:pos+l])
关于四季的作文
#print py
GPy_Table[index]=py
pos += l
#获取⼀个词组的拼⾳
def getWordPy(data):
pos = 0
length = len(data)
ret = u''
while pos < length:
index = struct.unpack('H',data[pos]+data[pos+1])[0]
ret += GPy_Table[index]
pos += 2
return ret
#获取⼀个词组
def getWord(data):致橡树的作者
pos = 0
length = len(data)
ret = u''
while pos < length:
index = struct.unpack('H',data[pos]+data[pos+1])[0]
ret += GPy_Table[index]
pos += 2
return ret
#读取中⽂表
def getChine(data):
#import pdb
#pdb.t_trace()
pos = 0
length = len(data)
while pos < length:
#同⾳词数量
same = struct.unpack('H',data[pos]+data[pos+1])[0]
#print '[same]:',same,
#拼⾳索引表长度
pos += 2
py_table_len = struct.unpack('H',data[pos]+data[pos+1])[0]
#拼⾳索引表
pos += 2
py = getWordPy(data[pos: pos+py_table_len])
#中⽂词组
pos += py_table_len
for i in xrange(same):
#中⽂词组长度
c_len = struct.unpack('H',data[pos]+data[pos+1])[0]
#中⽂词组
pos += 2
word = byte2str(data[pos: pos + c_len])
#扩展数据长度
pos += c_len
ext_len = struct.unpack('H',data[pos]+data[pos+1])[0]
#词频
pos += 2
count = struct.unpack('H',data[pos]+data[pos+1])[0]
#保存
GTable.append((count,py,word))
#到下个词的偏移位置
pos += ext_len
def deal(file_name):
print '-'*60
f = open(file_name,'rb')
data = f.read()
f.clo()
if data[0:12] !="\x40\x15\x00\x00\x44\x43\x53\x01\x01\x00\x00\x00": print "确认你选择的是搜狗(.scel)词库?"
#pdb.t_trace()
print "词库名:" ,byte2str(data[0x130:0x338])#.encode('GB18030')
print "词库类型:" ,byte2str(data[0x338:0x540])#.encode('GB18030') print "描述信息:" ,byte2str(data[0x540:0xd40])#.encode('GB18030') print "词库⽰例:",byte2str(data[0xd40:startPy])#.encode('GB18030') getPyTable(data[startPy:startChine])
getChine(data[startChine:])
if __name__ == '__main__':
#将要转换的词库添加在这⾥就可以了
o = ['计算机词汇⼤全【官⽅推荐】.scel',
'IT计算机.scel',
'计算机词汇⼤全【官⽅推荐】.scel',
'北京市城市信息精选.scel',
'常⽤餐饮词汇.scel',
'成语.scel',
什么是社会保险'成语俗语【官⽅推荐】.scel',
'法律词汇⼤全【官⽅推荐】.scel',
'房地产词汇⼤全【官⽅推荐】.scel',
'⼿机词汇⼤全【官⽅推荐】.scel',山海经内容
'⽹络流⾏新词【官⽅推荐】.scel',
'歇后语集锦【官⽅推荐】.scel',
'饮⾷⼤全【官⽅推荐】.scel',
]
#for f in o:
# deal(f)
print sys.argv[1]
deal( sys.argv[1] )
#保存结果
f = open('','w')
for count,py,word in GTable:
#GTable保存着结果,是⼀个列表,每个元素是⼀个元组(词频,拼⾳,中⽂词组),有需要的话可以保存成⾃⼰需要个格式 #我没排序,所以结果是按照上⾯输⼊⽂件的顺序
f.write( unicode('{%(count)s}' %{'count':count}+py+' '+ word).encode('GB18030') )#最终保存⽂件的编码,可以⾃给改 f.write('\n')
f.clo()