為什么要建立自己的單詞庫
用過各種的背單詞軟件,總是在使用其他人的詞庫或者軟件自己提供的詞庫,基本是人家提供什么自己就用什么,要想有更多的自主基本沒有,最近看一個 COCA的按單詞使用頻率來提取的2萬單詞表,但沒有對應的單詞庫,知米里倒是可以直接導入英文單詞,系統幫你匹配上音標、讀音、例句及解釋,然而匹配后的結果你卻無法導出。
特別是最近準備利用AnkiDroid來進行單詞背誦,所以有種要建立自己的單詞庫的需求。更進一步或許可以自己開發一個背單詞的軟件也是有可能的。“萬里長征第一步,先來建立單詞庫”,走一步看一步吧。
詞庫的需求分析
根據需求,詞庫應該包括如下內容
- 英文:對應英語單詞
- 音標及讀音:分為美語音標,讀音,英語音標,讀音
- 詞性,中文釋義:單詞多個含義的不同詞性和中文
- 例句:單詞的例句
- 助記:比如詞根或者其他有助于記憶的說明
- 輸出一個文本文件好了,方便以后進行各種處理
使用技術的選擇
獲得單詞的相關信息,目前可以通過百度翻譯,有道翻譯,必應翻譯,谷歌翻譯,金山詞霸等方式,在綜合考慮后選擇通過必應字典模式獲得相關數據。
數據爬取上,目前最為流行的并且相對成熟的是使用python(也就懂python),所以選擇python
對于使用python爬取數據,一般有兩種模式,一種是python+urllib+lxml
, python+selenium+chrome
。本身就是一個小項目,同時自身學習能力有限就沒考慮scrapy的爬蟲框架了。估計以后要是大量、各種、經常性爬取內容才會考慮這個。什么都要學習呀,學習是要成本的。
-
python+selenium+chrome
- 可以模擬瀏覽器動作,能有效的解決ajax模式下的數據爬取問題
- 很容易實現基于瀏覽器的測試
- 必須能夠趟過 selenium 的一系列坑,相對學習成本要高
-
python+urllib+lxml
- 學習成本相對較低
- ajax,動態網頁的爬取不方便
當然兩者都需要有一定的正則表達式能力。由于必應字典基本都屬于靜態網頁,所以選擇方式2就是python+urllib+lxml
模式。
技術實現
1.python及相關環境安裝:
使用anaconda 完成整體環境的安裝,這里略過,詳細見http://www.lxweimin.com/p/f452f71860ab
- 核心代碼分析
- 構造url
基本構造很簡單http://cn.bing.com/dict/search?q=單詞
- 獲得頁面:構造一個函數,輸入單詞,通過urllib獲得對應頁面,并返回
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進行內容解析,以下以獲得單詞音標為例,其他相識。
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)" ##這個是為了獲得對應的讀音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 ""
- 多數據輸入輸出:輸入文件為一個英語單詞文件,每個單詞一行,輸出為一個包含單詞,音標,釋義,例句的文件,同樣每個單詞一行。
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) #怕爬太快給必應干掉,所以歇一會再來
print(word.rstrip(),i)
word_line=get_word(word.rstrip()) #獲得單詞相關內容函數
f.write("%s\n"%(word_line.encode('utf-8'))) #寫入輸出文件
i=i+1
f.close()
- 整體代碼: python3下的實現,在python2下需要進行一些微調。
import urllib.request
from lxml import etree
import re
import time
from functools import reduce
#獲得頁面數據
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 ""
#獲得單詞音標和讀音連接
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)
#單詞音標及讀音
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()