请技术大佬多多指点思路。
编程小白水平有限,这一篇只是自己的制作练手经历与各位有动手愿望的朋友分享,写代码过程中我主要负责提需求,实际代码主要依靠AI协助生成。
iOS+欧陆测试ok,Mdict也ok。附图
mdx、mdd和css已上传。
20240306更新
changelog
20240303v1: 规范化所有词条源文本为3行格式,修复因换行符混乱导致的部分单词分隔粘连的问题。
20240303v2:对下划线单词增加a href跳转
20240304:添加LINK跳转提高查询便捷性(根据GCIDE的ent和hw配对结果再匹配现有词头,大部分原词头是特殊字符,比如AEon跳转至Æon)
20240306:添加:ABBREVIATIONS词头,作为缩写列表(引用自GCIDE)
后续待更新:
Abbreviations, Usage页面缺失
部分词头部分仍使用特殊字符,暂未能通过普通字符搜索,后续匹配再添加跳转
背景
虽然英文能力尚待提高,但阅读到这两篇帖子,还是在想有没有可能自己也试着读读看。
而在阅读的过程中发现这本mdx词典有以下两点未满足需求:
- 词典内容本身是很不错,但是原来mdx版式上还是有些许不适应,而websters1913.com阅读体验似乎更好。
- 发现某些内容似乎有误,翻看mdx信息得知基于GCIDE 0.48,现在新版是0.53也修复部分既有错误。
原有词典无论是修改css还是mdx都很费劲(不好校对),websters1913网站数据源看起来本身就很不错,于是就萌生了自行重新制作mdx词典的想法。
主要参考的技术帖子
虽然代码本身不一定完全适用,但核心思想适用,也就是bt4baidu大佬提到的寻址+特征识别。过程中碰壁,需要调整思路,就重新用核心思想来思考问题,非常受用。
https://www.pdawiki.com/forum/thread-13219-1-1.html
https://forum.freemdict.com/t/topic/7001
https://forum.freemdict.com/t/topic/9610
使用工具:
编程助手:ChatGPT
平台:WSL + python3.10
制作思路:
- 定义词头列表
- 按词头列表抓取网页中的特征源码保存
- 去重
- 合并
- 格式调试
调试思路
- 先用1个典型单词:跑通单个流程
- 再用5个单词:跑通循环流程
- 完整词头列表:跑通整体流程
定义词头列表
尝试过以下两种不同方法尽量交叉验证确保词头列表完整
- 使用之前版本的mdx提取词头(使用mdx-utils)
- gcide提取词头<ent>标签和<hw>标签内的文本(python + 正则表达式)
经验教训:
- gcide源文件里面的标签内容存在特殊写法,无法直接使用xml相关来按节点处理,一开始用lxml包来提取标签文本并不顺利,后来根据文本特征重新思考,改用正则表达式来提取<ent>和<hw>反而提高了准确性,再通过在<p>里面配对<source>标签来筛选就搞定了。
- 网站的词头文件名本身更多使用特殊字符而不是通用字符,所以提取完和源数据过后,要对照webfont特殊符号做替换去做地址拼接,才能顺利抓到网页。
按词头列表抓取网页中的特征源码保存
- 要抓取什么
这点比较容易,直接浏览器看网页源码,看看在哪个div节点以内包含了所有需要的信息,只保存该节点就好了。
保存的同时,文件开头和结尾都提前写好代码能满足之后mdx格式转换的相关文本,每个txt文本自身都能满足单个词条记录的格式要求,以防合并后要去找bug就很难定位了。 - 怎么抓取
由于网站不需要登录,也没有反爬,于是使用urllib3,创建PoolManager 对象来发送GET的request。
经验教训:
- 文件名检查,避免重复抓取
- 一定要有日志文档:要输出抓取成功的log、抓取失败的log、写入失败的log。否则没法监控过程中是否有异常,哪里异常,无法批量修正(靠人手修正真的要疯)
去重
linux对大小写敏感,所以会把And和and认为是两个单词分别保存。
我的做法是把全小写的文件移动到单独目录,然后把文件名输出成第一个单词首字母大写的词头列表,把这一小戳单词重新检查(已存在则跳过)和抓取。
合并
如果文本不多,可以用cat输出合并
cat *.txt > combine.txt
但10万个txt就没法用这个办法了(会提示命令行太长 无法执行),所以用了find来查找、sort来排序、通过xargs来传递给cat来合并,从而规避命令行长度限制。
find ./raw -name "*.txt" -print0 | sort -z | xargs -0 cat > 1913.comb
经验教训
直接使用了网站自身的css,所以没碰到什么css问题。我把css调用,直接写到每个词条的开头。
经验教训:
Linux文件行末标记是\n,但是转换成mdx的时候会无法正确识别,必须改成\r\n才能正常分开词条。