Jsoup 抓取网页信息(1) 抓取 国际疾病码

 Jsoup Java 库是一款非常好用的网页数据抓取工具。 API非常简单。功能强大。

官方网站为:http://jsoup.org/

下面举个例子,怎样抓取网页数据。

下面网页是ICD-9-CM (International Classification of Diseases, Ninth Revision, Clinical Modification)  国际疾病分类码

http://www.icd9data.com/2015/Volume1/default.htm


1. 分析网页: 

 从这个网站上看,所有编码是呈现树结构分布。也就是每个向内部有不同的子项,深度不确认。

使用chrome自带的inspect element 工具我们可以看出来,所有代码是以html 的<li>元素进行显示,如下图:


用inspect element工具可以分析出各个子网页中的内容几乎都是以相同方式排列。唯一不同的是在最后的Leaf节点页面里, 如果是非leaf节点信息是alt="Non-specific code"

,如果是Leaf节点,节点信息是Specific code。

2.采取方法:

从上述分析,我们可以看出如果要抓取我们想要的信息,使用递归方法最方便。所以采取递归方法。

3.使用Jsoup抓取网页信息。具体的API使用方法,请阅读Jsoup文档。 下面代码可以成功抓取icd9的数据,并且输出相应的格式以便于建立树结构的数据库。

public class DiagnosisCodes {
    /**
     * diagnosis codes
     */
    static void captureIcd9DiagnosisCodes (){
        parsePage("http://www.icd9data.com/2015/Volume1/default.htm", 1, "\\DiagnosesCodes");
    }

    static void parsePage(String pageUrl, int level, String rootName) {
        boolean isRootPage = true;
        try {
            Document doc = Jsoup.connect(pageUrl).get();
            Elements newsHeadlines = doc.select("div.definitionList");
            if (newsHeadlines.isEmpty()) {
                newsHeadlines = doc.select("ul.definitionList");
                if (newsHeadlines.isEmpty()) {
                    //Here is the leaf
                    newsHeadlines = doc.select("ul.codeHierarchyUL");
                    isRootPage = false;
                }
            }

            //Parse the root
            Elements list = newsHeadlines = newsHeadlines.select("li");
            for (int i = 0; i < list.size(); i++) {
                Element li = list.select("li").get(i);
//                System.out.println(li.toString());
                if (isRootPage) {
                    NodeInfo nodeInfo = parseItem(li,level + 1, rootName);
                    if (nodeInfo.isRootPage) {
                        parsePage(nodeInfo.url, level + 1, rootName + "\\" + nodeInfo.name);
                    }
                } else {
                    //for the leaf
                    if (i != 0) { //remove the parent that belong to last page.
                        parseLeaf(li, level + 1, rootName);                        
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static NodeInfo parseItem(Element li, int level, String rootName) {
        boolean isRootPage = true;
        Element link = li.select("a").first();
        String linkHref = link.attr("href"); // "/2015/Volume1/800-999/default.htm"

        String diseaseNo = link.text(); // "800-999""

        String diseaseDesc = "";
        for (TextNode t : li.textNodes()) {
            if (!t.isBlank()) {
                diseaseDesc = t.text().trim();
            }
        }

        String type = "FA";
        if (!linkHref.endsWith("default.htm")) {
            type = "LA";
            isRootPage = false;
        }

        System.out.println(level + "#" + rootName + "\\" + diseaseDesc + "\\" +"#" + type + "#" + diseaseNo + "#" + diseaseDesc);
        return new NodeInfo (diseaseDesc, Common.host_link + linkHref, isRootPage);
    }

    static void parseLeaf(Element li, int level, String rootName) {
        Element span = li.select("span").first();//the <span> under <li>
        Element link = span.select("a").first();
        String linkHref = link.attr("href"); // "/2015/Volume1/800-999/default.htm"

        String diseaseNo = link.text(); // "800-999""

        Element s2 = span.select("span.threeDigitCodeListDescription").first();
        String diseaseDesc = s2.text();

        if (isRealLeaf (span)){
            if (isDoubleDecimal (diseaseNo)){
                level ++;
            }
            System.out.println(level + "#" + rootName + "\\"+ diseaseDesc + "\\" + "#LA#" + diseaseNo + "#" + diseaseDesc);
        }else{
            System.out.println(level + "#" + rootName + "\\"+ diseaseDesc + "\\" + "#FA#" + diseaseNo + "#" + diseaseDesc);
        }
    }

    static boolean isRealLeaf(Element span) {        
        Elements img = span.select("img");
        for (int i = 0; i < img.size(); i++) {
             String alt = img.get(i).attr("alt");
             if (alt != null &&  alt.equals("Specific code")){
                 return true;
             }
        }
        return false;
    }   
    
    static boolean isDoubleDecimal (String code){
        String s = code.trim();
        
        if (s.contains(".") && s.length() == 6){
            return true;
        }
        return false;
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值