文档章节

TinySpider实战之-Visual Paradigm教学相关文档下载

悠悠然然
 悠悠然然
发布于 2014/11/05 08:20
字数 1424
阅读 743
收藏 15

Visual Paradigm是一个非常棒的UML绘图工具,需要对它了解的,可以直接看官网,在此不做更多介绍,最近要使用它来做一些设计,它有非常完备的在线教学,写得非常不错。这个时候问题来了,这些教学非常多,而且如果所有人都访问外网的话及学习效率都比较低。通过观察,发现里面的所有文章都有PDF可以下载,而且里面的示例也可以下载,呵呵,这就好办了,做个程序把它抓下来不就解决了?于是把此问题交给HulkZ同学去干了,HulkZ同学花了半天时间交工,我看了下,发现虽然局部有优化的地方,但是总体还是可以的,于是就写这篇文章做个说明。

注:HulkZ同学还没有大学毕业,正在大学4年级学习。

第一步:教学首页的处理

public class VisualParadigmMain {
    public static void main(String[] args) throws Exception {
        Spider spider = new SpiderImpl("UTF-8");
        Watcher watcher = new WatcherImpl();
        watcher.addProcessor(new VisualParadigmMainProcessor());
        QuickNameFilter<HtmlNode> nodeFilter = new QuickNameFilter<HtmlNode>();
        nodeFilter.setNodeName("li");
        nodeFilter.setIncludeAttribute("class", "tutorialLeftMenuItem");
        watcher.setNodeFilter(nodeFilter);
        spider.addWatcher(watcher);
        spider.processUrl("http://www.visual-paradigm.com/tutorials/");
    }
}

大意是创建一个抓取UTF-8的爬虫,然后创建一个观察者,设定对带有class为tutorialLeftMenuItem的li标签用VisualParadigmMainProcessor类去处理,然后去处理URLhttp://www.visual-paradigm.com/tutorials/。

到这里处理还是比较清晰的,接下来看看VisualParadigmMainProcessor是怎么样的。

public class VisualParadigmMainProcessor implements Processor {
    public void process(String url, HtmlNode node, Map<String, Object> parameters) throws Exception {
        HtmlNode a = node.getSubNode("a");
        File file = new File("E:\\临时\\spider\\" + a.getPureText().trim());
        if (!file.exists()) {
            file.mkdirs();
        }
        VisualParadigmList.process(a.getAttribute("href"));
    }
}


这里传入的node实际上,就是上面说的带有class为tutorialLeftMenuItem的li标签,这里的意思是找到它下面的所有<a>标签,然后创建目录,然后再用VisualParadigmList类来对这些分类连接进行处理。

第二步:教学分类中的教学内容列表处理


教学分类中主要就是一篇一篇的教学文章了,接下来当然是对这些文章进行处理了。

public class VisualParadigmList {
    public static void process(String url) throws Exception {
        Spider spider = new SpiderImpl("UTF-8");
        Watcher watcher = new WatcherImpl();
        watcher.addProcessor(new VisualParadigmListProcessor());
        QuickNameFilter<HtmlNode> nodeFilter = new QuickNameFilter<HtmlNode>();
        nodeFilter.setNodeName("div");
        nodeFilter.setIncludeAttribute("class", "tutorial-link-container");
        watcher.setNodeFilter(nodeFilter);
        spider.addWatcher(watcher);
        spider.processUrl("http://www.visual-paradigm.com" + url);
        System.out.println(System.currentTimeMillis()+"-"+url);
    }
}
这里又创建一个爬虫,然后对需要处理的 页面查找class为"tutorial-link-container"的div标签,找到之后用VisualParadigmListProcessor进行处理。


VisualParadigmListProcessor类的内容如下:

public class VisualParadigmListProcessor implements Processor {
    public void process(String url, HtmlNode node, Map<String, Object> parameters) throws Exception {
        HtmlNode a = node.getSubNode("a");
        VisualParadigmPage.process(a.getPureText(), a.getAttribute("href"));
    }
}


意思就是再对它下面的a标签中的URL用VisualParadigmPage类进行处理。

第三步:具体的页面处理

上面就是具体的教学页面了,在其右上角,就有PDF的链接,下面要做的工作就是把这些PDF抓取下来,首先看VisualParadigmPage类:

public class VisualParadigmPage {
    public static void process(String title,String url) throws Exception {
        Spider spider = new SpiderImpl("UTF-8");
        Watcher watcher = new WatcherImpl();
        watcher.addProcessor(new VisualParadigmPageProcessor(title));
        QuickNameFilter<HtmlNode> nodeFilter = new QuickNameFilter<HtmlNode>();
        nodeFilter.setNodeName("html");
        watcher.setNodeFilter(nodeFilter);
        spider.addWatcher(watcher);
        spider.processUrl("http://www.visual-paradigm.com" + url);
        System.out.println(System.currentTimeMillis()+"-"+url);
    }
}



其意思是创建一个爬虫,并对里面的html标签用VisualParadigmPageProcessor类进行处理,相对于上面的一些类这个类的内容就稍微复杂些了:
public class VisualParadigmPageProcessor implements Processor {
    static HttpClient httpClient = new HttpClient();
    private final String title;

    public VisualParadigmPageProcessor(String title) {
        this.title = title;
    }

    public void process(String url, HtmlNode node, Map<String, Object> parameters) throws Exception {
        NameFilter<HtmlNode> titleUrlFilter = new NameFilter(node);
        titleUrlFilter.setNodeName("title");
        HtmlNode titleNode = titleUrlFilter.findNode();

        NameFilter<HtmlNode> pdfUrlFilter = new NameFilter(node);
        pdfUrlFilter.setNodeName("a");
        pdfUrlFilter.setIncludeAttribute("class", "pdf notranslate");
        HtmlNode pdfNode = pdfUrlFilter.findNode();
        NameFilter<HtmlNode> ol = new NameFilter(node);
        pdfUrlFilter.setNodeName("ol");
        pdfUrlFilter.setIncludeAttribute("class", "contentPoint");
        HtmlNode olNode = pdfUrlFilter.findNode();
        if (pdfNode != null) {
            String pdfUrl = "http://www.visual-paradigm.com" + pdfNode.getAttribute("href");
            saveUrl(titleNode.getPureText() + ".pdf", pdfUrl);
        }
        if (olNode != null && olNode.getSubNodes("a") != null) {
            for (HtmlNode aNode : olNode.getSubNodes("a")) {
                String vppUrl = "http://www.visual-paradigm.com" + aNode.getAttribute("href");
                saveUrl(aNode.getPureText(), vppUrl);
            }
        }
    }

    private void saveUrl(String name, String urlAddress) throws IOException {
        String fileName = "E:\\临时\\spider\\" + title + "\\" + name;
        GetMethod getMethod = new GetMethod(urlAddress);
        int iGetResultCode = httpClient.executeMethod(getMethod);
        if (iGetResultCode == HttpStatus.SC_OK) {
            InputStream inputStream = getMethod.getResponseBodyAsStream();
            OutputStream outputStream = new FileOutputStream(fileName);
            byte[] buffer = new byte[4096];
            int n = -1;
            while ((n = inputStream.read(buffer)) != -1) {
                if (n > 0) {
                    outputStream.write(buffer, 0, n);
                }
            }
            inputStream.close();
            outputStream.close();
        }
        getMethod.releaseConnection();
    }
}



但是其逻辑还是清晰的:

到文章中查找到标题,再查找到PDF的链接,再查找到其它附件的链接,如果有的话,就把它们存储下来,整个代码编写任务结束。

运行结果

D:\BaiduYunDownload\VPTutorials 的目录

2014/11/02  20:06    <DIR>          .
2014/11/02  20:06    <DIR>          ..
2014/11/02  20:05    <DIR>          Business Modeling
2014/11/02  20:05    <DIR>          Business Process Modeling
2014/11/02  20:05    <DIR>          Business Rule
2014/11/02  20:05    <DIR>          Code Engineering
2014/11/02  20:05    <DIR>          Customization
2014/11/02  20:05    <DIR>          Data Modeling
2014/11/02  20:05    <DIR>          Database Tools
2014/11/02  20:05    <DIR>          Design Animation
2014/11/02  20:05    <DIR>          Diagramming
2014/11/02  20:05    <DIR>          Enterprise Architecture
2014/11/02  20:05    <DIR>          Glossary
2014/11/02  20:05    <DIR>          Grid
2014/11/02  20:05    <DIR>          IDE Integration
2014/11/02  20:05    <DIR>          Impact Analysis
2014/11/02  20:05    <DIR>          Interoperability
2014/11/02  20:05    <DIR>          Modeling Toolset
2014/11/02  20:05    <DIR>          Object Relational Mapping
2014/11/02  20:05    <DIR>          Plug-in Development
2014/11/02  20:05    <DIR>          Process Simulation
2014/11/02  20:05    <DIR>          Project Referencing
2014/11/02  20:06    <DIR>          Reporting
2014/11/02  20:06    <DIR>          Requirements Capturing
2014/11/02  20:06    <DIR>          SoaML Modeling
2014/11/02  20:06    <DIR>          Team Collaboration
2014/11/02  20:06    <DIR>          UML Modeling
2014/11/02  20:06    <DIR>          Use Case Modeling



上面是他提交给我的成果物,总共108M,任务完成得非常漂亮。

补充

这部分代码,HulkZ同学已经Push给我,放在TinySpider工程当中。

另外做这个过程中,还发现TinySpider不能处理gzip方式处理过的Html文档,因此还增加了对gzip方式的html内容进行处理的支持。

更多内容,请查看Tiny框架官网:http://www.tinygroup.org,也可以查看本人的博客,相信不会空手而归。

也可以添加本人QQ进行直接沟通,还可以加入Tiny群与TinyFans互动。

© 著作权归作者所有

悠悠然然

悠悠然然

粉丝 2475
博文 185
码字总数 363071
作品 14
杭州
架构师
私信 提问
加载中

评论(3)

悠悠然然
悠悠然然 博主

引用来自“四少”的评论

我觉得比如编码?url的放在配置文件里是不是更好?
呵呵,这个只是个简单实例了,比较简单,所以放哪里问题都不大。
敲代码猥琐男
敲代码猥琐男
我觉得比如编码?url的放在配置文件里是不是更好?
芝麻谷
芝麻谷
点赞
悠然乱弹:WebMagic VS TinySpider

上次@黄勇 提到与@黄亿华 WebMagic比较的问题。我在后面简单回复了一下下,现系统整理一下,不一定正确。 两者都是可以用于网页数据抓取,都有良好的扩展性及架构设计,但是由于定位稍有差异...

悠悠然然
2014/03/04
599
5
用TinySpider进行网页抓取实例

非常感谢@李少龙 的提醒 本例中用到的maven坐标变化如下: <dependency><groupId>org.tinygroup</groupId><artifactId>org.tinygroup.spider</artifactId><version>0.1.0-SNAPSHOT</version>......

悠悠然然
2014/03/01
2.4K
25
你做好准备参加一个活力四射的开源团队了吗?

关于Tiny框架更多的介绍,参见:http://www.tinygroup.org/ Tiny框架现有成员列表:http://www.tinygroup.org/about.page Tiny框架发起人博客:http://my.oschina.net/tinyframework/blog Ti...

悠悠然然
2014/06/25
1K
22
OSChina 技术周刊第八期 —— 10 大常见的 web 开发错误

每周技术抢先看,总有你想要的! 移动开发 【翻译】实现 iOS 上的井字游戏 前端开发 【软件】Twemoji —— Twitter 开源其完整的 Emoji 表情 【软件】LokiJS —— 高性能的 JavaScript 数据库...

OSC编辑部
2014/11/09
4K
5
关于使用tinyspider从网页抓取数据的问题

@悠悠然然 你好,想跟你请教个问题:经你的代码指导,但我还是运行不结果,(关于笑话大全的那个),求指导,谢谢!

ls612473
2014/04/10
518
2

没有更多内容

加载失败,请刷新页面

加载更多

idea 打开一个新的项目,maven都需要重新配置,解决方案

需要有个默认全局配置 File->Other Settings -> Default Settings 将Maven home directory目录修改成我们自定安装Maven的目录...

观海562
22分钟前
3
0
链表中环的入口节点

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。 思路: public ListNode EntryNodeOfLoop(ListNode pHead) { if (pHead == null || pHead.next == null) ...

Garphy
42分钟前
5
0
Spring5 源码分析-容器刷新-invokeBeanFactoryPostProcessors()方法

上一篇:Spring5 源码分析-容器刷新-prepareBeanFactory()方法 该方法主要完成以下功能: 1.实例化ConfigurationClassPostProcessor,并调用ConfigurationClassPostProcessor.postProcessBe...

特拉仔
42分钟前
5
0
为什么MySQL用B+树做索引

索引这个词,相信大多数人已经相当熟悉了,很多人都知道MySQL的索引主要以B+树为主,但是要问到为什么用B+树,恐怕很少有人能把前因后果讲述的很完整。本文就来从头到尾介绍下数据库的索引。...

小致Daddy
今天
8
0
网站前台的三级联动数据封装

我在进行项目时候遇到了一个进行数据封装的一个功能,进行数据的封装的功能也挺复杂,来回试了好几十种方法.最后使用的是这种方法. 使用一个pojo进行封装两个数据,一个是list一个是实体类. 具体...

小天丶羽
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部