You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

148 lines
5.1 KiB

#!/usr/bin/perl
use strict;
#######################################################################
# Copyright (C) 2007-2010 Rod Roark <rod@sunsetsystems.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#######################################################################
# This loads ICD9 codes and descriptions into the "codes" table of
# OpenEMR, scraping from from www.icd9data.com.
# Alternatively you can just dump the INSERT statements to stdout.
#######################################################################
# You might need to install one or more of these dependencies.
# The Debian/Ubuntu package names are noted as comments:
#
use DBI; # libdbi-perl and libdbd-mysql-perl
use WWW::Mechanize; # libwww-mechanize-perl
use HTML::TokeParser; # libhtml-parser-perl
#######################################################################
# Parameters that you may customize #
#######################################################################
# Change this as needed for years other than 2010.
#
my $START_URL = "http://www.icd9data.com/2010/Volume1/default.htm";
# An empty database name will cause SQL INSERT statements to be dumped
# to stdout, with no database access. To update your OpenEMR database
# directly, specify its name here.
#
my $DBNAME = "";
# You can hard-code the database user name and password (see below),
# or else put them into the environment with bash commands like these
# before running this script:
#
# export DBI_USER=username
# export DBI_PASS=password
#
my $dbh = DBI->connect("dbi:mysql:dbname=$DBNAME") or die $DBI::errstr
if ($DBNAME);
# my $dbh = DBI->connect("dbi:mysql:dbname=$DBNAME", "username", "password")
# or die $DBI::errstr if ($DBNAME);
# Comment this out if you want to keep old nonmatching codes.
#
$dbh->do("delete from codes where code_type = 2") or die "oops"
if ($DBNAME);
#######################################################################
# Startup #
#######################################################################
$| = 1; # Turn on autoflushing of stdout.
my $countup = 0;
my $countnew = 0;
#######################################################################
# Main Logic #
#######################################################################
# This function recursively scrapes all of the web pages.
#
sub scrape {
my $url = shift;
my $browser = WWW::Mechanize->new();
$browser->get($url);
my $parser = HTML::TokeParser->new(\$browser->content());
while(my $tag = $parser->get_tag("li", "div")) {
# The <li><a> sequence is recognized as a link to another list
# that must be followed. We handle those recursively.
if ($tag->[0] eq "li") {
$tag = $parser->get_tag;
$tag = $parser->get_tag if ($tag->[0] eq "strong");
next unless ($tag->[0] eq "a");
my $nexturl = $browser->base();
# $nexturl =~ s'/[^/]+$'/';
$nexturl =~ s'/20.+$'';
scrape($nexturl . $tag->[1]{href});
}
# The <div><img> sequence starts an ICD9 code and description.
# If the "specific green" image is used then we know this code is
# valid as a specific diagnosis, and we will grab it.
else {
$tag = $parser->get_tag;
next unless ($tag->[0] eq "img");
next unless ($tag->[1]{src} =~ /SpecificGreen/);
$tag = $parser->get_tag("a");
my $tmp = $parser->get_trimmed_text;
unless ($tmp =~ /Diagnosis Code (\S+)/) {
print STDERR "Parse error in '$tmp' at $url\n";
next;
}
my $code = $1;
$tag = $parser->get_tag("div");
my $desc = $parser->get_trimmed_text;
$desc =~ s/'/''/g; # some descriptions will have quotes
# This creates the needed SQL statement, and optionally writes the
# code and its description to the codes table.
my $query = "INSERT INTO codes " .
"( code_type, code, modifier, code_text ) VALUES " .
"( 2, '$code', '', '$desc' )";
if ($DBNAME) {
my $usth = $dbh->prepare("SELECT id FROM codes " .
"WHERE code_type = 2 AND code = '$code'")
or die $dbh->errstr;
$usth->execute() or die $usth->errstr;
my @urow = $usth->fetchrow_array();
if (! @urow) {
++$countnew;
}
else {
$query = "UPDATE codes SET code_text = '$desc' " .
"WHERE code_type = 2 AND code = '$code'";
++$countup;
}
$dbh->do($query) or die $query;
}
print $query . ";\n";
}
}
}
# This starts the ball rolling.
scrape($START_URL);
#######################################################################
# Shutdown #
#######################################################################
if ($DBNAME) {
print "\nInserted $countnew rows, updated $countup codes.\n";
$dbh->disconnect;
}