多站点RSS新闻正文抓取,导入discuz论坛,自动发帖的实现(一)
2013-11-06 16:04
507 查看
公司研发部不能上外网,但是公司又希望研发的同事能关注下新闻,了解科技热点,跟上时代潮流。所以搭建了一个discuz论坛, 但内容匮乏。幸运的是搭这台论坛的服务器可以上网的(在两个网络里面)。所以想着要我做一个爬虫工具,通过rss把新闻内容,抓取过来放到公司论坛。
现在已经实现了,同时抓取多个网站上面的数据(IT之家,虎嗅网等等),只有文字没有图片。当然图片抓取,我也会尝试做出来。目前的效果还不错。网络上关于RSS读取的文字特别多,但是关于rss中链接指向正文的抓取比较少,正好这几天做这样一个项目,现在把设计思想和关键代码贴出来分享一下。
源码已经整理上传,在文章最底部有链接。
一、先简单介绍下RSS
更多RSS介绍:http://www.360doc.com/content/10/1224/09/1007797_80869844.shtml
二、实现思路
1. http请求抓取RSS的内容。rss都是xml格式,通过home jar装配成对象。
先定义一个bean,请求的rss 内容都装配成这种对象。字段根据你的项目要求来
http请求代码,这里引用了 import com.sun.syndication.feed.synd.* ;下面的文件,请引入home.jar包
到这里rss解析就完毕了。新闻标题、文章地址、简介都有了,很简单吧,问题来了,新闻的正文还没有呢?正文是不在rss内的,像百度新闻这种,只是做一个聚合,当你点击新闻链接的时候,依然会链接到新闻的源网页上面去。
某些时候,我们需要把新闻的正文也抓下来。难度不大,请接着往下看。
这个link就指向新闻的正文页面,我们需要做的是从url获取到源码。这里使用java 发起一个http请求,这里涉及到java网络操作的知识点,忘记了的再去补一下吧。 因为每个网站的编码都不一样,有的用gbk,有的utf-8。中文在这个时候就比较纠结了,乱码问题常常出现, 所以就有了这行代码
这个pageEncoding,可以从读取来源码中找到,比如
当然我是实现去要找的网站上找到的(肉眼去看的),gb2312对应GB2312;utf-8对应UTF-8.乱码问题不多说,出了乱码就是这里的问题。
现在就把网页的源代码全部抓过来了,还不是我们想要的啊,我只要正文,其他东西都不要的。
看看我怎么做的吧。
我用IT之家做的测试, 网站的右上角 有个"订阅 "按钮---->点击
跳转到了RSS 目录。这些内容都被我抓取了,内容中的 红色<link> 中的url 就指向新闻正文,复制链接,在浏览器中打开。如下图,
红色框中的内容 是不需要的,只需要绿色框中的内容。 我们抓来的源码,就是一个string,只要找到文章的开始和结尾, 那不就把正文抓下来了吗? 并且同一个网站,文章的内容的位置都一样, 如果文章的父标签是<div id="content"></div> 这样我们就找到正文的开始了,正文的结尾也大多如此。 看下文
使用firebug 查看正文位置 我取的正文开始:<div class="post_content" id="paragraph">
正文结尾:<div class="share">
对应到代码中,就是一个求子串的过程。如下
就这样 ,新闻的正文就抓过来了, 每个网站的 startTag和endTag 都不一样,所以要分开对待。
rss正文抓取就这样搞定了,下一篇文章,我会介绍针对不同网站,不同rss的正文抓取策略。也算是对自己工作的总结吧。
想认真研究的下载源码吧。这个博客只写了一些关键的代码,有任何问题都可以直接联系我。
这个项目使用maven 开发,请加入maven支持或者导入相应的jar
源码的下载地址: http://download.csdn.net/detail/a442180673/6511981 简单版本 正文抓取,未导入到数据
完整版本 :http://download.csdn.net/detail/a442180673/6523263 导入discuz 数据库的实现
现在已经实现了,同时抓取多个网站上面的数据(IT之家,虎嗅网等等),只有文字没有图片。当然图片抓取,我也会尝试做出来。目前的效果还不错。网络上关于RSS读取的文字特别多,但是关于rss中链接指向正文的抓取比较少,正好这几天做这样一个项目,现在把设计思想和关键代码贴出来分享一下。
源码已经整理上传,在文章最底部有链接。
一、先简单介绍下RSS
1: 什么是RSS RSS(really simple syndication) :网页内容聚合器。RSS的格式是XML。必须符合XML 1.0规范。 RSS的作用:订阅BLOG,订阅新闻 2 RSS的历史版本: http://blogs.law.harvard.edu/tech/rssVersionHistory RSS的版本有很多个,0.90、0.91、0.92、0.93、0.94、1.0 和 2.0。与RSS相对的还有ATOM。 国内主要是RSS2.0,国外主要用ATOM0.3. 由于RSS出现2派,导致混乱场面。其中RSS2.0规范由哈佛大学定义并锁定。 地址:http://blogs.law.harvard.edu/tech/rss 3: 解析jar:Rome: http://wiki.java.net/bin/view/Javawsxml/Rome Rome是 java.net 上的一个开源项目,现在的版本是1.0。为什么叫Rome呢,按它的介绍上的说法,有个“条条大路通罗马”的意思,有些RSS的意味。Rome可能是 sun 公司从自己某个子项目中抽离出来的,package和类的命名就象j2sdk一样感觉规范。功能上支持RSS的所有版本及 Atom 0.3(Atom是和RSS类似的一种内容聚合的方式)。Rome 本身是提供API和功能实现. |
二、实现思路
1. http请求抓取RSS的内容。rss都是xml格式,通过home jar装配成对象。
先定义一个bean,请求的rss 内容都装配成这种对象。字段根据你的项目要求来
public class RSSItemBean { private String title; private String author; private String uri; private String link; private String description; private Date pubDate; private String type; private String content; //省略 get set }
http请求代码,这里引用了 import com.sun.syndication.feed.synd.* ;下面的文件,请引入home.jar包
/** * * @param url rss 网站地址 比如:http://www.ithome.com/rss/ * @return 所有文章对象 * @throws Exception */ public List<RSSItemBean> getRss(String url) throws Exception { URL feedUrl = new URL(url);//SyndFeedInput:从远程读到xml结构的内容转成SyndFeedImpl实例 SyndFeedInput input = new SyndFeedInput();//rome按SyndFeed类型生成rss和atom的实例, SyndFeed feed = input.build(new XmlReader(feedUrl)); //SyndFeed是rss和atom实现类SyndFeedImpl的接口 List<SyndEntryImpl> entries = feed.getEntries(); RSSItemBean item = null; List<RSSItemBean> rssItemBeans = new ArrayList<RSSItemBean>(); for (SyndEntryImpl entry : entries) { item = new RSSItemBean(); item.setTitle(entry.getTitle().trim()); item.setType(feed.getTitleEx().getValue().trim()); item.setUri(entry.getUri()); item.setPubDate(entry.getPublishedDate()); item.setAuthor(entry.getAuthor()); rssItemBeans.add(item); } return rssItemBeans; }
到这里rss解析就完毕了。新闻标题、文章地址、简介都有了,很简单吧,问题来了,新闻的正文还没有呢?正文是不在rss内的,像百度新闻这种,只是做一个聚合,当你点击新闻链接的时候,依然会链接到新闻的源网页上面去。
某些时候,我们需要把新闻的正文也抓下来。难度不大,请接着往下看。
String url = entry.getUri();
item.setUri(url);
这个link就指向新闻的正文页面,我们需要做的是从url获取到源码。这里使用java 发起一个http请求,这里涉及到java网络操作的知识点,忘记了的再去补一下吧。 因为每个网站的编码都不一样,有的用gbk,有的utf-8。中文在这个时候就比较纠结了,乱码问题常常出现, 所以就有了这行代码
htmlContent = new String(bytes, pageEncoding);
这个pageEncoding,可以从读取来源码中找到,比如
content="text/html; charset=gb2312"
当然我是实现去要找的网站上找到的(肉眼去看的),gb2312对应GB2312;utf-8对应UTF-8.乱码问题不多说,出了乱码就是这里的问题。
/** * http 请求获取到页面的源码 * @param surl 正文url * @return 页面源码 */ public String getStaticPage(String surl) { String htmlContent = ""; try { java.io.InputStream inputStream; java.net.URL url = new java.net.URL(surl); java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection(); connection.connect(); inputStream = connection.getInputStream(); byte bytes[] = new byte[1024 * 4000]; int index = 0; int count = inputStream.read(bytes, index, 1024 * 4000); while (count != -1) { index += count; count = inputStream.read(bytes, index, 1); } htmlContent = new String(bytes, pageEncoding); connection.disconnect(); } catch (Exception ex) { ex.printStackTrace(); } return htmlContent.trim(); }
现在就把网页的源代码全部抓过来了,还不是我们想要的啊,我只要正文,其他东西都不要的。
看看我怎么做的吧。
我用IT之家做的测试, 网站的右上角 有个"订阅 "按钮---->点击
跳转到了RSS 目录。这些内容都被我抓取了,内容中的 红色<link> 中的url 就指向新闻正文,复制链接,在浏览器中打开。如下图,
红色框中的内容 是不需要的,只需要绿色框中的内容。 我们抓来的源码,就是一个string,只要找到文章的开始和结尾, 那不就把正文抓下来了吗? 并且同一个网站,文章的内容的位置都一样, 如果文章的父标签是<div id="content"></div> 这样我们就找到正文的开始了,正文的结尾也大多如此。 看下文
使用firebug 查看正文位置 我取的正文开始:<div class="post_content" id="paragraph">
正文结尾:<div class="share">
对应到代码中,就是一个求子串的过程。如下
/** * 根据url 获取 正文内容 * * @param url 指向正文的url地址 * @return 正文源码 */ public String getContent(String url) { String src = getStaticPage(url); //获取所有源码 int startIndex = src.indexOf(startTag); //开始标签 int endIndex = src.indexOf(endTag); //结束标签 // System.out.println(src); // System.out.println(startTag+"\t"+endTag); //System.out.println(startIndex+"\t"+endIndex); if (startIndex!=-1 && endIndex !=-1) { return src.substring(startIndex, endIndex); } return ""; }
就这样 ,新闻的正文就抓过来了, 每个网站的 startTag和endTag 都不一样,所以要分开对待。
rss正文抓取就这样搞定了,下一篇文章,我会介绍针对不同网站,不同rss的正文抓取策略。也算是对自己工作的总结吧。
想认真研究的下载源码吧。这个博客只写了一些关键的代码,有任何问题都可以直接联系我。
这个项目使用maven 开发,请加入maven支持或者导入相应的jar
源码的下载地址: http://download.csdn.net/detail/a442180673/6511981 简单版本 正文抓取,未导入到数据
完整版本 :http://download.csdn.net/detail/a442180673/6523263 导入discuz 数据库的实现
相关文章推荐
- 多站点RSS新闻正文抓取,导入discuz论坛,自动发帖的实现(三)
- 多站点RSS新闻正文抓取,导入discuz论坛,自动发帖的实现
- 多站点RSS新闻正文抓取,导入discuz论坛,自动发帖的实现(二)
- Python实现自动登录discuz论坛
- Discuz论坛自动发帖机
- powerd by discuz 7.2 论坛自动发帖原理介绍
- 网站上抓取数据并且自动发帖到论坛程序
- PYTHON实现DISCUZ论坛的自动POST登录发贴回帖
- PYTHON实现DISCUZ论坛的自动POST登录发贴回帖
- 抓取网站数据并且自动发帖到论坛
- Asp.Net站点整合Discuz论坛实现同步注册和单点登录
- Asp.Net站点整合Discuz论坛实现同步注册和单点登录
- Discuz!开发之修改论坛TAG页面,实现主题按发帖时间倒序排序(新帖在前)
- C#代码、流程discuz论坛批量或自动发帖
- discuz 中实现从微信抓取消息并发帖
- 黄聪:Python实现Discuz论坛的自动POST登录发贴回帖(转)
- 黄聪:Python实现Discuz论坛的自动POST登录发贴回帖(转)
- 通过SAS宏实现自动导入批量数据
- discuz!X1.5 指定版块发帖时 自动默认最高阅读权限(让您的秘密版块只有vip可见)
- 使用java的html解析器jsoup和jQuery实现一个自动重复抓取任意网站页面指定元素的web应用