作为一个程序员,会经常查阅一些技术文档和技术网站,很多都是英文的,遇到不认识的词就要查,词典的使用频率也颇高,既然是程序员,高逼格的方式当然是做一个词典,此为动机。
运行平台: Windows
Python版本: Python3.6
IDE: PyCharm
其他工具:Chrome浏览器
1.寻找词典来源
我寻找一个好的词典的标准是:解释到位、数据抓取方便。
几个候选词典有:百度翻译、金山词霸、有道翻译、谷歌翻译。
最终选定金山词霸作为词源,原因:
大学时就使用金山词霸;
url比较简单。
2.数据抓取
2.1 寻找URL
打开金山词霸在线翻译首页http://www.iciba.com/ ,输入一个单词进行查询,此处以“call”为例,查询页面出来以后看URL,浏览器的地址栏内容为http://www.iciba.com/call 。猜想查询URL格式为http://www.iciba.com/ 后面跟上要查询的单词(或词语),将call改为其他单词果然跳出相应的查询页面,中文也一样,由此可以证明以上猜想,也可以看出查询的URL真的简单明了。
2.2 寻找数据
我只是想弄懂单词的意思,所以我需要的数据是如图所示部分:
需要的数据
在浏览器按F12键调出开发者工具,然后刷新页面,我们要在页面中寻找我们需要的数据,按图示操作:
2.查找区域
确定好了数据区域是< ul class="base-list switch_part">和 < /ul>中间的部分,接下来就把这些数据都抓取下来吧。
2.3 抓取数据
抓取数据用到了urllib.request库,解析html用到了BeautifulSoup库。所以首先导入这两个库。
import urllib.request
from bs4 import BeautifulSoup
需要将整个网页内容抓取下来,用如下代码实现:
root_url = 'http://www.iciba.com/'
word = input('请输入想要查询的单词(或"q"退出):\n')
url = root_url + word # 拼接URL
response = urllib.request.urlopen(url)
html = response.read()
有了html内容,接下来要把 base-list switch_part 标签里的内容读取出来,BeautifulSoup里的find可以实现此功能:
soup = BeautifulSoup(html, 'lxml')
tag_soup = soup.find(class_='base-list switch_part')
print(tag_soup)
获得输出结果为:
v.
呼唤,喊叫;
召唤,叫来,召集;
下令,命令;
打电话给
,n.
喊叫,大声喊;
电话联络;
必要,理由;
要求
可以看出里面包含了两个< li class="clearfix">< /li>,这表明call这个单词有两个词性,接下来就要解析出所有的词性,用到BeautifulSoup的find_all函数:
meanings = tag_soup.find_all(class_='clearfix')
for i in range(len(meanings)):
translation = meanings[i].get_text() # 获取文本内容
print(translation.strip()) # 去掉字符串开头和结尾的空行
print('='*30) # 华丽的分割线
最后输出结果如图所示,这已经是我想要的结果了。
3.查询结果
3. 改进优化
该词典的的基本功能已经完成,但是存在几个缺陷。
3.1 查询中文
查询英语单词已经没有问题了,那么查询中文试试:
4.查询中文失败
程序报错,是编码问题,是urllib.request.urlopen函数导致的,我们只需将URL拼接改为url = root_url + urllib.parse.quote(word)即可,试一下:
5.查询中文成功
3.2 查询不存在的单词
如果查询不存在的单词结果会如何:
6.查询不存在的单词失败
失败是因为在tag_soup = soup.find(class_='base-list switch_part')这一行执行完之后,tag_soup的值为None,已经不是BeautifulSoup里的数据类型了,已经不能使用find_all 函数了。那么在此处做一个判断:
如果tag_soup为None,打印提醒语句并等待下一次输入
如果tag_soup不为None,那么继续执行下面的解析。