為什么要建立自己的單詞庫
用過各種的背單詞軟件,總是在使用其他人的詞庫或者軟件自己提供的詞庫,基本是人家提供什么自己就用什么,要想有更多的自主基本沒有,最近看一個(gè) COCA的按單詞使用頻率來提取的2萬單詞表,但沒有對(duì)應(yīng)的單詞庫,知米里倒是可以直接導(dǎo)入英文單詞,系統(tǒng)幫你匹配上音標(biāo)、讀音、例句及解釋,然而匹配后的結(jié)果你卻無法導(dǎo)出。
特別是最近準(zhǔn)備利用AnkiDroid來進(jìn)行單詞背誦,所以有種要建立自己的單詞庫的需求。更進(jìn)一步或許可以自己開發(fā)一個(gè)背單詞的軟件也是有可能的?!叭f里長征第一步,先來建立單詞庫”,走一步看一步吧。
詞庫的需求分析
根據(jù)需求,詞庫應(yīng)該包括如下內(nèi)容
- 英文:對(duì)應(yīng)英語單詞
- 音標(biāo)及讀音:分為美語音標(biāo),讀音,英語音標(biāo),讀音
- 詞性,中文釋義:單詞多個(gè)含義的不同詞性和中文
- 例句:單詞的例句
- 助記:比如詞根或者其他有助于記憶的說明
- 輸出一個(gè)文本文件好了,方便以后進(jìn)行各種處理
使用技術(shù)的選擇
獲得單詞的相關(guān)信息,目前可以通過百度翻譯,有道翻譯,必應(yīng)翻譯,谷歌翻譯,金山詞霸等方式,在綜合考慮后選擇通過必應(yīng)字典模式獲得相關(guān)數(shù)據(jù)。
數(shù)據(jù)爬取上,目前最為流行的并且相對(duì)成熟的是使用python(也就懂python),所以選擇python
對(duì)于使用python爬取數(shù)據(jù),一般有兩種模式,一種是python+urllib+lxml, python+selenium+chrome。本身就是一個(gè)小項(xiàng)目,同時(shí)自身學(xué)習(xí)能力有限就沒考慮scrapy的爬蟲框架了。估計(jì)以后要是大量、各種、經(jīng)常性爬取內(nèi)容才會(huì)考慮這個(gè)。什么都要學(xué)習(xí)呀,學(xué)習(xí)是要成本的。
-
python+selenium+chrome- 可以模擬瀏覽器動(dòng)作,能有效的解決ajax模式下的數(shù)據(jù)爬取問題
- 很容易實(shí)現(xiàn)基于瀏覽器的測試
- 必須能夠趟過 selenium 的一系列坑,相對(duì)學(xué)習(xí)成本要高
-
python+urllib+lxml- 學(xué)習(xí)成本相對(duì)較低
- ajax,動(dòng)態(tài)網(wǎng)頁的爬取不方便
當(dāng)然兩者都需要有一定的正則表達(dá)式能力。由于必應(yīng)字典基本都屬于靜態(tài)網(wǎng)頁,所以選擇方式2就是python+urllib+lxml模式。
技術(shù)實(shí)現(xiàn)
1.python及相關(guān)環(huán)境安裝:
使用anaconda 完成整體環(huán)境的安裝,這里略過,詳細(xì)見http://www.itdecent.cn/p/f452f71860ab
- 核心代碼分析
- 構(gòu)造url
基本構(gòu)造很簡單http://cn.bing.com/dict/search?q=單詞 - 獲得頁面:構(gòu)造一個(gè)函數(shù),輸入單詞,通過urllib獲得對(duì)應(yīng)頁面,并返回
def get_page(myword):
basurl='http://cn.bing.com/dict/search?q='
searchurl=basurl+myword
response = urllib.request.urlopen(searchurl)
html = response.read()
return html
- 解析頁面:主要使用lxml,通過xpath進(jìn)行內(nèi)容解析,以下以獲得單詞音標(biāo)為例,其他相識(shí)。
def get_yingbiao(html_selector):
yingbiao=[]
yingbiao_xpath='/html/body/div[1]/div/div/div[1]/div[1]/div[1]/div[2]/div' #xpath
bbb="(https\:.*?mp3)" ##這個(gè)是為了獲得對(duì)應(yīng)的讀音MP3文件,使用正則表達(dá)式
reobj1=re.compile(bbb,re.I|re.M|re.S)
get_yingbiao=html_selector.xpath(yingbiao_xpath)
for item in get_yingbiao:
it=item.xpath('div')
if len(it)>0: #處理沒有讀音或者音標(biāo)的部分
ddd=reobj1.findall(it[1].xpath('a')[0].get('onmouseover',None))
yingbiao.append("%s||%s"%(it[0].text,ddd[0]))
ddd=reobj1.findall(it[3].xpath('a')[0].get('onmouseover',None))
yingbiao.append("%s||%s"%(it[2].text,ddd[0]))
if len(yingbiao)>0: #數(shù)據(jù)整形成一個(gè)字符串,用四個(gè)豎線分隔
return reduce(lambda x, y:"%s||||%s"%(x,y),yingbiao)
else:
return ""
- 多數(shù)據(jù)輸入輸出:輸入文件為一個(gè)英語單詞文件,每個(gè)單詞一行,輸出為一個(gè)包含單詞,音標(biāo),釋義,例句的文件,同樣每個(gè)單詞一行。
filename='words.txt' #輸入文件
f=open(filename,"r")
words=f.readlines()
f.close()
filename2='words_jieguo.txt' #輸出文件
f=open(filename2,"w")
i=0
for word in words:
time.sleep(0.25) #怕爬太快給必應(yīng)干掉,所以歇一會(huì)再來
print(word.rstrip(),i)
word_line=get_word(word.rstrip()) #獲得單詞相關(guān)內(nèi)容函數(shù)
f.write("%s\n"%(word_line.encode('utf-8'))) #寫入輸出文件
i=i+1
f.close()
- 整體代碼: python3下的實(shí)現(xiàn),在python2下需要進(jìn)行一些微調(diào)。
import urllib.request
from lxml import etree
import re
import time
from functools import reduce
#獲得頁面數(shù)據(jù)
def get_page(myword):
basurl='http://cn.bing.com/dict/search?q='
searchurl=basurl+myword
response = urllib.request.urlopen(searchurl)
html = response.read()
return html
#獲得單詞釋義
def get_chitiao(html_selector):
chitiao=[]
hanyi_xpath='/html/body/div[1]/div/div/div[1]/div[1]/ul/li'
get_hanyi=html_selector.xpath(hanyi_xpath)
for item in get_hanyi:
it=item.xpath('span')
chitiao.append('%s||%s'%(it[0].text,it[1].xpath('span')[0].text))
if len(chitiao)>0:
return reduce(lambda x, y:"%s||||%s"%(x,y),chitiao)
else:
return ""
#獲得單詞音標(biāo)和讀音連接
def get_yingbiao(html_selector):
yingbiao=[]
yingbiao_xpath='/html/body/div[1]/div/div/div[1]/div[1]/div[1]/div[2]/div'
bbb="(https\:.*?mp3)"
reobj1=re.compile(bbb,re.I|re.M|re.S)
get_yingbiao=html_selector.xpath(yingbiao_xpath)
for item in get_yingbiao:
it=item.xpath('div')
if len(it)>0:
ddd=reobj1.findall(it[1].xpath('a')[0].get('onmouseover',None))
yingbiao.append("%s||%s"%(it[0].text,ddd[0]))
ddd=reobj1.findall(it[3].xpath('a')[0].get('onmouseover',None))
yingbiao.append("%s||%s"%(it[2].text,ddd[0]))
if len(yingbiao)>0:
return reduce(lambda x, y:"%s||||%s"%(x,y),yingbiao)
else:
return ""
#獲得例句
def get_liju(html_selector):
liju=[]
get_liju_e=html_selector.xpath('//*[@class="val_ex"]')
get_liju_cn=html_selector.xpath('//*[@class="bil_ex"]')
get_len=len(get_liju_e)
for i in range(get_len):
liju.append("%s||%s"%(get_liju_e[i].text,get_liju_cn[i].text))
if len(liju)>0:
return reduce(lambda x, y:"%s||||%s"%(x,y),liju)
else:
return ""
def get_word(word):
#獲得頁面
pagehtml=get_page(word)
selector = etree.HTML(pagehtml.decode('utf-8'))
#單詞釋義
chitiao=get_chitiao(selector)
#單詞音標(biāo)及讀音
yingbiao=get_yingbiao(selector)
#例句
liju=get_liju(selector)
return "%s\t%s\t%s\t%s"%(word,yingbiao,chitiao,liju)
filename='5.txt'
f=open(filename,"r")
words=f.readlines()
f.close()
filename2='5_jieguo.txt'
f=open(filename2,"wb")
i=0
for word in words:
time.sleep(0.2)
print(word.rstrip(),i)
word_line=get_word(word.rstrip())
f.write("%s\n"%(word_line))
i=i+1
f.close()