最近上课想给学生做一下单词表,以前有学生反映课本的单词表没有音标,这也确实是一个问题。而且以前的单词表单词和解释之间没有明显界限,不适合做成表格,更不要说生成单词卡了。所以要是能有一个词典api,我出一个单词,它告诉我音标,解释,例句就好了。
Jonathan LEI:必应词典第三方API v2.0zhuanlan.zhihu.com上面这个是在知乎上别人做的api,在线那种。不过现在上不去。
所以我就想,要不自己做一个吧。
目前需求比较简单(其实主要是想自动生成音标,然后查找比较公认的解释)。微软词典本身没有做api,所以现在只能模拟网页访问,然后parse返回的html页面。不过有了requests和beautifulsoup,这些都不是事。
需要的python package
如果还没有安装requests和beautifulsoup的话,使用下面的命令安装,可以带-i https://pypi.tuna.tsinghua.edu.cn/simple
这个参数,会加快安装速度
pip install requests
pip install beautifulsoup4
导入会用到的包
import requests
from bs4 import BeautifulSoup
import pandas as pd
import time
DictRstParser类
不确定应该怎么写的时候,先弄个类出来总不会有大错。
class DictRstParser:
大体来说这个naive implementation的步骤包括:
- 使用requests.get从
https://cn.bing.com/dict/search?q=
拿到某个词在词典的查询结果网页。 - 利用beautifulsoup把网页文本转换成方便查找信息的soup形式
- 利用浏览器的
检查
工具,找到感兴趣的内容所在的html标签 - 使用select或者find得到这个标签,然后用get_text()函数获得里面的文本
这是最开始的设计,后面把4这步抽象成了一个函数,加入了情况判定:
def get_content(self,from_obj,selector_str):
rst = from_obj.select(selector_str)
if len(rst)==0:
return None
elif len(rst)==1:
return rst[0].get_text().replace("xa0"," ").strip()
else:
return 'n'.join([e.get_text() for e in rst])
然后就是不停的使唤这个函数了,不过复制粘贴的多了(当你粘贴次数超过三次的时候,就应该想一下自己是不是代码写的有点不对了),觉得使用dict会更好一点,目前__init__
函数长这样:
def __init__(self,word_str):
self.req_link = f"https://cn.bing.com/dict/search?q={word_str}"
self.res_txt = requests.get(self.req_link).text
self.soup = BeautifulSoup(self.res_txt,'html.parser')
self.word_info_selector_dict = {
'word':'div#headword',
'eng_pr':'div.hd_pr',
'ame_pr':'div.hd_prUS',
'tongyi':'div.wd_div',
'fushu':'div.hd_div1',
'defination':'div.qdef > ul > li',
}
self.word_info_dict = {}
self.related_divs = self.soup.select('div.lf_area > div')
for k,v in self.word_info_selector_dict.items():
self.word_info_dict[k]=self.get_content(self.related_divs[0],v)
self.word_info_dict['sentences']=self.get_content(self.related_divs[1],'div#sentenceSeg')
主要的配置部分写在word_info_selector_dict 里面,然后通过遍历word_info_selector_dict .item()来实现反复使唤get_content的目的
试试这个api
现在的工作流程是将要找的单词放在一个单独的文本文件里,比如说wordlist.txt
,然后在代码里面像下面这么做:
with open('wordlist.txt','r') as wordlistfile:
word_list = wordlistfile.readlines()
row_list = []
for w in word_list:
parser = DictRstParser(w)
row_list.append(parser.word_info_dict)
time.sleep(0.5)
df = pd.DataFrame(row_list)
xlwriter = pd.ExcelWriter('wordlist.xlsx',engine='xlsxwriter')
df.to_excel(xlwriter,'Sheet0')
xlwriter.save()
前面是读取wordlist.txt
这个文件,然后readlines把各行弄进一个list里面。之后遍历这个list,生成 DictRstParser实例,读取做好的word_info_dict。为了防止被封,每走一个单词停半秒(time.sleep(0.5))
输出的时候用xlsx而不是csv:毕竟转码是好麻烦的一件事情,尤其是这种中英混搭还有音标的,天知道该用什么码。总之交给excel自己搞定好了
需要note的一下的地方:如何逐行累积最后形成一个dataframe[1]:
- 生成一个空的list:
row_list =[]
- 将各行内容做成dict,逐个往list里append:
row_list.append(parser.word_info_dict)
- 使用pandas.DataFrame()将list转成df:
df = pd.DataFrame(row_list)
[2]
参考
- ^stackoverflow上的相关讨论 https://stackoverflow.com/questions/10715965/add-one-row-to-pandas-dataframe
- ^pd是前面导入的时候用了import pandas as pd,这还是蛮常见的一种写法