好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

用python去抓取网页上emoji的Unicode编码和SB Unicode编码

用python去抓取网页上emoji的Unicode编码和SB Unicode编码

关于IOS emoji表情的编码问题是这样的,IOS4.0以前emoji采用的是SoftBank的那套编码,叫做SB_Unicode, 而且IOS5时,emoji被放进了Unicode6.0, 此后IOS采用的是Unicode编码,为了在新老IOS应用程序(如微信,我们在做的人人的私信)之间传递emoji表情,就必须在后台做一个编码的转换,苹果系统自带的iMessage当然自己在后台或是前台完成了这个转换

昨天折腾了一天,要完成这么一个工作,从gibhub这上面  http://punchdrunker.github.com/iOSEmoji/table_html/index.html  把最新的编码给更新到配置文件,然后我写了一个python脚本来完成这个工作 (我此时才发现在wiki上有现成的文本的网页 http://www.unicode.org/Public/UNIDATA/EmojiSources.txt   .....)

通过个这个也学习了python,在这之前写phthon的机会很少,phthon写起来确实比C++要爽和快,代码如下

   1   #  coding=utf-8 
   2   import   urllib2
    3   from  HTMLParser  import   HTMLParser
    4  
   5   class   MyHtmlParser(HTMLParser):
    6       #   class attribute defined here     
   7  
   8       def   __init__ (self):   #   python class的构造方法 
   9          HTMLParser. __init__ (self)  #  必须调用基类的constructor     
  10           #  实例属性     
  11          self.record =  False
   12          self.emojiUnicodes =  dict()
   13          self.emojiSB =  dict()
   14          self.uniSBMap =  dict()
   15          self.isUni =  False
   16          self.isSB =  False
   17          self.numUni =  0
   18          self.numSB =  0
   19  
  20       def   handle_starttag(self, tag, attrs):
   21           if  tag ==  "  table  "  :
   22               print  attrs   #   attrs 是 list 
  23               for  attr  in  attrs:   #   attr 是 tuple 
  24                   print   attr
   25                  (name, value) =  attr
   26                   print   name
   27                   print   value
   28           if  tag !=  "  td  "  :
   29              self.record =  False
   30              self.isUni =  False
   31              self.isSB =  False
   32  
  33       def   handle_data(self, data):
   34           if  data ==  "  Unicode  "   or  data ==  "  SB Unicode  "  :
   35              self.record =  True
   36               if  data ==  "  Unicode  "  :
   37                  self.isUni =  True
   38               if  data ==  "  SB Unicode  "  :
   39                  self.isSB =  True
   40               return  
  41           if  self.record:     #  bool 类型 
  42               if  data.find( "  \n  " ) != -1:   #  忽略掉不知道哪里来的换行符 
  43                   return  
  44               if   self.isUni:
   45                  dataList = data.split( "   "  )
   46                  self.numUni += 1
  47                   for  code  in   dataList:    
   48                      code = code[2 :]
   49                      code =  "  000  "  +  code
   50                      self.emojiUnicodes[self.numUni] =  code
   51                       return 
  52               if   self.isSB:
   53                  self.numSB += 1
  54                  self.emojiSB[self.numSB] =  data
   55                   return 
  56      
  57       #  生成网页上(key, value)为(Unicode, SBCode)的dict 
  58       def   processMap(self):
   59           for  i  in  range(1, self.numUni+1):   #  注意这里range()的用法, range(start, end), 只会遍历到最大的比end小的数,不会等于end 
  60              self.uniSBMap[self.emojiUnicodes[i]] =  self.emojiSB[i]
   61  
  62  
  63   def   processEmoji(url):
   64       print   "  destination url:   "  , url
   65       #  把目标网页的html先扒到本地 
  66      htmlfile =  urllib2.urlopen(url)
   67      data =  htmlfile.read()
   68      
  69       #  把网页html文本写到./wyfile中 
  70      fp = open( "  ./wyfile  " ,  '  a  '  )
   71       fp.write(data)
   72       fp.close()
   73      
  74       #  用自己定义的htmlParser处理htmlfile 
  75      parser =  MyHtmlParser()
   76       parser.feed(data)
   77       parser.processMap()
   78       print  parser.emojiUnicodes,  "  \nnumUni=  " , parser.numUni,  "  \n  " , parser.emojiSB,  "  \nnumSB=  " , parser.numSB,  "  \n   "  , parser.uniSBMap
   79      
  80       #  单独把emoji.txt中不存在的条目 写成一个map 
  81      newMap =  dict()
   82       for  key  in   parser.emojiUnicodes:
   83          value =  parser.emojiUnicodes[key]
   84           if  value  not   in  emojiMap:  #  这里访问的emojiMap是下面定义的全局的 
  85               print  (value, parser.uniSBMap[value])  #  可以这样来print出一个tuple 
  86              newMap[value] =  parser.uniSBMap[value]
   87       return  newMap   #  返回生成的dict 
  88  
  89  
  90   #  把emoji.txt中内容读到 emojiMap中 
  91  fp = open( "  ./emoji.txt  " ,  '  a+  ' )  #  追加和读模式打开./emoji.txt时,不存在就会自动创建 
  92  emojiMap =  dict()
   93   for  line  in   fp:
   94       if  line ==  "  \n  "  :  #  跳过空行 
  95           continue 
  96       line.strip()
   97      (name, value) = line.split()  #  string的split()默认以" "作为分隔符 
  98      emojiMap[name] =  value
   99   fp.close()
  100  
 101   #  所有的要去抓取的urls,还是写死了 
 102  baseUrl =  "  http://punchdrunker.github.com/iOSEmoji/table_html/  " 
 103  urlList = [ "  index.html  " ,  "  flower.html  " ,  "  bell.html  " ,  "  vehicle.html  " ,  "  number.html  "  ]
  104  codeDict = dict()  #  用来保存每个网页新的条目的总和 
 105   for  url  in   urlList:
  106      url = baseUrl +  url
  107      newMap =  processEmoji(url)
  108      codeDict.update(newMap)  #  dict的合并 
 109  
 110   #  把codeDict写到emoji.txt中 
 111   print   codeDict
  112  fp = open( "  ./emoji.txt  " ,  '  a  ' )  #   以追加模式打开emoji.txt 
 113  fp.write( "  \n  "  )
  114   for  key  in  codeDict:   #   dict的遍历要像这样 
 115      line = key +  "   "  + codeDict[key] +  "  \n  " 
 116       fp.write(line)
  117  fp.close()

这个程序做的就是去读取这几个网页上emoji表情的Unicode和SB_Unicode编码,然后更新本地的配置文件emoji.txt,如果配置文件中没有,则把它加上

1, 自己定义的MyHtmlParser从2.7的标准库的 HTMLParser.HTMLParser派生,重写了 handle_starttage()和handle_data()两个函数, 我去分析了一上网页的HTML内容,其中我要扒取的内容的html形式如下,基于html这部份的内容的分析,在handle_data中实现了主要的逻辑,用了一个record成员变量来记录是否是需要记录此是遇到的数据,注意一下我在什么情况下打开和关掉这个变量,每次这个类被调用会生成一个dict,就是这个html文件中的emoji表情的unicode和SB_unicode的对应。

 <  tr  > 
                         <  td  > Unicode </  td  > 
                         <  td  > U+2B06 </  td  > 
                         <  td  > U+2B07 </  td  > 
                         <  td  > U+2B05 </  td  > 
                         <  td  > U+27A1 </  td  > 
                         <  td  > U+2197 </  td  > 
                         <  td  > U+2196 </  td  > 
                         <  td  > U+2198 </  td  > 
                         <  td  > U+2199 </  td  > 
                         <  td  > U+25C0 </  td  > 
                         <  td  > U+25B6 </  td  > 
                         <  td  > U+23EA </  td  > 
 </  tr  > 

2,比较奇怪的是在handle_data中我遇到了很多换行符和空格,但是这些在我读到的html文件中都没有,基本上遇到每个data后面都会有换行符和空格,42行的代码把它处理调了,70到72行我把 html文件写到了本地的./wyfile中

3,写这个程序的时候也顺便学习了一些python的基础知识,比如第一行的#encoding=utf-8 ,如果没有这一行声明的话,程序里面是写不了注释的,对此这里有说明,暂时没看明白  http://www.python.org/dev/peps/pep-0263/  。还有list, dictionary, tuple的使用,以及phthon中的class及,构造函数__init__(), 如果是子类在其__init__()中对父类__init__()的调用。实例属性初使化,文件对象的使用, for进行遍历等,注意见代码中的注释

最后在文件中输出的结果形式如下 : 左边是Unicode,右边是对应的SB_Unicode

?

0001F499  E32A

0001F38F  E43B

0001F38C  E143

00026BE  E016

00026BD  E018

0001F319  E04C

  

写代码去解决实际问题确实是学习最快的途径,相比单独去看语法书什么的,而且会给你带来成就感和快感,虽然这只是一个简单的小程序,但是我写的时候确实感觉比较high,挺久没体会到写程序让我high的感觉了,所以我发现我还是喜欢这个的。另外粘来一张图,因为我对其它的语言不熟,我感觉它对python, c,c++, java/c#的表达比较契合我的感觉, 当然java/c#我基本上也不熟

c++的那把刀是真实存在的,叫做winger Giant Knife, 淘宝上有售 http://s.taobao.com/search?spm=a230r.1.8.1.8ec807&q=giant-knife-wenger-swiss-army-knife&tab=all

 

分类:  python

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于用python去抓取网页上emoji的Unicode编码和SB Unicode编码的详细内容...

  阅读:50次