1方案概述
抓取维基百科数据。
根据网上调查,现有三种解决方案:
² 使用Apache Nutch爬虫技术,深度抓取页面数据。
² 使用JWPL技术,解析Wikipaia离线数据。
² 使用Jsoup工具类,解析Wikipaia在线html dom元素。
2方案分析
2.1 ApacheNutch
2.1.1原理
Nutch 是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。包括全文搜索和Web爬虫。
1. 创建一个新的WebDb (admin db -create).
2. 将抓取起始URLs写入WebDB中 (inject).
3. 根据WebDB生成fetchlist并写入相应的segment(generate).
4. 根据fetchlist中的URL抓取网页 (fetch).
5. 根据抓取网页更新WebDb (updatedb).
6. 循环进行3-5步直至预先设定的抓取深度。
7. 根据WebDB得到的网页评分和links更新segments (updatesegs).
8. 对所抓取的网页进行索引(index).
9. 在索引中丢弃有重复内容的网页和重复的URLs (dedup).
10. 将segments中的索引进行合并生成用于检索的最终index(merge).
2.1.2不足
Nutch可以广度的抓取html页面,但是不能精确的分析html页面元素,进行数据分析。
2.2 JWPL
2.2.1原理
JWPL(Java Wikipedia Library)是一个开源的访问wikipeida数据的java api包。它提供的DataMachine 工具类可快速解析wiki格式文件,生成mysql的数据txt文件,可通过mysqlimport 导入到本地数据库中
2.2.2不足
无法快速有效的从词条正文(wiki格式的数据)中提取有用的信息,需要解析比对wiki中的数据模板,来查找对应的属性
2.3 Jsoup
2.3.1原理
Jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
2.3.2不足
只能解析制定url的html页面信息,无法像Nutch 一样自动的进行页面抓取。
3方案实施
3.1 结论
通过以上的方案分析,任何单独的一种技术都无法实现 精确抓取维基百科数据的功能。但是可以利用这些技术的优点,进行组合查询。
l 利用JWPL技术将下载的wikipedia数据进行解析,存入本地的mysql数据库中。然后根据表之间的关系,遍历分类信息,最后根据分类信息查询对应的词条。
² Category 分类信息表
² Category_outlinks 分类信息和父节点关系表
² Category_pages 分类信息对应词条表
² Page 词条信息表
l 词条信息 = https://zh.wikipedia.org/wiki/ + 词条名称
l 根据Jsoup技术解析 url 获取html信息,找出对应的属性、概述、文本
3.2 步骤
3.2.1Jwpl解析wiki数据
l 指导性的文章
http://www.cs.bgu.ac.il/~elhadad/nlp12/jwpl/wikification.html
http://www.cnblogs.com/heshizhu/archive/2012/06/26/2564267.html
3.2.1.1下载维基百科 历史数据
中文维基 历史下载地址http://dumps.wikimedia.org/zhwiki/
需下载这三个 压缩包
http://download.wikipedia.com/zhwiki/20150703/zhwiki-20150703-pages-articles.xml.bz2
http://download.wikipedia.com/zhwiki/20150703/zhwiki-20150703-categorylinks.sql.gz
http://download.wikipedia.com/zhwiki/20150703/zhwiki-20150703-pagelinks.sql.gz
3.2.1.2下载Wikipedia离线阅读器WikiTaxi
http://jingyan.baidu.com/article/90895e0fb9fb5164ec6b0b1e.html
3.2.1.3下载JWPL jar
下载 DataMachine地址:
https://repo1.maven.org/maven2/de/tudarmstadt/ukp/wikipedia/de.tudarmstadt.ukp.wikipedia.datamachine/0.9.1/de.tudarmstadt.ukp.wikipedia.datamachine-0.9.1-jar-with-dependencies.jar
下载 WikipediaAPI 地址:
3.2.1.4通过JWPL 中的DataMachine 工具 解析下载的历史数据
java -jar JWPLDataMachine.jar [LANGUAGE][MAIN_CATEGORY_NAME][DISAMBIGUATION_CATEGORY_NAME][SOURCE_DIRECTORY]
LANGUAGE——JWPL_Languages语言字符串匹配。
MAIN_CATEGORY_NAME——主要的名称(上)类别的Wikipedia类别层次结构
DISAMBIGUATION_CATEGORY_NAME -类别的名称包含消歧的类别
SOURCE_DIRECTORY——包含源文件的目录的路径
l 本机命令:
D:\Wikipedia>java -Dfile.encoding=utf8 -Xmx4g-cp jar-with-dependencies.jar de.tudarmstadt.ukp.wikipedia.datamachine.domain.JWPLDataMachine chinese 頁面分類消歧义./zhwiki
3.2.1.5将解析完成的 txt文件导入到mysql数据库中
3.2.1.5.1创建数据库
CREATE DATABASE zhwiki DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
3.2.1.5.2执行建表sql
jwpl_tables.sql http://www.cs.bgu.ac.il/~elhadad/nlp12/jwpl/jwpl_tables.sql
--MySQLdump10.11----Host: localhost Database: jwpl_tables----------------------------------------------------------Server version 5.0.37-community-nt/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;/*!40101 SET NAMES utf8 */;/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;/*!40103 SET TIME_ZONE='+00:00' */;/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;----Table structure for table `Category`--DROP TABLE IF EXISTS `Category`;CREATE TABLE `Category`(`id` bigint(20) NOT NULL auto_increment,`pageId`int(11)default NULL,`name` varchar(255)default NULL,PRIMARY KEY (`id`),UNIQUE KEY `pageId`(`pageId`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;----Dumping data for table `Category`--LOCK TABLES `Category` WRITE;/*!40000 ALTER TABLE `Category` DISABLE KEYS */;/*!40000 ALTER TABLE `Category` ENABLE KEYS */;UNLOCK TABLES;----Table structure for table `category_inlinks`--DROP TABLE IF EXISTS `category_inlinks`;CREATE TABLE `category_inlinks`(`id` bigint(20) NOT NULL,`inLinks`int(11)default NULL,KEY `FK3F433773E46A97CC`(`id`),KEY `FK3F433773BB482769`(`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;----Dumping data for table `category_inlinks`--LOCK TABLES `category_inlinks` WRITE;/*!40000 ALTER TABLE `category_inlinks` DISABLE KEYS */;/*!40000 ALTER TABLE `category_inlinks` ENABLE KEYS */;UNLOCK TABLES;----Table structure for table `category_outlinks`--DROP TABLE IF EXISTS `category_outlinks`;CREATE TABLE `category_outlinks`(`id` bigint(20) NOT NULL,`outLinks`int(11)default NULL,KEY `FK9885334CE46A97CC`(`id`),KEY `FK9885334CBB482769`(`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;----Dumping data for table `category_outlinks`--LOCK TABLES `category_outlinks` WRITE;/*!40000 ALTER TABLE `category_outlinks` DISABLE KEYS */;/*!40000 ALTER TABLE `category_outlinks` ENABLE KEYS */;UNLOCK TABLES;----Table structure for table `category_pages`--DROP TABLE IF EXISTS `category_pages`;CREATE TABLE `category_pages`(`id` bigint(20) NOT NULL,`pages`int(11)default NULL,KEY `FK71E8D943E46A97CC`(`id`),KEY `FK71E8D943BB482769`(`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;----Dumping data for table `category_pages`--LOCK TABLES `category_pages` WRITE;/*!40000 ALTER TABLE `category_pages` DISABLE KEYS */;/*!40000 ALTER TABLE `category_pages` ENABLE KEYS */;UNLOCK TABLES;----Table structure for table `MetaData`--DROP TABLE IF EXISTS `MetaData`;CREATE TABLE `MetaData`(`id` bigint(20) NOT NULL auto_increment,`language` varchar(255)default NULL,`disambiguationCategory` varchar(255)default NULL,`mainCategory` varchar(255)default NULL,`nrofPages` bigint(20)default NULL,`nrofRedirects` bigint(20)default NULL,`nrofDisambiguationPages` bigint(20)default NULL,`nrofCategories` bigint(20)default NULL,PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;----Dumping data for table `MetaData`--LOCK TABLES `MetaData` WRITE;/*!40000 ALTER TABLE `MetaData` DISABLE KEYS */;/*!40000 ALTER TABLE `MetaData` ENABLE KEYS */;UNLOCK TABLES;----Table structure for table `Page`--DROP TABLE IF EXISTS `Page`;CREATE TABLE `Page`(`id` bigint(20) NOT NULL auto_increment,`pageId`int(11)default NULL,`name` varchar(255)default NULL,`text` longtext,`isDisambiguation` bit(1)default NULL,PRIMARY KEY (`id`),UNIQUE KEY `pageId`(`pageId`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;----Dumping data for table `Page`--LOCK TABLES `Page` WRITE;/*!40000 ALTER TABLE `Page` DISABLE KEYS */;/*!40000 ALTER TABLE `Page` ENABLE KEYS */;UNLOCK TABLES;----Table structure for table `page_categories`--DROP TABLE IF EXISTS `page_categories`;CREATE TABLE `page_categories`(`id` bigint(20) NOT NULL,`pages`int(11)default NULL,KEY `FK72FB59CC1E350EDD`(`id`),KEY `FK72FB59CC75DCF4FA`(`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;----Dumping data for table `page_categories`--LOCK TABLES `page_categories` WRITE;/*!40000 ALTER TABLE `page_categories` DISABLE KEYS */;/*!40000 ALTER TABLE `page_categories` ENABLE KEYS */;UNLOCK TABLES;----Table structure for table `page_inlinks`--DROP TABLE IF EXISTS `page_inlinks`;CREATE TABLE `page_inlinks`(`id` bigint(20) NOT NULL,`inLinks`int(11)default NULL,KEY `FK91C2BC041E350EDD`(`id`),KEY `FK91C2BC0475DCF4FA`(`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;----Dumping data for table `page_inlinks`--LOCK TABLES `page_inlinks` WRITE;/*!40000 ALTER TABLE `page_inlinks` DISABLE KEYS */;/*!40000 ALTER TABLE `page_inlinks` ENABLE KEYS */;UNLOCK TABLES;----Table structure for table `page_outlinks`--DROP TABLE IF EXISTS `page_outlinks`;CREATE TABLE `page_outlinks`(`id` bigint(20) NOT NULL,`outLinks`int(11)default NULL,KEY `FK95F640DB1E350EDD`(`id`),KEY `FK95F640DB75DCF4FA`(`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;----Dumping data for table `page_outlinks`--LOCK TABLES `page_outlinks` WRITE;/*!40000 ALTER TABLE `page_outlinks` DISABLE KEYS */;/*!40000 ALTER TABLE `page_outlinks` ENABLE KEYS */;UNLOCK TABLES;----Table structure for table `page_redirects`--DROP TABLE IF EXISTS `page_redirects`;CREATE TABLE `page_redirects`(`id` bigint(20) NOT NULL,`redirects` varchar(255)default NULL,KEY `FK1484BA671E350EDD`(`id`),KEY `FK1484BA6775DCF4FA`(`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;----Dumping data for table `page_redirects`--LOCK TABLES `page_redirects` WRITE;/*!40000 ALTER TABLE `page_redirects` DISABLE KEYS */;/*!40000 ALTER TABLE `page_redirects` ENABLE KEYS */;UNLOCK TABLES;----Table structure for table `PageMapLine`--DROP TABLE IF EXISTS `PageMapLine`;CREATE TABLE `PageMapLine`(`id` bigint(20) NOT NULL auto_increment,`name` varchar(255)default NULL,`pageID`int(11)default NULL,`stem` varchar(255)default NULL,`lemma` varchar(255)default NULL,PRIMARY KEY (`id`),KEY `name`(`name`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;----Dumping data for table `PageMapLine`--LOCK TABLES `PageMapLine` WRITE;/*!40000 ALTER TABLE `PageMapLine` DISABLE KEYS */;/*!40000 ALTER TABLE `PageMapLine` ENABLE KEYS */;UNLOCK TABLES;/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;--Dump completed on 2008-02-1112:33:30
3.2.1.5.3导入数据库
在output目录下执行批处理文件 dbimport.bat:
@echo offset db=zhwikiset usr=rootset pwd=rootmysqlimport -u%usr%-p%pwd%--local--default-character-set=utf8 %db%Category.txtmysqlimport -u%usr%-p%pwd%--local--default-character-set=utf8 %db% category_inlinks.txtmysqlimport -u%usr%-p%pwd%--local--default-character-set=utf8 %db% category_outlinks.txtmysqlimport -u%usr%-p%pwd%--local--default-character-set=utf8 %db% category_pages.txtmysqlimport -u%usr%-p%pwd%--local--default-character-set=utf8 %db%MetaData.txtmysqlimport -u%usr%-p%pwd%--local--default-character-set=utf8 %db%Page.txtmysqlimport -u%usr%-p%pwd%--local--default-character-set=utf8 %db%PageMapLine.txtmysqlimport -u%usr%-p%pwd%--local--default-character-set=utf8 %db% page_categories.txtmysqlimport -u%usr%-p%pwd%--local--default-character-set=utf8 %db% page_inlinks.txtmysqlimport -u%usr%-p%pwd%--local--default-character-set=utf8 %db% page_outlinks.txtmysqlimport -u%usr%-p%pwd%--local--default-character-set=utf8 %db% page_redirects.txt
3.2.2Jsoup解析hml
/*** 利用Jsoup技术解析html*/privatevoidJsoupHtml(String categoryId,String entryId,String name){Date date =newDate();//中文 简体转繁体 工具类ZHConverter converter =ZHConverter.getInstance(ZHConverter.SIMPLIFIED);String url ="https://zh.wikipedia.org/wiki/"+name;name = converter.convert(name);Long sTime =System.currentTimeMillis();logger.info(name+" --------------------------------------------解析开始:---------------------------------url--"+url);//判断数据库中是否存在该词条String queryEntryByNameSql ="select t.id from bk_entry t where t.name = '"+name+"'";List<Map<String,Object>> list =newArrayList<Map<String,Object>>();try{list = jtLocal.queryForList(queryEntryByNameSql);}catch(Exception e){logger.info("判断数据库中是否存在该词条 sql 出错了"+queryEntryByNameSql);}if(list.size()==0){Document doc =null;try{// 5000 = 5秒doc =Jsoup.connect(url).timeout(50000).get();if(doc.select("sup").size()>0){doc.select("sup").remove();//html页面的标注信息}if(doc.select(".mw-editsection").size()>0){doc.select(".mw-editsection").remove();//删除编辑}//获取html正文信息Elements bodys = doc.select("#mw-content-text > *");StringBuffer text =newStringBuffer();//解析 html 获取 概述 和 正文for(Element el : bodys){String elText = el.text().trim();if(!StringUtil.isBlank(elText)){elText = converter.convert(elText);if(el.attr("id").equals("toc")){//目录text.append("@@!@@");//定义特殊符号,分割 概述和正文}if(el.tagName().equals("h2")){//分类标题text.append("<h2>"+elText+"</h2>");}if(el.tagName().equals("p")){//判断当前文本标签text.append("<p>"+elText+"</p>");}}}String describe ="";//概述String content ="";//正文if(!StringUtil.isBlank(text.toString())){if(text.indexOf("@@!@@")>-1){//判断当前text是否存在 正文和概述的分隔符describe = text.substring(0, text.indexOf("@@!@@"));content = text.substring(text.indexOf("@@!@@")+5,text.length());logger.info("概述:--------------");logger.info(describe);logger.info("正文:--------------");logger.info(content);}else{//如果没有 @@!@@ 分隔符的话,默认用第一段作为概述if(text.indexOf("<h2>")>-1){//默认用第一个分类标题 做分割describe = text.substring(0, text.indexOf("<h2>"));content = text.substring(text.indexOf("<h2>")+4,text.length());}else{//用第一个p标签做分割describe = text.substring(0, text.indexOf("</p><p>")+4);content = text.substring(text.indexOf("</p><p>")+7,text.length());}logger.info("概述:--------------");logger.info(describe);logger.info("正文:--------------");logger.info(content);}}//添加词条信息到数据库Entry entry =newEntry();entry.setName(name);entry.setCategoryId(categoryId);entry.setAuthor("admin");entry.setDescribe(describe);entry.setContent(content);entry.setWikiid(entryId);try{entryService.insertSelective(entry);logger.info(JSON.toJSONString(entry));}catch(Exception e){logger.info("词条插入出错:-------"+JSON.toJSONString(entry));}logger.info("属性:--------------");//获取页面属性信息 infoboxElements infoboxs = doc.select(".infobox");if(infoboxs.size()>0){//查找属性Element info = infoboxs.get(0);Elements trs = info.select("tr");for(Element tr : trs){String key ="";String val ="";if(tr.select("th").size()>0&& tr.select("td").size()>0){// key=th 、val=tdkey = tr.select("th").text();val = tr.select("td").text();}elseif(tr.select("th").size()==0&& tr.select("td").size()>=2){// key=td 、val=tdkey = tr.select("td").get(0).text();val = tr.select("td").get(1).text();}key = converter.convert(key);val = converter.convert(val);if(!StringUtil.isBlank(key)&&!StringUtil.isBlank(val)){logger.info(key+" : "+val );Meta m =newMeta();//判断属性表里是否已存在该属性String metaSql =" select t.id from bk_meta t where t.category_id = '-' and t.name = '"+key+"' ";//is not null// logger.info("判断该 '"+key+"' 属性是否已存在------"+metaSql);List<Map<String,Object>> metaList = jtLocal.queryForList(metaSql);if(metaList.size()==0){m.setCategoryId("-");m.setName(key);try{metaService.insertSelective(m);}catch(Exception e){logger.info("属性插入出错:-------"+JSON.toJSONString(m));}}else{m.setId(Long.parseLong(metaList.get(0).get("id").toString()));}Metadata metadata =newMetadata();metadata.setEntryId(entry.getId());metadata.setMetaId(m.getId());metadata.setValue(val);metadata.setUpdateTime(date);try{metadataService.insertSelective(metadata);}catch(Exception e){logger.info("属性值 插入出错:-------"+JSON.toJSONString(metadata));e.printStackTrace();}}}}}catch(IOException e1){logger.error(url+" 连接超时!!!");}}Long eTime =System.currentTimeMillis();logger.info(name+" --------------------------------------------解析结束:---------------------------------耗时--"+(eTime-sTime)+"毫秒!");logger.info("");logger.info("");logger.info("");logger.info("");logger.info("");logger.info("");}

1042

被折叠的 条评论
为什么被折叠?



