爬虫代码实现四:采用Hbase存储爬虫数据(2)
导入hbase的jar包,在maven仓库找:进入http://mavenrepository.com/,输入hbase client,选择apache hbase client,
点击进入,选择
点击进入:
将这段配置
<!-- https://mvnrepository.com/artifact/org.apache.hbase/hbase-client -->
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>0.98.11-hadoop2</version>
</dependency>
复制到pom.xml中
准备好以上工作后,代码操作如下:
1.新建一个Hbase工具类,这里直接用已经写好的现成工具。
2.Page实体类添加属性tvId,并且添加set/get方法。
之前我们通过观察,点击不同的电视剧,url分别为:
这里我们如何获取电视剧的id?采用正则表达式。因此,我们在配置文件中添加一个变量idRegex=http://list.youku.com/show/id_([\\w]+).html,为了获取电视剧的id
youku.properties如下:
allnumberRegex=(?<=\u603B\u64AD\u653E\u6570\uFF1A)[\\d,]+
commentnumberRegex=(?<=\u8BC4\u8BBA\uFF1A)[\\d,]+
supportnumberRegex=(?<=\u9876\uFF1A)[\\d,]+
parseAllNumber=/body/div/div/div/div/div/ul/li[11]
parseCommentNumber=//div[@class=\"p-base\"]/ul/li[12]
parseSupportNumber=//div[@class=\"p-base\"]/ul/li[13]
idRegex=http://list.youku.com/show/id_([\\w]+).html
我们知道,RegexUtil的工具类中封装的方法是public static String getPageInfoByRegex(String content,Pattern pattern,int groupNo),需要传入匹配的内容以及正则表达式以及groupNo,
而这里正则表达式是idRegex=http://list.youku.com/show/id_([\\w]+).html,它对应的匹配内容是page.getUrl,因此,我们在调用RegexUtil.getPageInfoByRegex方法前,还得去设置page.url。所以,
1.回到HttpClientDownLoadService:
package com.dajiangtai.djt_spider.service.impl;
import com.dajiangtai.djt_spider.entity.Page;
import com.dajiangtai.djt_spider.service.IDownLoadService;
import com.dajiangtai.djt_spider.util.PageDownLoadUtil;
public class HttpClientDownLoadService implements IDownLoadService {
public Page download(String url) {
Page page = new Page();
page.setContent(PageDownLoadUtil.getPageContent(url));
page.setUrl(url); //添上这句代码
return page;
}
}
2.YOUKUProcessService 中,添加代码,即通过正则表达式获取电视剧id。通过调用RegexUtil.getPageInfoByRegex方法,注意,groupNo为1,表示,对于匹配的内容,我们使用正则表达式,我们不需要所有的匹配到的字符串如http://list.youku.com/show/id_z9cd2277647d311e5b692.html,我们只需要([\\w]+)正则对应的z9cd2277647d311e5b692。由于这里未使用到XPath,仅仅是正则匹配,因此只需要使用到正则表达式工具。
package com.dajiangtai.djt_spider.service.impl;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode;
import org.htmlcleaner.XPatherException;
import com.dajiangtai.djt_spider.entity.Page;
import com.dajiangtai.djt_spider.service.IProcessService;
import com.dajiangtai.djt_spider.util.HtmlUtil;
import com.dajiangtai.djt_spider.util.LoadPropertyUtil;
import com.dajiangtai.djt_spider.util.RegexUtil;
public class YOUKUProcessService implements IProcessService {
//这里解析得到的是 : 总播放数:16,931,628,832,因此采用正则表达式获取数字
// private String allnumberRegex = "(?<=总播放数:)[\\d,]+";
// private String commentnumberRegex = "(?<=评论:)[\\d,]+";
// private String supportnumberRegex = "(?<=顶:)[\\d,]+";
//
// private String parseAllNumber = "/body/div/div/div/div/div/ul/li[11]";
// private String parseCommentNumber = "//div[@class=\"p-base\"]/ul/li[12]";
// private String parseSupportNumber = "//div[@class=\"p-base\"]/ul/li[13]";
public void process(Page page) {
String content = page.getContent();
HtmlCleaner htmlCleaner = new HtmlCleaner();
//利用htmlCleaner对网页进行解析,得到根节点
TagNode rootNode = htmlCleaner.clean(content);
try {
// /html/body/div[4]/div/div[1]/div[2]/div[2]/ul/li[11]
//对XPath做相应的调整,使其有效,如果不该写,则使用debug模式,会发现evaluateXPath为[]
//总播放数
// String allnumber = HtmlUtil.getFieldByRegex(rootNode, parseAllNumber, allnumberRegex);
String allnumber = HtmlUtil.getFieldByRegex(rootNode, LoadPropertyUtil.getYOUKY("parseAllNumber"), LoadPropertyUtil.getYOUKY("allnumberRegex"));
//System.out.println("总播放数数量为:"+allnumber);
page.setAllnumber(allnumber);
//总播放数
String commentnumber = HtmlUtil.getFieldByRegex(rootNode, LoadPropertyUtil.getYOUKY("parseCommentNumber"), LoadPropertyUtil.getYOUKY("commentnumberRegex"));
//System.out.println("总评论数量为:"+commentnumber);
page.setCommentnumber(commentnumber);
//总播放数
String supportnumber = HtmlUtil.getFieldByRegex(rootNode, LoadPropertyUtil.getYOUKY("parseSupportNumber"), LoadPropertyUtil.getYOUKY("supportnumberRegex"));
//System.out.println("总评论数量为:"+supportnumber);
page.setSupportnumber(supportnumber);
page.setDaynumber("0");
page.setAgainstnumber("0");
page.setCollectnumber("0");
//通过正则表达式获取电视剧id
//Pattern numberPattern = Pattern.compile(regex,Pattern.DOTALL);
Pattern numberPattern = Pattern.compile(LoadPropertyUtil.getYOUKY("idRegex"),Pattern.DOTALL);
page.setTvId("tvId_"+RegexUtil.getPageInfoByRegex(page.getUrl(), numberPattern, 1));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3.ConsoleStoreService中添加电视剧id打印信息。
package com.dajiangtai.djt_spider.service.impl;
import com.dajiangtai.djt_spider.entity.Page;
import com.dajiangtai.djt_spider.service.IStoreService;
public class ConsoleStoreService implements IStoreService {
public void store(Page page) {
System.out.println("电视剧id:"+page.getTvId());
System.out.println("总播放数:"+page.getAllnumber());
System.out.println("评论数:"+page.getCommentnumber());
System.out.println("赞:"+page.getSupportnumber());
System.out.println("踩:"+page.getAgainstnumber());
System.out.println("收藏:"+page.getCollectnumber());
System.out.println("每日播放增量:"+page.getDaynumber());
}
}
4.运行StartDSJCount的main方法进行测试。
package com.dajiangtai.djt_spider.start;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.dajiangtai.djt_spider.entity.Page;
import com.dajiangtai.djt_spider.service.IDownLoadService;
import com.dajiangtai.djt_spider.service.IProcessService;
import com.dajiangtai.djt_spider.service.IStoreService;
import com.dajiangtai.djt_spider.service.impl.ConsoleStoreService;
import com.dajiangtai.djt_spider.service.impl.HttpClientDownLoadService;
import com.dajiangtai.djt_spider.service.impl.YOUKUProcessService;
/**
* 电视剧爬虫入口类
* @author Administrator
*
*/
public class StartDSJCount {
//页面下载接口
private IDownLoadService downLoadService;
//页面解析接口
private IProcessService processService;
//数据存储接口
private IStoreService storeService;
public static void main(String[] args) {
StartDSJCount dsj = new StartDSJCount();
dsj.setDownLoadService(new HttpClientDownLoadService());
dsj.setProcessService(new YOUKUProcessService());
dsj.setStoreService(new ConsoleStoreService());
String url = "http://list.youku.com/show/id_z9cd2277647d311e5b692.html?spm=a2h0j.8191423.sMain.5~5~A!2.iCUyO9";
//下载页面
Page page = dsj.downloadPage(url);
dsj.processPage(page);
//存储页面信息
dsj.storePageInfo(page);
}
//下载页面方法
public Page downloadPage(String url){
return this.downLoadService.download(url);
}
//解析页面方法
public void processPage(Page page){
this.processService.process(page);
}
//存储页面信息方法
public void storePageInfo(Page page){
this.storeService.store(page);
}
public IDownLoadService getDownLoadService() {
return downLoadService;
}
public void setDownLoadService(IDownLoadService downLoadService) {
this.downLoadService = downLoadService;
}
public IProcessService getProcessService() {
return processService;
}
public void setProcessService(IProcessService processService) {
this.processService = processService;
}
public IStoreService getStoreService() {
return storeService;
}
public void setStoreService(IStoreService storeService) {
this.storeService = storeService;
}
}
5.控制台输出:
电视剧id:tvId_z9cd2277647d311e5b692
总播放数:17,130,904,276
评论数:1,259,621
赞:13,954,307
踩:0
收藏:0
每日播放增量:0
爬虫代码实现四:采用Hbase存储爬虫数据(2)的更多相关文章
- 爬虫代码实现四:采用Hbase存储爬虫数据(1)
3.Hbase表设计: 1.窄表:列少行多,表中的每一行尽可能保持唯一. 2.宽表:列多行少,通过时间戳版本来进行区分取值. 窄表:比如说,这个表,rowkey由userid+时间+bbsid假设bb ...
- Sybase:存储过程中采用临时表存储统计数据
Sybase:存储过程中采用临时表存储统计数据 作用 很有效的提升统计查询速度,对于数据量亿级.千万级多表之间关联查询,非常有效: 使用 --无需定义临时表,直接使用 --自动释放临时表 select ...
- python爬虫入门(四)利用多线程爬虫
多线程爬虫 先回顾前面学过的一些知识 1.一个cpu一次只能执行一个任务,多个cpu同时可以执行多个任务2.一个cpu一次只能执行一个进程,其它进程处于非运行状态3.进程里包含的执行单元叫线程,一个进 ...
- 分布式爬虫系统设计、实现与实战:爬取京东、苏宁易购全网手机商品数据+MySQL、HBase存储
http://blog.51cto.com/xpleaf/2093952 1 概述 在不用爬虫框架的情况,经过多方学习,尝试实现了一个分布式爬虫系统,并且可以将数据保存到不同地方,类似MySQL.HB ...
- 爬虫技术(四)-- 简单爬虫抓取示例(附c#代码)
这是我的第一个爬虫代码...算是一份测试版的代码.大牛大神别喷... 通过给定一个初始的地址startPiont然后对网页进行捕捉,然后通过正则表达式对网址进行匹配. List<string&g ...
- (转)Python新手写出漂亮的爬虫代码2——从json获取信息
https://blog.csdn.net/weixin_36604953/article/details/78592943 Python新手写出漂亮的爬虫代码2——从json获取信息好久没有写关于爬 ...
- 第三百五十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—利用开源的scrapy-redis编写分布式爬虫代码
第三百五十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—利用开源的scrapy-redis编写分布式爬虫代码 scrapy-redis是一个可以scrapy结合redis搭建分布式爬虫的开 ...
- 第三百二十四节,web爬虫,scrapy模块介绍与使用
第三百二十四节,web爬虫,scrapy模块介绍与使用 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了 ...
- 四十七 Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索的自动补全功能
elasticsearch(搜索引擎)提供了自动补全接口 官方说明:https://www.elastic.co/guide/en/elasticsearch/reference/current/se ...
随机推荐
- FastDFS的配置、部署与API使用解读(7)Nginx的FastDFS模块(转)
1.Nginx的FastDFS模块什么作用? 我们在使用FastDFS部署一个分布式文件系统的时候,通过FastDFS的客户端API来进行文件的上传.下载.删除等操作.同时通过 FastDFS的HTT ...
- python--软件规范和反射
软件开发规范 写一个作业的时候,要将写的代码分开 bin文件夹里面第一个是start文件 核心代码都在core文件夹里面 文件core最好也是固定名字 BaseDir=os.path.dirna ...
- windows下检验caffe是否配置正确
windows下检验caffe是否配置正确:(注:不考虑搭建caffe的编译环境,而是直接使用caffe官网提供的二进制文件) windows版本源码以及二进制库文件下载地址:https://gith ...
- java中 hashCode() 和 equals()
1. 值类型是存储在内存中的栈,而引用类型的变量在栈中仅仅是存储引用类型变量的地址来自堆,而其本身则存储在栈中. 2. ==操作比较的是两个变量的值是否相等, 3. 对于引用型变量表示的是两个变量在堆 ...
- LeetCode(155)题解--Min Stack
https://leetcode.com/problems/min-stack/ 题目: Design a stack that supports push, pop, top, and retrie ...
- Android 四大组件学习之BroadcastReceiver一
本节课学习四大组件最后一个, 广播接受者. 顾名思义广播接受者就是接受广播呗.比方在现实社会中,曾经每一个人家都有一台收音机,这可就能够去接受广播发出来的消息.大家都知道.程序世界也是參照的显示生活设 ...
- iframe调用父页面js函数 方法 元素
在一个页面中添加iframe,但是有时需要与父页面进行通信,传递参数. 网上总结有以下方法: 一.iframe标签中 src属性传参 <iframe src="test.jsp?i ...
- 九度OJ 1084:整数拆分 (递归)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2274 解决:914 题目描述: 一个整数总可以拆分为2的幂的和,例如: 7=1+2+4 7=1+2+2+2 7=1+1+1+4 7=1+1 ...
- Linux环境下安装MySQL(解压方式)
1.将安装包放在服务器上:mysql-5.6.37-linux-glibc2.12-x86_64.tar.gz 2.将安装包解压:tar -zxvf mysql-5.6.37-linux-glibc2 ...
- Git 忽略上传文件设置 .gitignore exclude
1.项目根目录下创建.gitignore vi .gitignore #输入需要忽略的文件,支持正则表达式, *.o *.exe*.pyc 可以用git status来检查是否生效 未添加文件前: M ...