65.9K
CodeProject 正在变化。 阅读更多。
Home

我是如何抓取 Merriam-Webster 词典的

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.38/5 (4投票s)

2019 年 9 月 19 日

CPOL

6分钟阅读

viewsIcon

16943

downloadIcon

746

一种不费吹灰之力下载大量文件的简单方法

第二部分:Merriam-Webster 词典:将 HTML 转换为 RTF

引言

Merriam-Webster 词典可在互联网上免费使用。任何人都可以访问他们的网站。输入一个单词。获取定义。我相当确定,编写几行代码来检索他们数据库中的每个文件并将它们复制到您的硬盘上可能处于道德界限的边缘,但只要您在插入对特朗普这个词的辱骂性定义后不将其出售以牟利……您就没事。

人们可能想这样做的原因很简单,而且有很多,但说实话……就是因为。为什么不呢,对吧?称之为挑战、二进制健美操或仅仅是乐趣。它比数独好。

它很酷的一点是,一旦你制作了一个网页抓取器,制作下一个就会容易得多。而且你最终可能会找到使用它的好理由,即使你现在想不出理由。我的电脑上有 Merriam-Webster 词典的副本,这很酷,因为它现在已集成到我的文字处理器中。是的,我知道,MS-Word 也有这个功能。我可以出去买一个寿命更长、外观比我手工制作的任何东西都好的工厂制造的篮子,但又能怎样呢,我家附近不远处有一个沼泽,自己用采摘的芦苇制作一个,对我来说只花费几个小时的阳光明媚的休闲时间。

无论如何,以下是我如何抓取 Merriam-Webster 词典的方法……

背景

Merriam-Webster 的维基百科页面会告诉你,George & Charles Merriam 于 1828 年创立了他们的公司,然后于 1843 年收购了 Noah Webster 的遗产,以建立他们现在享誉世界的参考书出版帝国。他们编辑和出版词典已有近 200 年的历史,自从高中以来,我可能拥有过六本他们的产品,包括我身边书架上的那本。

Using the Code

本文附带的源代码本身不会下载 MW 数据库,我会告诉你为什么……

首先,我会解释一下它的作用。我将 Merriam-Webster 网站上列出的单词集合中的第一个 URL 给出,即 “cause”。它将此 URL 插入到它需要下载的 URL 队列(List<string>)中。然后它从列表中取出第一个 URL,并将其添加到另一个已下载 URL 列表中(目前为空),然后从 Merriam-Webster 网站下载文件。然后它解析 HTML 并找到指向 “cause” 附近的词典条目 的链接。一旦找到这些,它会将它们与已下载 URL 列表进行比较,并将尚未下载的 URL 添加到前面提到的列表中,然后在继续处理下一个 URL 之前,将此文件保存到我的硬盘上。

想法很简单。获取一个文件,找到它尚未尝试过的链接,并将 HTML 文件保存在硬盘上。

但是……有一个问题。通常都会有问题。有些单词出现在不同的 URL 下,但实际上是同一个文件。所以当你遇到字母 A 的文件时,它的“附近的条目 A”链接都指向自身,这使得这个简单的抓取算法失效。因此,我不得不将我的同义词词典按字母顺序排列的内容作为要尝试的单词/文件名包含在内。由于 Merriam-Webster 词典中的所有文件名都与它们定义的单词相同,因此您可以简单地输入您想要下载的任何单词的地址,例如,www.merriam-webster.com/dictionary/whatever。所以,每当我的算法的“待尝试 URL 列表”为空时,它就会转到同义词词典,取出列表中的第一个单词,并询问自己是否在下载它之前已经尝试过该单词,并看看它是否能自我重启以检索新 URL 并将它们添加到其不断增长的列表中。

//
string strURL_source = ParseHTML_MerriamWester_GetNextUntriedWordFrom_URLsList();
if (strURL_source.Length == 0)
{
    strURL_source = ParseHTML_MerriamWester_GetNextUntriedWordFrom_Thesaurus();
}
//

您可以在上面的代码中看到它决定从收集的 URL 列表中获取一个 URL 或尝试同义词词典路线的行。您需要自己获取同义词词典才能做到这一点。但我计划通过另外两篇文章来发布此项目的成果,这些文章将演示

  1. 这些文件是如何从 255,000 个 HTML 文件(脱机时看起来很糟糕)重写成富文本文件文档的,这些文档看起来比源文件更好(比您想象的要麻烦得多)
  2. 如何将这个离线词典集成到一个文字处理器中,以帮助您更优雅地写作(它需要一个搜索引擎)。

下面的屏幕截图向您展示了包含我从 Merriam-Webster 网站上获取的战利品的目录。

(此处插入我带着傻笑的照片)。

关注点

以下代码利用了我有限的 HTML 知识。本质上,它检测 Merriam-Webster 的网页设计师用来告诉您的浏览器它将列出您当前查看的单词附近的单词链接的 HTML 标记的存在。然后,它会从 HTML 文档中提取所有这些单词的链接,并将之前未见过的链接添加到它将用于下载下一个文件的新 URL 列表中。

//                  URLsNearby
{
    string strURLSNearby_start = "<div id=\"near-entries-anchor\" class=";
    int intURLSNearby_Start = strHTML.IndexOf(strURLSNearby_start);
    if (intURLSNearby_Start > 0)
        strSource_URLsNearby = GetNext(strHTML, "<div ", "</div>", intURLSNearby_Start);
}

// get next URL
{
    string strMWNextURLList_Start = "<h2>Dictionary Entries near <em>";
    string strMWNextURL_Start = "<a class=\"b-link";
    int intCut_URL_List_Start = strSource_URLsNearby.IndexOf(strMWNextURLList_Start);

    if (intCut_URL_List_Start >= 0)
    {//<a class="b-link" data-
        int intCut_URL_Next_Start 
              = strSource_URLsNearby.IndexOf(strMWNextURL_Start, intCut_URL_List_Start);
        string[] strSeparator = { strMWNextURL_Start };
        string[] strUrlsNearby 
              = strSource_URLsNearby.Split(strSeparator, 
                                           StringSplitOptions.RemoveEmptyEntries);
        IEnumerable<string> URLs = lstURLs.Distinct();
        lstURLs = (List<string>)URLs.ToList<string>();

        for (int intCounter = 0; intCounter < strUrlsNearby.Length; intCounter++)
        {
            string strUrlNearby = strSeparator[0] + strUrlsNearby[intCounter];
            string strURL_New = RemoveMarkUpLanguage(GetNext(strUrlNearby, "<a ", "</a>"));
            if (strURL_New.Length > 0 && !lstURLs.Contains(strURL_New))
                if (strURL_New.IndexOfAny(chrInvalidCharacter) < 0)
                    lstURLs.Add(strURL_New);
        }
    }
}
他们的网站看起来像这样

HTML 看起来像这样

因此,您需要做的是获取上面看到的 <div id 的内容,然后解析该文本,从中提取每个 <a class= 链接中的相关信息,这些链接提供了您继续前进所需的 URL。为了简化这一点,它使用了 GetNext()RemoveMarkUpLanguage() 函数。为了在处理这些 URL 时让我的眼睛舒适,我将 unicode 转换为可读文本,然后在使用 URL 下载文件之前必须将其重新 unicode。

我包含了 **HTML-ator** 工具,该工具是我为帮助我穿透 HTML 抓取领域深邃的奥秘而制作的。请注意,我从未为其编写任何说明手册,因此您需要自己玩一下才能了解它的作用。本质上,它擅长搜索标记,跳转到特定的字符索引,并提取 HTML 标记之间的文本内容,例如 <p> </p>

下面是它的一个屏幕截图。本文的 HTML 被复制粘贴到左边的文本框中。然后,将光标放在您感兴趣的 <p> 段落标记的左侧,然后单击下方框中的 p。**保留**单选按钮告诉它将段落标记及其内容发送到右侧的文本框。此工具利用了一个易于使用的 **Sweep-and-Prune** 算法来绘制 classMultiButtonPic 中的所有按钮,这些按钮是我特意为此场合制作的。红色圆圈下方的文本中的每个单词都是一个可单击按钮,当光标经过时会做出反应。图片被绘制一次,然后用必要的突出显示刷新鼠标光标事件。

我相信还有更多要说的,但一切都很简单。难的部分是如何让这些文件在 Rich Text Boxes 中看起来很好。那些东西很挑剔,需要一些技巧才能让它们按照您的意愿工作。您甚至可能拥有一件“我讨厌富文本框”的 T 恤。但别担心,我有一个好办法来帮助您。请尽快回来看看。

第二部分:Merriam-Webster 词典:将 HTML 转换为 RTF

© . All rights reserved.