05实时新闻采集
天亮爬虫篇--初级篇
五大门户:新浪新闻,网易,腾讯,搜狐,凤凰
中国青年网是国内用户群体最广泛,体量最大,权威度最高,集新闻编撰,发布,传播为一体的新闻数据中心。
http://news.youth.cn/gn/
采集要求:
数据字段要求
新闻标题,发布时间,数据插入数据库的时间
首次采集
因为新闻数据量巨大,机器和带宽有限,故只采集前5页即可,并存储到mysql数据库中
增量采集
当首次采集的5页完成后,定时周期性每隔1分钟增量采集一次,将新出现的新闻条目采集下去,并存储到mysql数据库即可
采集日志输出要求
日志当中,要能一直输出当前共采集多少条新闻,当天共采集多少条新闻
主要思路:
通过javase+maven+httpclient数据集组件+正则+mysql综合实现
数据采集器的开发流程:主要包括提交任务的用户接口层,任务调度层,网络爬取层,数据解析层,数据持久化层,共5个主要层,再循环至任务调度层的过程
模块间解耦设计,模块间通过类或方法来衔接串联,最终形成完整的系统。
//任务调度层:解决先后采集等策略问题
//递归采集分深度优先和广度优先
主要考点:
项目分析与开发过程熟悉
javase程序设计基础
面向对象程序设计
maven项目构建和开发
httpclient api学习和使用
正则
mysql操作
爬虫相关博文链接:
https://blog.csdn.net/erliang20088/article/details/45790263?locationNum=7&fps=1
https://blog.csdn.net/erliang20088/article/details/45790201
https://blog.csdn.net/erliang20088/article/details/45790103
https://blog.csdn.net/erliang20088/article/details/45790253
简单页面:是指没有异步请求的页面。
nlp:
句法分析
itp 哈工大
数据挖掘:
基于nlp基础
HttpURLConnection底层是socket
HttpClient底层是httpURLConnection
SimpleYouthNewsSpider
<!-- 首先配置仓库的服务器位置,首选阿里云,也可以配置镜像方式 -->
<repositories>
<repository>
<id>nexus-aliyun</id>
<name>Nexus iliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/xxxx</url>
</repository>
</repositories>
<dependencies>
<!-- 引入hadoop-cli-2.7.4依赖 -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.4</version>
<scope>provided</scope>
</dependency>
hive
...
</dependencies>
<build>打包的</build>
package一般是5层
com.tl.spider.ui
UIManager();
com.tl.spider.schedule
com.tl.spider.download
com.tl.spider.parser
com.tl.spider.utils
resources
seeds.txt
/*
负责爬虫系统对外开放接口的设计
*/
public class UIManager{
//拿到系统运行的种子
public static String getSeedUrl(){
return "http://news.youth.cn/gn/";
}
//拿到系统运行的种子通过文件加载的方式
public static List<String> getSeedUrlFromFile(){
String seedFilePath = "seeds.txt";
List<String> seedUrlList=FileOperatorUtil.getList();
}
public static String readFromFile(String filePath,String charset){
File fileObj = new File(filePath);
FileInputStream fis = new FileInputStream(fileObj);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
StringBuilder stringBuilder = new StringBuilder();
String temp = null;
int lineCounter=0;// StringBuilder会多一行
while(temp=br.readLine()!=null){
if(lineCounter > 0){
stringBuilder.append("\n");
}
lineCounter ++;
stringBuilder.append(temp);
}
br.close();
return stringBuilder.toString();
}
public static List<String> readFromFile(String filePath,String charset) throws Exception{
File fileObj = new File(filePath);
FileInputStream fis = new FileInputStream(fileObj);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
StringBuilder stringBuilder = new StringBuilder();
String temp = null;
List<String> lineList = new ArrayList<String>();
while(temp=br.readLine()!=null){
temp = temp.trim();
if(temp.length() > 0){
lineList.add(temp);
}
}
br.close();
return stringBuilder.toString();
}
psvm(){
}
}
//seeds.txt
http://news.youth.cn/gn/
URL. 里面有个.openStream()。 返回InputStream
.....
拿到html后
//负责接收外部传过来的url任务,通过一定的分发策略,将相应的url任务分发到采集任务中
public class ScheduleManager{
public static List<UrlTaskPojo> todoTaskList = new LinkedList<>();
//
public static List<UrlTaskPojo> xxx(xxx){
//将种子url加入到待采集队列
return null;
}
}
去重:
添加种子的时候要去重
remove的时候也要去重
public static Set<String> todoTaskUrl = new HashSet<String>();
if(todoTaskUrl.contains(seedUrl)){
return false;
}
todoTaskUrlSet.remove(url);
mysql插入数据
maven依赖:
mysql-connector-java 5.1.40
批量插入数据:
PreparedStatement ps = conn.prepareStatement(sql);
ps.addBatch();
for(xxx:xxx){
ps.set...
ps.addBatch();
}
ps.executeBatch();
//25 前5页采集 周期采集
一次采集步骤:
1.拿种子
2.交给任务调度层,用于后续的下载分发
3.下载拿到的url,没有则返回空
4.解析下载下来的htmlsource
5.对解析出来的对象进行持久化
3.
String htmlSource = DownLoadManager.download();
while(htmlSource != null){
4.
5.
3.
}
while(true){
12345.
Thread.sleep(10*1000);
}
将定时循环次数放在配置文件里面
增量采集:
//用于保存已采集过的url的任务集合donwTaskSet
public static Set<String> doneTaskSet = new HashSet<String>();
在持久化的时候
//filed:01 (不建议)
for(xxx:xxx){
//加入到已采集任务集合当中
}
//filed:02 (这种方式更符合业务逻辑)
//在5.步的时候
DataPersistenceManager.persist(resultEntityList);
//将已入库完成的entity数据,加入到已采集数据的set当中,用于判断是否已采集过数据,最终实现增量采集
ScheduleManager.addUrlToDoneTaskSet(resultEntityList);
htmlSource = DownLoadManager.download();
public static void addUrlToDoneTaskSet(List<ParserResultEntity> resultEntityList){
for(ParserResultEntity entity:resultEntityList){
addUrlToDoneTaskSet(entity.getSourceUrl());
}
}
//在4.步到5.步时判断是否需要添加重复的数据持久化
3种方法判断 在4上,在5上,在4~5之间判断(优)
4.
//加入增量采集的判断
boolean isFindRepeatData = false;
List<ParserResultEntity> resultEntityListFinal = new ArrayList<ParserResultEntity>();
for(ParserResultEntity entity:resultEntityList){
if(ScheduleManager.isHaveDone(entity.getSourceUrl)){
isFindRepeatData = true;
break;
}
ParserResultEntityFinal.add(entity);
}
//scheduleManager.java
public static boolean isHaveDone(String url){
return doneTaskSet.contains(url);
}
5.
DataPersistenceManager.persist(resultEntityListFinal);
ScheduleManager.addUrlToDoneTaskSet(resultEntityList);
//循环下载,直到不存在待采集任务
if(isFindRepeatData){
ScheduleManager.clearToDoTaskList();
sout("发现重复");
break;
}
htmlSource = DownLoadManager.download();
//ScheduleManager.java
public static void clearToDoTaskList(){
todoTaskUrlSet.clear();
todoTaskUrlList.clear();
}
log4j
reg:介绍
https://www.cnblogs.com/franson-2016/p/5640427.html
log4j maven
修改log4j.properties. 一般maven文件都放在resources下
要自己新建 UTF-8
log4j.rootLogger = DEBUG,stdout,file
//这里不写info,表示DEBUG级以上的信息全部显示出来
.File = 路径
.MaxFileSize = 5MB 每隔多少M写一个新的文件
TestLog4j{
public static Logger logger = Logger.getLogger(TestLog4j.class);
psvm(){
logger.info("123");
}
}
将其放入爬虫:
manager
StatisticManager();
public class StaticManager{
public static Logger logger=Logger.getLogger(StatisticManager.class);
public static void logStatistic(){
logger.info(SchedulaManager.xxxx);
}
}