• 前言
  • 分析网页
    • 页码分析
    • 文章链接分析
    • 文章内容分析
  • io流生成jsp页面
  • squarz设置定时抓取

前言

看视频看的累了 写写博文~
很久以前就想有个自己的博客。csdn很好,可是我不是专家啊,还是功底不够, 没有权限,也就不能实现自己的一些想法。所以就百度了一个静态模版。有了模版,问题来了。是个空壳子啊,没有任何内容,所以就想着爬取自己csdn上面的所有文章并生成相应的jsp页面保存到本地,而且为了实时保证自己的博文新鲜度所以就用spring-quartz定时器定时执行抓取页面的任务。博客地址(http://www.susulovefreedom.cn)

分析网页

分析完网页,我终于发现为啥我的博文总是那么轻易的被别人爬走了 , 百度搜索排名还在我的前面。原来那么简单

页码分析

http://blog.csdn.net/su20145104009?viewmode=contents
在这个页面我们可以看到最短的分页信息。
然后通过审查元素定位到这里。

仔细查看,最大页码为12.在id为papelist标签下的第一个span元素。所以最大页码就可以这样获得

HtmlPage page=wc.getPage("http://blog.csdn.net/su20145104009?viewmode=contents");DomElement pageList = page.getElementById("papelist");//最大页码int MaxPage=Integer.parseInt(pageList.getFirstChild().asText().substring(6, 8));

文章链接分析

在上一步,我们得到了分页的最大页码。
通过查看url可以发现http://blog.csdn.net/su20145104009/article/list/2 最后一位
即为你要请求的页码。
那么就可以通过get请求来获得某一页的数据。
page=wc.getPage(“http://blog.csdn.net/su20145104009/article/list/“+MaxPage);
而在进入某一页后。继续查看源码

可以发现所有的文章都在article_list标签内。
所以我们可以首先获得article_list标签。
DomElement article_list = page.getElementById(“article_list”);

在article_list 标签内我们要继续获得文章的信息。
首先获得所有的article_list 子标签(并不包括子标签的子标签)。即上述图片的

    DomNodeList<DomNode> childNodes = article_list .getChildNodes();

然后通过for循环对每一篇的文章细节进行分析:

for (DomNode htmlElement : childNodes)


文章的所有信息一览无余。
由于里面只有两个a标签。

  • 在第一个a标签里面有文章的地址,标题信息。
  • 在第二个a标签里面有文章的阅读次数信息。然后第二个a标签的父标签的父标签下的第一个标签内有文章的创建日期信息。
  • 在获得题目的同时,使用md5码对文章的标题进行加密作为数据库中的主键

所以通过标签名字获取两个a标签:

    DomNodeList<HtmlElement> links = ((DomElement) htmlElement).getElementsByTagName("a");
String address=links.get(0).getAttribute("href");String title=links.get(0).asText();String readCounts=links.get(1).getParentNode().asText();String time=links.get(1).getParentNode().getParentNode().getFirstChild().asText();

到了这一步仅仅获得了所有文章的题目信息。
那么应该如何获得文章的具体内容呢?

文章内容分析

定位到某一篇文章。通过审查元素,我们可以找到所有的文章内容都在article_details标签里。

剩下的就是把article_details标签的所有内容存到自己的网页了。
在这里遇到了一问题。
起初我使用的是htmlunit工具直接通过getElementById的方法获取article_details的源码。可以生成后的网页分析后发现。所有的文章是正常显示了,可是代码出现严重的换行现象。通过对比源码后发现,htmlunit的axXml方法会自动对所有的标签进行格式化操作。google许久也没有找到适当的解决办法。灵光一闪,想到了URLConnection。
URLConnection的get请求获得的源码和浏览器源码一致。
于是定义了一个方法。对获得的源码进行字符串截取即可。正则表达式不是我不用,是爆栈啦~字符串太长了。。。。

/*** * @Title: getArticle* @Description: (通过URLConnection的get请求获得文章的源码信息)* @param  link 文章的链接* @return String    文章的源码*/public static String getArticle(String link){URL url=null;URLConnection conn=null;InputStream is = null;  //字符流  InputStreamReader isr = null;  //缓冲流  BufferedReader br = null;  try {url=new URL(link);conn= url.openConnection();conn.setRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");  conn.connect();//网页编码  String context = null;  //获得网页的字节输入流  is = conn.getInputStream();  //将字节输入流转换为字符输入流 并设置转码格式为utf-8  isr = new InputStreamReader(is, "utf-8");  //将字符流转换为缓冲流  br = new BufferedReader(isr);  //一行一行读取网页内容  context = br.readLine();  String txt="";while ((txt=br.readLine())!=null) {  context +=txt+"\n";  }  int st=context.indexOf("<div id=\"article_content\"");int ed=context.indexOf("<!-- Baidu Button BEGIN -->");return context.substring(st, ed);} catch (Exception e) {if(is!=null){try {is.close();} catch (IOException e1) {throw new RuntimeException(e1);}}if(isr!=null){try {isr.close();} catch (IOException e1) {throw new RuntimeException(e1);}}if(br!=null){try {br.close();} catch (IOException e1) {throw new RuntimeException(e1);}}throw new RuntimeException(e);} 

到了这里基本就快完成了~
剩下的就是使用io流写入网页了

io流生成jsp页面

我们的jsp页面肯定不能只有个文章的信息。当然也需要一些其它的元素。所以这些其它元素就需要我们自己准备了,保存到web项目里,然后使用io流读取即可。由于至少需要读取两个部分。所以我新建了一个方法

/*** * @Title: getHeadHtml* @Description: (通过文件的路径读取相应的文件信息并返回)* @param  path  文件路径* @return String   文件内的信息* @throws*/public static String getHeadHtml(String path) {String res="";BufferedReader br=null;String data=null;try {br=new BufferedReader(new InputStreamReader(new FileInputStream(path),"utf-8"));while((data=br.readLine())!=null){res+=data+"\n";}} catch (IOException e) {throw new RuntimeException(e);}finally{if(br!=null){try {br.close();} catch (IOException e) {e.printStackTrace();}}}return res;}

然后就是写入jsp信息了。如果当前数据库中没有这篇文章,那么就生成这个jsp页面。jsp的名称我使用的是文章题目md5码的后8位

if(!articleService.findArticleById(id)){//将源码写入到文件OutputStreamWriter bw=new OutputStreamWriter(new FileOutputStream(filePath+"articles/"+htmlname+".jsp"),"utf-8");//jsp的头部信息bw.write(MyStringUtil.getHeadHtml(filePath+"headHtml.txt"));//head标签中的title标签bw.write("<title>"+title+"</title>");//head标签中的标题信息bw.write("<meta name=\"description\" content=\"");bw.write(content+"\" />");bw.write("<base href=\"<%=basePath%>articleShow_"+htmlname+".html\"/>");//文章内容前的信息 一些js文件css文件啦bw.write(MyStringUtil.getHeadHtml(filePath+"titlePreHtml.txt"));bw.write(title+"</a></h3>");//通过文章的链接 调用getArticle方法获得文章的源码 并写入jsp页面bw.write(MyStringUtil.getArticle(article.getLink()));//文章底部的信息bw.write(MyStringUtil.getHeadHtml(filePath+"endHtml.txt"));bw.flush();bw.close();System.out.println(title+"制作网页完成");}

到了这里就大功告成了。

squarz设置定时抓取

配置如下:每12个小时执行一次抓取任务
如果对squarz定时器不懂,请转http://blog.csdn.net/su20145104009/article/details/72842526

<!-- 任务bean 由于我要写入数据库 所有注入了articleService --><bean id="hourWork" class="com.scx.hourwork.HourWork"><property name="articleService" ref="articleService"></property></bean><!-- 使用MethodInvokingJobDetailFactoryBean,任务类可以不实现Job接口,targetObject:调用类targetMethod:调用方法-->    <bean id="methodInvokingBean"  class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"><property name="targetObject" ref="hourWork"></property><property name="targetMethod" value="execute"></property></bean><!-- 任务触发器 --><bean  id="myTriggers" class="org.springframework.scheduling.quartz.CronTriggerBean"><property name="jobDetail" ref="methodInvokingBean"></property><!-- 每隔12个小时更新一次 --><property name="cronExpression" value="00 00 0/12 * * ?"></property></bean><!-- 任务调度工厂 --><bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"><!-- 可以使用list配置多个,第一种方式已经演示 --><property name="triggers" ref="myTriggers"></property></bean>

执行后可以在文件夹中查看

当点击自己文章的链接时,去文章id的后8位转向这个jsp页面。

写了一个多小时 也该回宿舍了~~希望暑期能找到个实习工作 唉

htmlunit+quartz定时抓取博文并生成jsp页面相关推荐

  1. python 定时自动爬取_python实现scrapy爬虫每天定时抓取数据的示例代码

    1. 前言. 1.1. 需求背景. 每天抓取的是同一份商品的数据,用来做趋势分析. 要求每天都需要抓一份,也仅限抓取一份数据. 但是整个爬取数据的过程在时间上并不确定,受本地网络,代理速度,抓取数据量 ...

  2. python定时爬取数据_python实现scrapy爬虫每天定时抓取数据的示例代码

    1. 前言. 1.1. 需求背景. 每天抓取的是同一份商品的数据,用来做趋势分析. 要求每天都需要抓一份,也仅限抓取一份数据. 但是整个爬取数据的过程在时间上并不确定,受本地网络,代理速度,抓取数据量 ...

  3. 实现从淘宝(天猫)定时抓取订单数据、打印电子面单并保存到ERP表中

    实现从淘宝(天猫)定时抓取订单数据.打印电子面单并保存到ERP表中 前言 实现思路 代码片段参考 前言 最近有厂商提出想把天猫店铺的数据拿到后台ERP管理系统中,并能实现线下打印电子面单功能.接手这个 ...

  4. 记一次批量定时抓取微信公众号文章的实现

    记一次批量定时抓取微信公众号文章的实现 抓取前的说明和准备 数据的抓取 批量抓取 定时抓取 对爬虫防抓取机制的一些解决办法 最后 抓取前的说明和准备 本次抓取的选择的语言是java,本文章不会将整个工 ...

  5. python自动抓取网管软件的数据_python实现scrapy爬虫每天定时抓取数据的示例代码...

    1. 前言. 1.1. 需求背景. 每天抓取的是同一份商品的数据,用来做趋势分析. 要求每天都需要抓一份,也仅限抓取一份数据. 但是整个爬取数据的过程在时间上并不确定,受本地网络,代理速度,抓取数据量 ...

  6. python实现scrapy爬虫每天定时抓取数据

    python实现scrapy爬虫每天定时抓取数据 1. 前言. 1.1. 需求背景. 每天抓取的是同一份商品的数据,用来做趋势分析. 要求每天都需要抓一份,也仅限抓取一份数据. 但是整个爬取数据的过程 ...

  7. python爬虫定时抓取数据

    python爬虫定时抓取数据 from scrapy import cmdline import datetime import time def doSth(): # 把爬虫程序放在这个类中 shi ...

  8. id 怎么获取jira 评论_一篇文章教会你使用Python定时抓取微博评论

    [Part1--理论篇] 试想一个问题,如果我们要抓取某个微博大V微博的评论数据,应该怎么实现呢?最简单的做法就是找到微博评论数据接口,然后通过改变参数来获取最新数据并保存.首先从微博api寻找抓取评 ...

  9. .NET Core 实现定时抓取博客园首页文章信息并发送到邮箱

    前言 大家好,我是晓晨.许久没有更新博客了,今天给大家带来一篇干货型文章,一个每隔5分钟抓取博客园首页文章信息并在第二天的上午9点发送到你的邮箱的小工具.比如我在2018年2月14日,9点来到公司我就 ...

最新文章

  1. 巨潮网怎么下载年报_上海注册公司后如何下载电子营业执照
  2. [转][Timer学习]wall time和monotonic time
  3. 记一次云安全的安全事件应急响应
  4. buuctf(misc) FLAG [LSB隐写]
  5. [转]C#中得到程序当前工作目录和执行目录的一些方法
  6. sketch放入app组件_使用Sketch App设计CSS网格
  7. Linux 命令之 iwconfig 命令-配置无线网络接口
  8. 系统辨识理论及应用_企业战略分析的理论工具
  9. 两边放动物对战守城的游戏_疯狂动物园小程序游戏:入口
  10. 硬盘的老化测试软件,固态硬盘不耐用?教你检测固态硬盘还能用多久
  11. 地址转换函数(点分十进制与网络字节序的二进制)
  12. 在 uniapp 中使用阿里图标
  13. CCSK云安全认证-M2-云基础设施安全
  14. 前端可视化的四种方式
  15. Laravel 生成QRCODE
  16. 深度搜索算法(DFS)
  17. 使用 Windows XP 的外观风格
  18. 基于SSM的花店系统
  19. 如何将word文档内容在网页显示方法
  20. 星聚宝—云服务器快速搭建网站(阿里云服务器举例)

热门文章

  1. 如何更好使用markdown输出pdf
  2. Python挑战游戏( PythonChallenge)闯关之路Level- 3
  3. Unity3D 2D射击小游戏瞄准线的实现
  4. Window 10 电源高性能模式设置
  5. 平面桁架静力计算程序
  6. c++成员变量初始化
  7. ubuntu16.04修改DNS永久生效
  8. 如何解决Error running ‘Tomcat 8.5.45‘: port out of range:-1
  9. Java Scaner类详解_动力节点Java学院整理
  10. 动态内存的申请和非动态内存的申请_公安交管新举措咋解读?非营运七座车6年免检,70岁可申请驾照...