python网页抓取之英汉字典+自学习能力
上篇每次翻译一个单词都要联网抓取,重复翻译也要抓取,感觉不太好。晚上突然想到了一个不错的办法,
说白了就是查询数据库如果有这个单词就拿出来,没有就联网抓取显示出来并保存进
数据库。时间长了几乎就不用联网了,也就是离线了!
本人使用的数据库是sqlite,小巧简单。当然用其他的也可以了。还是看代码吧。
代码增加的不多,有些可以优化先不管啦。用BeautifulSoup解析html更容易写,可以看上篇文章。
dict.py: python-2.7.5
1 #!/usr/bin/python 2 import urllib2,sys,sqlite3 3 from HTMLParser import HTMLParser 4 5 class MyHTMLParser(HTMLParser): 6 def __init__(self): 7 HTMLParser.__init__(self) 8 self.t=False 9 self.trans=[] 10 self.prs=[] 11 self.pr=False 12 def handle_starttag(self, tag, attrs): 13 if tag=='div': 14 for attr in attrs: 15 if attr==('class','hd_prUS') or \ 16 attr==('class','hd_pr'): 17 self.pr=True 18 if tag=='span': 19 for attr in attrs: 20 if attr==('class','def'): 21 self.t=True 22 def handle_data(self, data): 23 if self.t: 24 length=len(self.trans)+1 25 self.trans.append(str(length)+". "+data) 26 self.t=False 27 if self.pr: 28 self.prs.append(data) 29 self.pr=False 30 def getTrans(self): 31 return self.trans 32 def getPr(self): 33 return self.prs 34 class trans: 35 _URL='http://cn.bing.com/dict/search' 36 _DBPATH='./dic.sqlite' #数据库文件位置 37 def __init__(self): 38 self.url=trans._URL+"?q=%s&go=&qs=bs&form=CM&mkt=zh-CN&setlang=ZH" 39 self.html=None 40 self.s=None #保存翻译 41 self.pr=None #保存发音(US和UK) 42 self.word=None #保存单词 43 self.conn=sqlite3.connect(trans._DBPATH) 44 self.cur = self.conn.cursor() 45 def getHtml(self): 46 self.url=self.url %self.word 47 req = urllib2.Request(self.url) 48 fd=urllib2.urlopen(req) 49 self.html=fd.read() 50 self.html=unicode(self.html,'utf-8') 51 fd.close() 52 53 def parseHtml(self): 54 parser = MyHTMLParser() 55 self.html=parser.unescape(self.html) #处理&、&#等开头的特殊字符串 56 parser.feed(self.html) 57 self.s=parser.getTrans() 58 self.pr=parser.getPr() 59 print self.word,':' 60 #for sk in self.pr: 61 print self.pr[0],',',self.pr[1] 62 print '' 63 for i in self.s: 64 print i 65 66 def saveDB(self): #把单词信息插入数据库 67 sjoin='\n'.join(self.s) 68 uspr=self.pr[0] 69 ukpr=self.pr[1] 70 #self.cur.execute("create table if not exists translate ( word CHAR(40) primary key, us CHAR(40), uk CHAR(40), trans text )") 71 self.cur.execute("insert into translate values(?,?,?,?);", \ 72 (self.word,uspr,ukpr,sjoin)) 73 self.conn.commit() 74 75 def isExists(self,word): #判断单词是否在db中,如果在直接打印出来。 76 self.word=word 77 rows=self.cur.execute("select * from translate where word=?",(self.word,)) 78 key=rows.fetchall() 79 if key==[]: 80 return False 81 else: 82 for row in key: 83 print row[0],':' 84 print row[1],",",row[2] 85 print '' 86 print row[3] 87 return True 88 def select(self): #测试查看用的,删不删无所谓啦 89 rows=self.cur.execute("select * from translate") 90 for row in rows: 91 print row[0] 92 print row[1],",",row[2] 93 print row[3] 94 def closeDB(self): 95 self.conn.close() 96 if __name__=='__main__': 97 t=trans() 98 flag=t.isExists(sys.argv[1]) 99 if not flag: 100 t.getHtml() 101 t.parseHtml() 102 t.saveDB() 103 # t.select() 104 t.closeDB()
终端运行:
08:59@:~/workspace$ ./dic.py believe --------->这是第一次的,联网抓取的 believe : 美 [bɪˈliv] , 英 [bɪˈliːv] 1. 相信;认为真实;把(某事)当真;认为有可能 2. 认定;看作;表示对某事吃惊或恼怒;有宗教信仰 3. 信任;我相信;你不渺小 09:00@:~/workspace$ ./dic.py believe --------->第二次从db中获取的(在查询里加个输出就知道是从db取出的了) believe : 美 [bɪˈliv] , 英 [bɪˈliːv] 1. 相信;认为真实;把(某事)当真;认为有可能 2. 认定;看作;表示对某事吃惊或恼怒;有宗教信仰 3. 信任;我相信;你不渺小
第二次翻译比第一次快多了,能感觉到。当然这是数据库中的信息比较少,多了的话现在不能下结论。
还有就是数据库本人用了四列,分别是word、us(美式发音)、uk(英式)、trans(翻译)。表名translate。
类型分别是char、char、char、text。
Note:注释是写博客后来加上去的,可以直接删了,或者添加# -*- coding: utf-8 -*-
本人是在linux下编写运行的.