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

时间:2022-10-31 11:48:24

 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

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

1. 分析网页: 

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

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

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

用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;
}
}