多站点RSS新闻正文抓取,导入discuz论坛,自动发帖的实现(一)

公司研发部不能上外网,但是公司又希望研发的同事能关注下新闻,了解科技热点,跟上时代潮流。所以搭建了一个discuz论坛, 但内容匮乏。幸运的是搭这台论坛的服务器可以上网的(在两个网络里面)。所以想着要我做一个爬虫工具,通过rss把新闻内容,抓取过来放到公司论坛。

现在已经实现了,同时抓取多个网站上面的数据(IT之家,虎嗅网等等),只有文字没有图片。当然图片抓取,我也会尝试做出来。目前的效果还不错。网络上关于RSS读取的文字特别多,但是关于rss中链接指向正文的抓取比较少,正好这几天做这样一个项目,现在把设计思想和关键代码贴出来分享一下。 源码已经整理上传,在文章最底部有链接。

一、先简单介绍下RSS

1: 什么是RSSRSS(really simple syndication) :网页内容聚合器。RSS的格式是XML。必须符合XML 1.0规范。RSS的作用:订阅BLOG,订阅新闻2 RSS的历史版本:http://blogs.law.harvard.edu/tech/rssVersionHistoryRSS的版本有很多个,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/rss3: 解析jar:Rome:http://wiki.java.net/bin/view/Javawsxml/RomeRome是 java.net 上的一个开源项目,现在的版本是1.0。为什么叫Rome呢,按它的介绍上的说法,有个“条条大路通罗马”的意思,有些RSS的意味。Rome可能是 sun 公司从自己某个子项目中抽离出来的,package和类的命名就象j2sdk一样感觉规范。功能上支持RSS的所有版本及 Atom 0.3(Atom是和RSS类似的一种内容聚合的方式)。Rome 本身是提供API和功能实现.

更多RSS介绍:http://www.360doc.com/content/10/1224/09/1007797_80869844.shtml

二、实现思路

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 就指向新闻正文,复制链接,在浏览器中打开。如下图,

使用firebug 查看正文位置 我取的正文开始:<div class="post_content" id="paragraph">

正文结尾:<div class="share">

对应到代码中,就是一个求子串的过程。如下


就这样 ,新闻的正文就抓过来了, 每个网站的 startTag和endTag 都不一样,所以要分开对待。

想认真研究的下载源码吧。这个博客只写了一些关键的代码,有任何问题都可以直接联系我。

这个项目使用maven 开发,请加入maven支持或者导入相应的jar

源码的下载地址:http://download.csdn.net/detail/a442180673/6511981 简单版本 正文抓取,未导入到数据

完整版本 :http://download.csdn.net/detail/a442180673/6523263 导入discuz 数据库的实现

接受失败更是一种智者的宣言和呐喊

多站点RSS新闻正文抓取,导入discuz论坛,自动发帖的实现(一)

相关文章:

你感兴趣的文章:

标签云: