编者注:我们发现了有趣的系列文章《30天学习30种新技术》,正在翻译,一天一篇更新,年终礼包。下面是第 18 天的内容。
今天我决定学习如何使用Java做网页链接的文本和图像提取。在大多数内容发现网站上(如Prismatic)这是一个非常常见的需求,今天就是学习如何使用一个名为boilerpipe的Java库来完成这个任务。
准备
基本的Java知识是必需的,安装最新的Java开发工具包(JDK ),可以是OpenJDK 7或Oracle JDK 7。
注册一个OpenShift帐户,它是完全免费的,可以分配给每个用户1.5 GB的内存和3 GB的磁盘空间。
安装RHC客户端工具,需要有ruby 1.8.7或更新的版本,如果已经有ruby gem,输入
sudo gem install rhc
,确保它是最新版本。要更新RHC的话,执行命令sudo gem update rhc
,如需其他协助安装RHC命令行工具,请参阅该页面: https://www.openshift.com/developers/rhc-client-tools-install通过
rhc setup
命令设置您的OpenShift帐户,此命令将帮助你创建一个命名空间,并上传你的SSH keys到OpenShift服务器。
第1步:创建一个JBoss EAP的应用
首先从创建示例应用程序开始,把该应用称作 newsapp
。
$ rhc create-app newsapp jbosseap
然后可以使用如下命令:
$ rhc create-app newsapp jbosseap -g medium
这样会创建一个应用程序容器,设置好所有需要的SELinux政策和cgroup配置,OpenShift也将创建一个私人git仓库并克隆到本地。最后,OpenShift会给外界提供一个DNS,该应用程序将在http://newsapp-{domain-name}.rhcloud.com/
下可以访问(将 domain-name
更换为自己的域名)。
第2步:添加Maven依赖
在 pom.xml
文件里添加如下依赖:
<dependency>
<groupId>de.l3s.boilerpipe</groupId>
<artifactId>boilerpipe</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.13</version>
</dependency>
同时也需要加一个新的库:
<repository>
<id>boilerpipe-m2-repo</id>
<url>http://boilerpipe.googlecode.com/svn/repo/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
通过更新 pom.xml
文件里的几个特性将Maven项目更新到Java 7:
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
现在就可以更新Maven项目了(右键单击>Maven>更新项目)。
第3步:启用CDI
使用CDI来进行依赖注入。CDI、上下文和依赖注入是一个Java EE 6规范,能够使依赖注入在Java EE 6的项目中。
在 src/main/webapp/WEB-INF
文件夹下建一个名为beans.xml
中一个新的XML文件。更换beans.xml中的以下内容:
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
第4步:创建Boilerpipe内容提取服务
现在创建一个Boilerpipe内容提取服务的服务类,这个类会用一个url,从这个url中提取标题和文章内容。
import java.net.URL;
import java.util.Collections;
import java.util.List;
import com.newsapp.boilerpipe.image.Image;
import com.newsapp.boilerpipe.image.ImageExtractor;
import de.l3s.boilerpipe.BoilerpipeExtractor;
import de.l3s.boilerpipe.document.TextDocument;
import de.l3s.boilerpipe.extractors.ArticleExtractor;
import de.l3s.boilerpipe.extractors.CommonExtractors;
import de.l3s.boilerpipe.sax.BoilerpipeSAXInput;
import de.l3s.boilerpipe.sax.HTMLDocument;
import de.l3s.boilerpipe.sax.HTMLFetcher;
public class BoilerpipeContentExtractionService {
public Content content(String url) {
try {
final HTMLDocument htmlDoc = HTMLFetcher.fetch(new URL(url));
final TextDocument doc = new BoilerpipeSAXInput(htmlDoc.toInputSource()).getTextDocument();
String title = doc.getTitle();
String content = ArticleExtractor.INSTANCE.getText(doc);
final BoilerpipeExtractor extractor = CommonExtractors.KEEP_EVERYTHING_EXTRACTOR;
final ImageExtractor ie = ImageExtractor.INSTANCE;
List<Image> images = ie.process(new URL(url), extractor);
Collections.sort(images);
String image = null;
if (!images.isEmpty()) {
image = images.get(0).getSrc();
}
return new Content(title, content.substring(0, 200), image);
} catch (Exception e) {
return null;
}
}
}
上述代码执行以下操作:
- 首先在给定的url中读取文件
- 然后解析HTML文档并返回TextDocument
- 接下来从文本文件中提取标题
- 最后从文本中提取内容,返回一个应用的值对象的新实例(value object)
第5步:启用JAX-RS
为启用JAX-RS,建立一个扩展 javax.ws.rs.core.Application
的类,并通过如下所示的 javax.ws.rs.ApplicationPath
注释指定应用程序路径。
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/api/v1")
public class JaxrsInitializer extends Application{
}
第6步:创建ContentExtractionResource
创建ContentExtractionResource
类,它会返回一个JSON内容对象。创建一个名为ContentExtractionResource
的新类,并用如下所示的内容替换:
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import com.newsapp.service.BoilerpipeContentExtractionService;
import com.newsapp.service.Content;
@Path("/content")
public class ContentExtractionResource {
@Inject
private BoilerpipeContentExtractionService boilerpipeContentExtractionService;
@GET
@Produces(value = MediaType.APPLICATION_JSON)
public Content extractContent(@QueryParam("url") String url) {
return boilerpipeContentExtractionService.content(url);
}
}
部署到OpenShift
最后,更改部署到OpenShift
$ git add .
$ git commit -am "NewApp"
$ git push
在代码push和部署完成后,我们可以在 http://newsapp-{{domain-name}.rhcloud.com
查看正在运行的应用程序。我的示例应用程序展示如下。
今天就这些,欢迎反馈。
原文 Day 18: BoilerPipe--Article Extraction for Java Developers
翻译整理 SegmentFault