Apache Nutch是在Java平台上开发的开源网络爬虫工具。按照Nutch官方网站给出的向导,通过使用Nutch命令,可以比较容易地抓取指定种子网站的数据。不过,若是要通过它提供的Java API,以编程方式抓取数据,并存储到指定的数据存储,如MySQL,则有一些技巧或者说秘诀需要注意。经过这几天抽空进行的试验,并查询了相关资料,完成了指定网站数据的抓取。
首先,需要准备好Nutch。目前Nutch的最新版本是2.1,在官方网站可以下载到2.1版本的源代码。奇怪的是,网站并未提供该版本的Bin下载。我们若是要通过Java API调用,则需要依赖于Nutch需要的Jar包。我们可以直接在自己的Java项目中导入这些Jar包,也可以在项目的pom.xml文件中指定Maven的Repository。
要直接导入Jar包,对于2.1版本而言,因为仅提供了源代码,所以在下载了Nutch之后,需要使用ant命令编译。编译后的Jar包会放在${NUTCH_HOME}下的runtime/local/lib下。如果想在pom.xml下管理依赖,而非直接导入,则需要查看Nutch 2.1究竟依赖了哪些Java库,并要了解这些库的版本。这个依赖管理还是比较麻烦的。所以,我在这里直接给出pom.xml文件。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>NutchSample</groupId>
<artifactId>NutchSample</artifactId>
<version>1.0-SNAPSHOT</version>
<repositories>
<repository>
<id>maven-restlet</id>
<name>Public online Restlet repository</name>
<url>http://maven.restlet.org</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.apache.nutch</groupId>
<artifactId>nutch</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.2.8</version>
</dependency>
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-core</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-test</artifactId>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.apache.gora</groupId>
<artifactId>gora-core</artifactId>
<version>0.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.gora</groupId>
<artifactId>gora-sql</artifactId>
<version>0.1.1-incubating</version>
</dependency>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>0.19.4</version>
</dependency>
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet</artifactId>
<version>2.0.5</version>
</dependency>
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet.ext.jackson</artifactId>
<version>2.0.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>
</dependencies>
</project>
|
注意,其中的mysql是后面存储抓取的数据时使用。pom.xml文件前面的maven-restlet的repository是restlet以及restlet.ext.jackson是独有的。因为这两个库必须在这个Repository下才能下载Jar包。
现在,假设我们已经通过maven建立了一个空白的Java项目,并且已经导入了依赖包,或者通过pom.xml下载了这些Jar包。接下来需要执行以下步骤:
建立种子文件
在项目的根目录下,建立urls目录,然后在目录下建立一个文本文件,文件名为seed.txt。内容是你要爬取的网站域名,例如:http://agiledon.github.com。如果要抓取多个网站,可以每行放一个网站域名。
复制配置文件
在项目main\resources目录下,创建文件夹nutchconf(文件夹名其实无关紧要,只要保证其下的文件都在classpath下即可。一个简单的做法是将resource目录设置为source root),然后到${NUTCH_HOME}\runtime\local\conf目录下,将里面所有的文件拷贝到你刚刚创建的文件夹下。
修改配置文件
首先,修改nutch-site.xml文件,将其设置为:
<configuration>
<property>
<name>http.agent.name</name>
<value>my nutch spider</value>
</property>
<property>
<name>parser.character.encoding.default</name>
<value>utf-8</value>
<description>The character encoding to fall back to when no other information
is available</description>
</property>
<property>
<name>storage.data.store.class</name>
<value>org.apache.gora.sql.store.SqlStore</value>
<description>Default class for storing data</description>
</property>
</configuration>
|
修改gora.properties,增加mysql的设置:
gora.sqlstore.jdbc.driver=com.mysql.jdbc.Driver
gora.sqlstore.jdbc.url=jdbc:mysql://localhost:3306/nutch?createDatabaseIfNotExist=true
gora.sqlstore.jdbc.user=root
gora.sqlstore.jdbc.password=
|
注意,jdbc.url值中的nutch为MySQL中数据库的名字,你可以根据自己的需要设置数据库名。前提是你要在MySQL中创建数据库。url值的createDatabaseIfNotExist=true,指代的是如果数据库中不存在该数据库,在运行Crawler时会自动创建。但是,对于MySQL而言,由于编码问题,可能会导致一些问题出现。因此,还是建议由自己创建。创建脚本在后面的链接提供。
接下来,打开gora-sql-mapping.xml,将WebPage映射文件的primarykey的length修改为767。
准备MySQL数据库
这里不再介绍如何安装MySQL数据库,如果是Mac Moutain Lion下安装MySQL,请参考我的博文《使用HomeBrew在Moutain Lion上安装MySQL》。
因为编码的问题,要准备MySQL数据库还是一件麻烦事。在网上找到一篇文章Setting up Nutch 2.1 with MySQL to handle UTF-8,很好地讲解了相关注意事项,并提供了脚本。我这里就不再赘述了。事实上,我们完全可以按照这篇文章来实现运用Nutch命令的方式抓取数据,并存储到MySQL。
调用Nutch Java API
Nutch本身提供了Crawler类来执行数据爬虫的命令。我们可以使用Hadoop的ToolRunner来运行Crawl工具。代码如下:
public class MyCrawler {
public static void main(String[] args) throws Exception {
String crawlArg = "urls -depth 3 -topN 5";
// Run Crawl tool
try {
ToolRunner.run(NutchConfiguration.create(), new Crawler(),
tokenize(crawlArg));
} catch (Exception e) {
e.printStackTrace();
return;
}
}
public static String[] tokenize(String str) {
StringTokenizer tok = new StringTokenizer(str);
String tokens[] = new String[tok.countTokens()];
int i = 0;
while (tok.hasMoreTokens()) {
tokens[i] = tok.nextToken();
i++;
}
return tokens;
}
}
|
复制插件
因为Nutch在抓取数据时,需要对数据进行解析。解析过程中要调用插件urlnormalizer-basic的UrlNormalizer。所以,我们还需要将对应版本Nutch下的插件复制到我们的项目中来。你可以直接在项目的根目录下创建plugins目录,并将其设置为source root,然后将${NUTCH_HOME}\runtime\local\plugins下的插件复制到这个目录中。
接下来就可以运行MyCrawler应用了。注意,在运行该程序时,你一定要启动你的MySQL数据库。在Mac下,可以输入命令mysql.server start来启动。你可能会发现项目无法编译成功,因为某些插件依赖的对象无法找到。我猜测在运行ant时,并没有编译这些插件,使得这些插件的依赖库并没有完全获得。我采取了一种粗暴的做法,就是直接将这些无法编译通过的插件直接删除。至少,对于我们这个简单的抓取工作而言,事实上用不了这么多插件。
运行完成后,你可以到MySQL数据库下查询webpage数据表。如果运行成功,可以查询到表中的数据记录。如果运行失败,一方面可以在IDE工具的控制台上看到一些信息。另一方面也可以查询日志。日志记录会更详细,该文件可以在当前项目的根目录下找到,即hadoop.log日志文件。我在之前碰到的一个问题就是内存不够的异常,控制台上并未显示该信息,但在hadoop.log中能够找到,帮助我定位了问题。运行这样一个普通任务,把内存设置为512M就足够了。
转自:http://agiledon.github.io/blog/2013/03/07/nutch-crawler-crawl-data-and-store-to-mysql/
相关推荐
4. **数据存储**:抓取的数据可能需要存入数据库(如MySQL、MongoDB)或文件系统(如CSV、JSON)。Java的JDBC API可以连接多种数据库,而Jackson或Gson库则方便地将数据序列化为JSON格式。 5. **爬虫框架**:Java也...
7. **数据存储**:爬取的数据通常需要存储,这可能涉及到数据库(如MySQL、MongoDB)或文件系统(如CSV、JSON)。 8. **异常处理与日志记录**:良好的错误处理和日志记录机制可以帮助调试和监控爬虫运行情况。 9. ...
Java有许多数据存储解决方案,如CSV文件、MySQL数据库、MongoDB等NoSQL数据库。根据数据量和需求,开发者会选择合适的存储方式。 6. IP代理与反反爬策略:为了避免被目标网站封IP,开发者可能需要使用代理IP池,并...
文档中可能未直接提及数据库,但在爬虫系统设计中,如何存储和管理抓取的数据是一个重要环节。 9. 数据封装: - LinkTypeData类:这是一个Java类,用于封装爬虫抓取到的链接类型的数据。它具备属性如链接的href地址...
3. **数据存储**:抓取到的数据通常需要存储起来,以便后续处理。可以选择关系型数据库(如MySQL)、非关系型数据库(如MongoDB)或者文件系统(如HDFS)等。对于微型计算机服务履历库,可能需要考虑存储效率和查询...
6. **数据存储**:抓取的数据通常需要存储,可以是文件系统、数据库(如MySQL、MongoDB)或是云存储服务。Java提供了JDBC接口和其他库如JPA、Hibernate来方便地与数据库交互。 7. **异常处理与日志记录**:良好的...
5. **爬虫(Web Crawler)**:搜索引擎通常需要从互联网上抓取数据,这就需要一个爬虫系统。Java中可以使用Jsoup或Nutch等库来实现网页抓取和解析。 6. **数据存储**:索引和搜索结果需要持久化存储。可以选择使用...
2. 数据库:MySQL、MongoDB等数据库系统可作为搜索引擎的数据存储后端,与Java无缝集成。 3. MapReduce:在分布式环境中,Hadoop的MapReduce模型可以处理搜索引擎的海量数据。 4. RESTful API:Spring Boot等框架...
7. **数据存储**:抓取的数据可能需要存储在数据库中,如MySQL、MongoDB等,或者使用文件系统如CSV或JSON文件。 8. **异常处理与反爬策略**:为了应对可能出现的网络问题、验证码、IP限制等,爬虫需要具备良好的...