本文提供了一个名为 Mowglee 的 Web 爬虫系统的实现,该系统使用地理作为爬虫的主要分类标准。此外,它还以多线程模式运行,该模式提供机器人排除协议的默认实现、站点地图生成、数据分类器、数据分析器以及用于构建网络爬虫的应用程序的通用框架。实现是用核心 Java 实现的。Mowglee 是 Java 中的多线程地理网络爬虫。
为此,您应该具备中级到专家级的核心 Java 技能,了解 Java 中多线程的复杂性,并了解 Web 爬虫的实际使用和需求。
您将学习什么
如何在核心 Java 中编写简单且分布式基于节点的 Web 爬虫。
如何设计具有地理亲和力的网络爬虫。
如何编写基于多线程或异步任务执行器的爬网程序。
如何编写具有模块化或可插拔架构的网络爬虫。
如何分析多种类型的结构化或非结构化数据。(最低限度覆盖)
地理爬网
我在这里描述的爬行系统在更高的可达性方面最大限度地提高了地理渗透率。它使用特定地理位置的最重要或更高吞吐量的超链接作为起点或爬行主页。吞吐量是指与给定地理位置具有更高数据相关性的多种不同链接、文本或媒体。它是使用 Java 中的异步任务执行和多线程概念开发的。
爬虫称为 Mowglee。最好保持“用户代理”名称相同,但您可以添加自己的变体。例如,如果要添加单词“raremile”来标识变体,请将用户代理重命名为“mowglee-raremile”。在尝试运行此操作系统之前,请确保您的系统上安装了 JDK 1.6+。其中一些类有自己的方法,但它们只是为单元测试而编写的。main()
运行应用程序的主类是 。您也可以在 using 下运行捆绑的 JAR 文件。如果使用 JDK 6 执行(推荐),则可以使用 JDK 6 进行性能分析。in.co.mowglee.crawl.core.Mowgleedistjava –jar mowglee.jarjvisualvm
在图中,类 Mowglee 显示为 MowgleeCentral。
Mowglee 的核心爬行系统使用爬行器的层次结构来实现高效爬行。 是一个按顺序调用 Mowglee 中所有爬网类型的类:静态爬网、外围爬网和网站爬网。MowgleeCrawl
MowgleeStaticCrawl是爬网过程的起始类。这将读取静态地理主页或爬回家。您可以为每个地理位置配置多个爬网主目录,并为每个区域启动一个进程。您可以将其可视化为多智能体系统的非常松散的表示。默认安全等待期为 10 秒,可根据需要进行配置。这是为了确保在开始主爬网之前,所有数据都可以从其他正在运行的进程或其他正在运行的线程中获取。MowgleeStaticCrawl
MowgleePeripheryCrawl是从给定页面或超链接中推断顶级域的传递爬虫。它的唯一目的是使(Pass 2)更容易和更可衡量。外围爬网过程还可用于跨爬网删除任何重复的顶级域,以便更集中地进行下一次爬网。在第 1 关中,我们只关注链接而不是数据。MowgleeSiteCrawl
MowgleeSiteCrawl是 Pass 2 爬网程序,用于对每个线程池使用 JDK 6 执行器服务实例化单个线程池。此阶段的 Mowglee 爬网过程非常广泛,并且就要检测的数据类型而言非常具有侵入性。在第 2 阶段,我们将链接类型分类为协议、图像、视频或音频,并且我们还尝试获取有关页面元数据的信息。这个阶段最重要的方面是,我们以动态但可控的方式进行分析,因为我们试图根据网站上的页面数量增加线程池大小。MowgleeSite
Mowglee 被组织为每个爬行通道中的一组工作人员。对于 Pass 1,阅读和演绎的实际工作由 完成。 对于第 2 关,读取和分析链接的工作由 完成。在此过程中,它使用的帮助程序类包括数据分析器,稍后将对此进行说明。MowgleePeripheryWorkerMowgleeSiteWorker
MowgleePeripheryWorker 用于存储顶级域。最重要的代码行位于 中,用于打开任何给定 URL 的套接字并读取其内容,如下所示。MowgleeDomainMapMowgleeUrlStream
StringBuffer httpUrlContents = new StringBuffer();
2
InputStream inputStream = null;
3
InputStreamReader inputStreamReader = null;
4
5
MowgleeLogger mowgleeLogger = MowgleeLogger.getInstance("FILE");
6
7
// Check if the url is http
8
try {
9
10
if (crawlMode.equals(MowgleeConstants.MODE_STATIC_CRAWL)) {
11
mowgleeLogger.log("trying to open the file from " + httpUrl, MowgleeUrlStream.class);
12
inputStream = new FileInputStream(new File(httpUrl));
13
14
inputStreamReader = new InputStreamReader(inputStream);
15
16
} else {
17
mowgleeLogger.log("trying to open a socket to " + httpUrl, MowgleeUrlStream.class);
18
inputStream = new URL(httpUrl).openStream();
19
20
inputStreamReader = new InputStreamReader(inputStream);
21
}
22
23
// defensive
24
StringBuffer urlContents = new StringBuffer();
25
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
26
String currentLine = bufferedReader.readLine();
27
28
while (currentLine != null) {
29
urlContents.append(currentLine);
30
currentLine = bufferedReader.readLine();
31
}
32
33
if (httpUrl != null & httpUrl.trim().length() > 0) {
34
MowgleePageReader mowgleePageReader = new MowgleePageReader();
35
mowgleePageReader.read(httpUrl, urlContents, crawlMode);
36
37
mowgleeLogger.log("the size of read contents are " + new String(urlContents).trim().length(),
38
MowgleeUrlStream.class);
39
}
40
41
// severe error fixed - possible memory leak in case of an exception! - [connection leak fixed]
42
// inputStream.close();
43
} catch (FileNotFoundException e) {
44
45
mowgleeLogger.log("the url was not found on the server due to " + e.getLocalizedMessage(),
46
MowgleeUrlStream.class);
47
} catch (MalformedURLException e) {
48
49
mowgleeLogger.log("the url was either malformed or does not exist", MowgleeUrlStream.class);
50
} catch (IOException e) {
51
52
mowgleeLogger.log("an error occured while reading the url due to " + e.getLocalizedMessage(),
53
MowgleeUrlStream.class);
54
} finally {
55
56
try {
57
// close the connection / file input stream
58
if (inputStream != null)
59
inputStream.close();
60
} catch (IOException e) {
61
62
mowgleeLogger.log("an error occured while closing the connection " + e.getLocalizedMessage(),
63
MowgleeUrlStream.class);
64
}
65
}
66
在 Mowglee 中,有各种分析器用于多种类型的数据和媒体。作为此代码库的一部分实现的分析器是 。它用作给定顶级域中所有链接的内存存储。 它还维护从给定顶级域中所有已爬网和分析的超链接中访问和收集的 URL 列表。MowgleeLinkAnalyzerMowgleeSiteMap
MowgleeGarbageCollector 是在运行主应用程序时实例化并启动的守护程序线程。由于每个线程实例化了大量对象,因此此线程尝试在内存使用的安全限制内控制和强制执行内部垃圾回收机制。 为 Mowglee 中所有类型的记录器提供抽象类。此外,还有 提供的实现。 这继承自 .所有其他类型的过滤器都更接近爬虫系统的功能,可以从这个特定类扩展而来。MowgleeLoggerRobotsExclusionProtocolMowgleeRobotsExclusionFilterMowgleeCrawlFilter
MowgleeCommonUtils 提供了许多常见的帮助程序函数,例如 . 是用于根据 SiteMaps 协议生成站点地图的占位符类,也是更广泛或自定义实现的起点。可以添加用于分析图像、视频和音频的实现。仅提供占位符。deduceTopLevelDomain()owgleeSitemapGenerator
应用
以下是此类网络爬虫的理想应用程序。
网站治理和政府执法
任何本地化或定制的地理规则都可以使用该系统来执行。此外,通过手动推导或出于任何管理目的自动检测数据模式完成的任何类型的分类都可以通过生成的数据轻松完成。
排名网站和链接
可以对来自该站点的数据执行进一步本地化到特定地理或特定区域的搜索引擎系统的站点和链接的排名。在同一地理位置内查找链接的关系和点击模式会更容易。
分析和数据模式
可以使用第三方或自定义工具分析从该爬虫收集的数据,以进一步创建知识。此外,还可以从生成的数据量创建相关的数字存储库。
基于关键字的广告
一个重要的应用是根据从这个爬虫系统收集的数据来驱动广告。分析器可用于查找特定术语、关键字、短语,并嵌入相关广告或为广告商生成建议。
增强
以下是涉及此类网络爬虫的一些增强功能。
使用图形数据库存储
您可以添加图形数据库的实现,也可以使用流行的 NoSQL 图形存储选项之一。起点是类。MowgleePersistenceCore
各种分析仪
您可以根据自己的组织或学术需求添加更多分析器。您必须扩展的基类是 ,您可以参考以了解分析器的实现。MowgleeAnalyzerMowgleeLinkAnalyzer
重点分类器
您可以添加分类器或插件的层次结构,以根据术语、关键字、地理术语或短语自动对数据进行分类。一个例子是 。MowgleeReligiousAbusePlugin
复杂的演绎机制
可以添加更复杂的演绎机制,以进一步创建特定地理区域内爬网的相关性。这包括忽略特定爬网会话的地理区域、国家/地区甚至大陆之外的链接。在更高层次上,例如在大陆层面,这可以作为一个协调的多主体系统来实施。
站点地图生成
此处提供了站点地图生成机制的起点。您也可以在内部使用其他站点地图生成库,也可以开发自己的自定义实现来增强此功能。
结论
Mowglee 不保证会创建站点地图或将其用于抓取。它使用一种机制,并确保从站点内部到自身可能无法访问的所有链接也被抓取。Mowglee 目前没有终止机制。我提供了一个占位符供您根据您的使用情况进行决定。这可能基于抓取的顶级域数量、数据量、抓取的页面数、地理位置边界、要抓取的网站类型或任意机制。async
请关闭系统上的所有应用程序,将所有可用的系统资源专用于 Mowglee。默认起始爬网点为 http://www.timesofindia.com。您也可以尝试将起始爬网点更改为其他站点。在当前窗体中,您可以使用该文件读取爬网分析。没有提供其他存储机制。您可以在 EditPlus 等编辑器中保持此文件打开状态,以持续监控其内容。mowglee.crawl
本文应该为构建分层多线程爬网程序奠定了良好的基础,特别是对于需要基于地理位置的分类和相关性的应用程序。它还应该可以帮助您节省时间(通过重用此代码库)来构建爬虫或应用程序。如上所述,您可能还想在 Mowglee 的基础上构建增强功能,并将其发布回 DZone,以造福整个社区!