Elasticsearch系列(十)----使用webmagic爬取数据导入到ES

2024-06-17 05:38

本文主要是介绍Elasticsearch系列(十)----使用webmagic爬取数据导入到ES,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

webmagic主要有两个文件




一个是对爬取页面进行处理,一个是对页面处理之后的数据进行保存:


CSDNPageProcessor

package com.fendo.webmagic;import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;import com.fendo.common.ClientFactory;
import com.fendo.common.CommonUtils;
import com.fendo.entity.CsdnBlog;import io.searchbox.client.JestClient;
import io.searchbox.client.JestResult;
import io.searchbox.indices.CreateIndex;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;/*** CSDN页面爬取* @author fendo**/
//@RunWith(SpringJUnit4ClassRunner.class)
//@WebAppConfiguration
//@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class CSDNPageProcessor implements PageProcessor{@Autowiredprivate static JdbcPipeline jdbcPipeline;private static String username="u011781521";  // 设置csdn用户名  private static int size = 0;// 共抓取到的文章数量  private JestClient jestClient;// 抓取网站的相关配置,包括:编码、抓取间隔、重试次数等      private Site site = Site.me().setRetryTimes(3).setSleepTime(1000).setUserAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36");@Overridepublic Site getSite() {return site;}@Overridepublic void process(Page page) {// 列表页  if (!page.getUrl().regex("http://blog\\.csdn\\.net/" + username + "/article/details/\\d+").match()) {  // 添加所有文章页  page.addTargetRequests(page.getHtml().xpath("//div[@id='article_list']").links()// 限定文章列表获取区域  .regex("/" + username + "/article/details/\\d+")  .replace("/" + username + "/", "http://blog.csdn.net/" + username + "/")// 巧用替换给把相对url转换成绝对url  .all());  // 添加其他列表页  page.addTargetRequests(page.getHtml().xpath("//div[@id='papelist']").links()// 限定其他列表页获取区域  .regex("/" + username + "/article/list/\\d+")  .replace("/" + username + "/", "http://blog.csdn.net/" + username + "/")// 巧用替换给把相对url转换成绝对url  .all());  // 文章页  } else {  size++;// 文章数量加1  page.putField("key", Integer.parseInt(page.getUrl().regex("http://blog\\.csdn\\.net/" + username + "/article/details/(\\d+)").get()));page.putField("title", CommonUtils.replaceHTML(page.getHtml().xpath("//div[@class='article_title']//span[@class='link_title']/a/text()").get()));page.putField("content",CommonUtils.replaceHTML(page.getHtml().xpath("//div[@class='article_content']/allText()").get()));page.putField("dates",page.getHtml().xpath("//div[@class='article_r']/span[@class='link_postdate']/text()").get());System.out.println("+++++++++++++++date:"+page.getHtml().xpath("//div[@class='article_r']/span[@class='link_postdate']/text()").get());page.putField("tags",CommonUtils.replaceHTML(listToString(page.getHtml().xpath("//div[@class='article_l']/span[@class='link_categories']/a/allText()").all())));page.putField("category",CommonUtils.replaceHTML(listToString(page.getHtml().xpath("//div[@class='category_r']/label/span/text()").all())));page.putField("view", Integer.parseInt(page.getHtml().xpath("//div[@class='article_r']/span[@class='link_view']").regex("(\\d+)人阅读").get()));page.putField("comments",Integer.parseInt(page.getHtml().xpath("//div[@class='article_r']/span[@class='link_comments']").regex("\\((\\d+)\\)").get()));page.putField("copyright",page.getHtml().regex("bog_copyright").match() ? 1 : 0);page.putField("url", page.getUrl().get());//创建索引ObjectMapper mapper = new ObjectMapper();//创建clientTransportClient client;CsdnBlog csdnBlog = new CsdnBlog();csdnBlog.setId(size);csdnBlog.setTags((String)page.getResultItems().get("tags"));csdnBlog.setKeyes((Integer)page.getResultItems().get("key"));csdnBlog.setTitles((String)page.getResultItems().get("title"));csdnBlog.setDates((String)page.getResultItems().get("dates"));csdnBlog.setCategory((String)page.getResultItems().get("category"));csdnBlog.setViews((Integer)page.getResultItems().get("view"));csdnBlog.setComments((Integer)page.getResultItems().get("comments"));csdnBlog.setCopyright((Integer)page.getResultItems().get("copyright"));csdnBlog.setContent((String)page.getResultItems().get("content"));try {//设置集群名称Settings settings = Settings.builder().put("cluster.name", "my-application").build();// 集群名client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));IndexResponse response = client.prepareIndex("csdnblog", "article").setSource(mapper.writeValueAsString(csdnBlog)).execute().actionGet();System.out.println(response.toString());} catch (Exception e) {e.printStackTrace();}// 把对象输出控制台  //System.out.println("获取的数据:"+page.toString()); }  }// 把list转换为string,用,分割  public static String listToString(List<String> stringList) {  if (stringList == null) {  return null;  }  StringBuilder result = new StringBuilder();  boolean flag = false;  for (String string : stringList) {  if (flag) {  result.append(",");  } else {  flag = true;  }  result.append(string);  }  return result.toString();  }  public static void main(String[] args) {  long startTime, endTime;  System.out.println("【爬虫开始】...");  startTime = System.currentTimeMillis();  //ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");ApplicationContext applicationContext = new FileSystemXmlApplicationContext(  "classpath:applicationContext.xml");  JdbcPipeline jdbcPipeline=(JdbcPipeline)applicationContext.getBean("jdbcPipeline");System.out.println(jdbcPipeline.toString());Spider.create(new CSDNPageProcessor()).addUrl("http://blog.csdn.net/u011781521/article/list/1")//.addUrl("http://blog.csdn.net/u011781521/article/list/1").addPipeline(jdbcPipeline).thread(5).run();// 从用户博客首页开始抓,开启5个线程,启动爬虫  // Spider.create(new CsdnBlogPageProcessor()).addUrl("http://blog.csdn.net/" + username).thread(5).run();  endTime = System.currentTimeMillis();  System.out.println("【爬虫结束】共抓取" + size + "篇文章,耗时约" + ((endTime - startTime) / 1000) + "秒,已保存到数据库,请查收!");  }  
}


注意:


在上面的代码中,不但通过jdbcPipeline保存了数据,还通过TransportClient 往ES中保存了数据!!


JdbcPipeline

package com.fendo.webmagic;import java.util.Map;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;import com.fendo.entity.CsdnBlog;
import com.fendo.mapper.CsdnBlogMapper;import us.codecraft.webmagic.ResultItems;
import us.codecraft.webmagic.Task;
import us.codecraft.webmagic.pipeline.Pipeline;@Component("jdbcPipeline")
public class JdbcPipeline implements Pipeline{@AutowiredCsdnBlogMapper csdnBlogMapper;@Overridepublic void process(ResultItems resultItems, Task task) {Map<String,Object> items = resultItems.getAll();if(resultItems!=null&&resultItems.getAll().size()>0){CsdnBlog csdnBlog = new CsdnBlog();csdnBlog.setTags((String)items.get("tags"));csdnBlog.setKeyes((Integer)items.get("key"));csdnBlog.setTitles((String)items.get("title"));csdnBlog.setDates((String)items.get("dates"));csdnBlog.setCategory((String)items.get("category"));csdnBlog.setViews((Integer)items.get("view"));csdnBlog.setComments((Integer)items.get("comments"));csdnBlog.setCopyright((Integer)items.get("copyright"));csdnBlog.setContent((String)items.get("content"));System.out.println("-----------------------------------------------------------------------process:"+csdnBlog.toString());csdnBlogMapper.insert(csdnBlog);}}}


对应的数据库脚本:

CREATE TABLE `csdnblog` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`keyes` int(11) unsigned NOT NULL,`titles` varchar(255) NOT NULL,`content` varchar(10240) NOT NULL,`dates` varchar(255) DEFAULT NULL,`tags` varchar(255) DEFAULT NULL,`category` varchar(255) DEFAULT NULL,`views` int(11) unsigned DEFAULT NULL,`comments` int(11) unsigned DEFAULT NULL,`copyright` int(20) unsigned DEFAULT NULL,`url` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3301 DEFAULT CHARSET=utf8;

完整项目: http://download.csdn.net/download/u011781521/9966717

这篇关于Elasticsearch系列(十)----使用webmagic爬取数据导入到ES的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1068606

相关文章

postgresql使用UUID函数的方法

《postgresql使用UUID函数的方法》本文给大家介绍postgresql使用UUID函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录PostgreSQL有两种生成uuid的方法。可以先通过sql查看是否已安装扩展函数,和可以安装的扩展函数

如何使用Lombok进行spring 注入

《如何使用Lombok进行spring注入》本文介绍如何用Lombok简化Spring注入,推荐优先使用setter注入,通过注解自动生成getter/setter及构造器,减少冗余代码,提升开发效... Lombok为了开发环境简化代码,好处不用多说。spring 注入方式为2种,构造器注入和setter

MySQL中比较运算符的具体使用

《MySQL中比较运算符的具体使用》本文介绍了SQL中常用的符号类型和非符号类型运算符,符号类型运算符包括等于(=)、安全等于(=)、不等于(/!=)、大小比较(,=,,=)等,感兴趣的可以了解一下... 目录符号类型运算符1. 等于运算符=2. 安全等于运算符<=>3. 不等于运算符<>或!=4. 小于运

使用zip4j实现Java中的ZIP文件加密压缩的操作方法

《使用zip4j实现Java中的ZIP文件加密压缩的操作方法》本文介绍如何通过Maven集成zip4j1.3.2库创建带密码保护的ZIP文件,涵盖依赖配置、代码示例及加密原理,确保数据安全性,感兴趣的... 目录1. zip4j库介绍和版本1.1 zip4j库概述1.2 zip4j的版本演变1.3 zip4

Python 字典 (Dictionary)使用详解

《Python字典(Dictionary)使用详解》字典是python中最重要,最常用的数据结构之一,它提供了高效的键值对存储和查找能力,:本文主要介绍Python字典(Dictionary)... 目录字典1.基本特性2.创建字典3.访问元素4.修改字典5.删除元素6.字典遍历7.字典的高级特性默认字典

SpringBoot整合(ES)ElasticSearch7.8实践

《SpringBoot整合(ES)ElasticSearch7.8实践》本文详细介绍了SpringBoot整合ElasticSearch7.8的教程,涵盖依赖添加、客户端初始化、索引创建与获取、批量插... 目录SpringBoot整合ElasticSearch7.8添加依赖初始化创建SpringBoot项

使用Python构建一个高效的日志处理系统

《使用Python构建一个高效的日志处理系统》这篇文章主要为大家详细讲解了如何使用Python开发一个专业的日志分析工具,能够自动化处理、分析和可视化各类日志文件,大幅提升运维效率,需要的可以了解下... 目录环境准备工具功能概述完整代码实现代码深度解析1. 类设计与初始化2. 日志解析核心逻辑3. 文件处

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

MyBatis-Plus通用中等、大量数据分批查询和处理方法

《MyBatis-Plus通用中等、大量数据分批查询和处理方法》文章介绍MyBatis-Plus分页查询处理,通过函数式接口与Lambda表达式实现通用逻辑,方法抽象但功能强大,建议扩展分批处理及流式... 目录函数式接口获取分页数据接口数据处理接口通用逻辑工具类使用方法简单查询自定义查询方法总结函数式接口

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)