级别: 中级 Nathan Harrington (harrington.nathan@gmail.com), 程序员, IBM
2007 年 6 月 12 日 AT&T Research 的 Graphviz 以及一些其他程序都是非常不错的工具,可以自动完成复杂链接集合的可视化工作。本文向您展示如何结合使用 Graphviz 工具集和 Web 页面缩略图生成器,创建能够显示 Web 页面上所有链接结构的新方式。您可以使用这些技巧和说明优化自己的显示逻辑,并创建定向和无向的 Graphviz 图表来增强对结构、软件和其他复杂链接的数据集的理解。
需求
硬件
任何 2000 年以后生产的 PC 机应该都能够满足编译和运行代码所需的处理能力。如果您打算绘制大量节点(多于 50 个),或者使用较大的 Web 页面缩略图呈现图形,确保使用千兆赫处理器和具有多个千兆字节的 RAM。当对磁盘进行分页操作时,规范简单的系统配置将需要较长的处理时间。
软件
当然,你需要使用 Graphviz,还需要 CPAN 的 HTML::SimpleLinkExtor 模块。如果要在 Linux® 上运行程序,可以使用 Simon MacMullen 的 khtml2png 工具生成自动的 Web 页面缩略图。如果在 Windows® 上运行,有很多种方法可以生成 Web 页面缩略图,那些希望评估可用于 Windows 程序的免费许可的读者可以为自己的环境选择一种工具。您还需要一个简单快捷的图像查看器,我推荐使用 Tom Gilbert 的 feh。参见 参考资料 中关于这些工具的链接。
安装
如果您是在 Windows 上运行程序,下载并运行 Graphviz 安装包。注意二进制代码的安装位置,稍后将在呈现过程中使用到。在 Linux 上,可以使用您喜欢的包管理器或直接从 Graphviz.org 获得源代码和二进制代码。
您还需要使用 Brian Foy 编写的 HTML::SimpleExtor 模块。假设您已经在 Window 上具有了可用的 Perl 环境,可以使用 ppm install HTML::SimpleLinkExtor 命令自动下载和安装包。对于 Linux,运行 cpan -i HTML::SimpleLinkExtor 即可。
在 Linux 上,还可以使用 khtml2png 程序快速生成 Web 页面缩略图。在运行 Fedora Core 3 的开发环境中,V1.0.2 版本将能够按预期执行。您可能会发现在自己的系统上必须使用基于 Qt 和 KDE 库的其他版本的 khtml2png 工具。查看 参考资料 中 kthml2png 程序的链接。对于操作 Windows 的人员,查看 参考资料 中可用来在 Window 上创建 Web 页面缩略图的各种程序。
一般策略,实现理想的可视化
我们希望看到什么?
开发可视化最棘手的部分之一就是确定所希望看到的内容。通过使用各种策略以及反复测试,本文确定了如下可视化策略:构建 Web 页面缩略图的无向图,其中节点之间的箭头用粗线表示,颜色与页面间链接的数量直接有关。听上去很简单,现在让我们看看是如何实现的。
如何实现?
构建粗略定义的图形的第一个步骤是获得相关 Web 页面之间的链接数量。实现此目的的最简单方法就是使用 HTML::SimpleLinkExtor 模块。清单 1 展示了可用于从指定的 HTML 文件提取前 N 个链接的 topLinks.pl 程序。
清单 1. topLinks.pl — 打印 HTML 页面中链接的频率计数
#!/usr/bin/perl -w
# topLinks.pl - print the top N links from an html file using SimpleLinkExtor
use strict;
use HTML::SimpleLinkExtor;
die "usage: toplinks.pl <html_file> <number>" unless @ARGV == 2;
my $extor = HTML::SimpleLinkExtor->new();
$extor->parse_file("$ARGV[0]");
my $maxLinks = $ARGV[1];
my %linkHash = ();
my @a_hrefs = $extor->a;
for my $link ( @a_hrefs )
{
next unless $link =~ /http/; # only process http links
$link = substr($link,7); # remove http://
# handle the triple slash prefix
$link = substr($link,1) unless substr($link,0,1) ne "/";
# remove everything after slash
$link = substr($link,0,index($link,'/')) unless $link !~ /\//;
# remove all subdomains
$link = substr($link,index($link,".")+1) unless ($link =~ tr/\.//) == 1;
$linkHash{$link}++;
}#for each link
my $linkCount = 0;
for my $key( sort {$linkHash{$b} <=>$linkHash{$a}} keys %linkHash )
{
print "$key $linkHash{$key}\n";
last unless $linkCount < $maxLinks-1;
$linkCount++;
}
|
完成变量和使用信息的设置后,SimpleLinkExtor 模块将处理指定的 HTML 文件。接下来将只对 HTTP 链接进行循环处理。代码将修改 domain.tld 表单中的所有链接。如果链接为 www.ibm.com/index.html,则斜杠之后的内容和第一个句点之前的内容将被截掉。这将为我们提供所有链接到输入 HTML 文件的域的频率计数。对于具有频率计数值的域散列,按照值对列表排序并打印前 N 个链接。下载开始页面的源 HTML 作为 startPage.html,并使用 perl topLinks.pl startPage.html 10 > top10Links 命令运行程序。
在本例中,我们使用 slashdot.org/index.html 作为 HTML 文件,图 2 展示了 top10Links 文件的内容。注意,由于对 Slashdot.org 页面进行了更新,文件中的值会有所不同。我们将把这些数据输入到 Graphviz dot 语言生成程序中。
清单 2. Slashdot.org 主页面链接的频率计数
slashdot.org 15
ostg.com 6
bfast.com 3
blogs.com 3
jhuapl.edu 3
arstechnica.com 2
doubleclick.net 2
wikipedia.org 2
wsj.com 2
thinkgeek.com 2
|
生成 Web 页面缩略图
如果在 Linux 之上运行,生成 Web 页面缩略图的最简便方法是使用 khtml2png 程序。在命令行中使用该程序可以很轻松地生成缩略图,甚至可以为包含 Flash 内容和其他修饰的页面生成缩略图。为此,需要有足够的时间加载 Flash 内容,因此可以使用 --flash-delay 选项。考虑使用如下一行代码为 top10Links 文件包含的域构建 Web 页面缩略图。
清单 3. Web 页面缩略图生成代码
cat top10Links | \
perl -lane '$r=`./khtml2png --flash-delay 3 \
--scaled-width 200 --scaled-height 200 http://$F[1] thumbnails/$F[1].png`'
|
注意 \ 字符用于本文的格式,需要删除该字符以使代码发挥作用。还需注意各种缩略图被放置在缩略图目录中,并且具有文件名 domain_name.png — 例如,thumbnails/ostg.com.png。这种特性将简化下面的 dot 语法生成步骤中的处理。
如果使用的是 Windows 系统,有很多方法可以创建 Web 页面快照。可以使用 参考资料 中列出的其中一种工具。
无向图 dot 语言语法生成
构建 dot 文件
既然已经生成了 Web 页面缩略图,现在可以开始生成图形描述语言了。
基本的 Graphviz 语言语法主要关注节点和边的概念。我们还将使用较少用到的聚类和 shapefile 概念。有关 Graphviz dot 语言以及 Graphviz 令人惊叹的图形生成功能的更多信息,请参见 参考资料。清单 3 展示了 dot 语言语法示例,需要使用它来创建所需的图形类型:
清单 4. 示例 dot 语法文件
subgraph "cluster_jhuapl.edu" { label="jhuapl.edu"; labelloc="t"; "jhuapl.edu_icon"};
"jhuapl.edu_icon" [label="", shape=box,
style=invis, shapefile="snapsSlash/jhuapl.edu.png"];
edge [ color="#93ca36", arrowtail="normal", arrowsize="3",
arrowhead="none", style="setlinewidth(9)" ];
"cluster_jhuapl.edu" -- "cluster_slashdot.org";
|
需要使用一致的方式放置缩略图节点和节点标签。实现此目的最简便方法之一就是创建一个子图,并将图像和标签放在子图中。清单 4 中的行 1 定义了名为 cluster_jhuapl.edu 的子图。这个聚类在顶部位置具有一个标签并包含了已知的 jhuapl.edu_icon 节点。行 4 定义了一个 jhuapl.edu_icon 节点(属性为 no label),一个不可见的边界框,以及一个用作合适的 Web 页面缩略图文件的图像。行 5 继续定义主节点和当前节点之间的边的属性。一个较大的亮绿色箭头指向链接的节点,使用增强的粗线来强调链接。行 7 定义了主节点和链接节点之间的链接。
下面所示的 dot 语法语言构建程序将自动处理不同的边属性,从而强调链接并创建定义宽松的图形。清单 5 展示了创建无向图的 buildDot.pl 程序。
清单 5. buildDot.pl — 创建 dot 语言无向图
#!/usr/bin/perl -w
# buildDot.pl - generate dot language undirected graph
use strict;
die "usage: buildDot.pl <home_node> <thumbnail_dir>" unless @ARGV == 2;
my( $homeNode, $thumbsDir ) = @ARGV;
print "graph g {\n";
while(<STDIN>)
{
my( $lineWidth, $nodeName ) = split;
# specify clusters
print qq(subgraph "cluster_$nodeName" );
print qq({ label="$nodeName"; labelloc="t"; "${nodeName}_icon"};\n);
print qq("${nodeName}_icon" [label="", shape=box, style=invis, );
print qq(shapefile="$thumbsDir/$nodeName.png"];\n);
# prevent recursive link
if( $nodeName =~ /$homeNode/ ){ print qq(\n); next }
# edge color classes, width emphasis
my $lineColor = "#000000";
if( $lineWidth > 8 ){ $lineColor = "#ff9900" }
elsif( $lineWidth > 5 ){ $lineColor = "#ca7836" }
elsif( $lineWidth > 3 ){ $lineColor = "#cabb36" }
elsif( $lineWidth > 2 ){ $lineColor = "#93ca36" }
$lineWidth *= 3;
# specify edge
print qq(edge [ color="$lineColor", arrowtail="normal", arrowsize="3", );
print qq(style="setlinewidth($lineWidth)" ];\n);
# specify linkage
print qq("cluster_$nodeName" -- "cluster_$homeNode";\n\n);
}#while stdin
print qq(}\n);
|
检查了选项并准备好使用信息后,程序将通过 graph g{ 行指定该图形是一个无向图。我们将使用清单 2 中的链接频率计数和域名分别作为 lineWidth 和节点名。read-from-stdin 循环中的第一部分将打印聚类描述,并打印在聚类内显示的节点。命令行中指定的 Web 页面缩略图目录将为每个节点提供正确的 shapefile 图像。
在第二部分中,如果刚刚打印出来的聚类和 shapefile 节点是主节点,那么退出主循环并且不要编写边或链接信息。这样做将避免图形描述中的自引用。虽然创建无向图的 Graphviz 解析器能够处理这类自引用问题,但是为了确保在需要时能够更轻松地转换为其它图形算法,我们并不打算这样做。
最后一部分创建了一个简单的分级着色系统,它分为五级。如果频率计数很小,那么使用黑色表示;如果频率计数较高,则使用亮红色表示。链接频率计数一般都使用绿色和黄色表示,所有边的粗细度按照其链接频率计数的三倍计算。打印完完整的描述符后,将打印主节点聚类和当前节点聚类之间的链接。
构建图形
在 Linux 上,使用 cat
top10Links |perl buildDot.pl slashdot.org thumbnails > dotFile.slash 命令创建 dot 语法图形文件。在 Window 中,type top10Links |perl buildDot.pl slashdot.org thumbnails > dotFile.slash 命令执行相同的功能。
您现在能够使用 Graphviz 程序执行实际的绘图工作,您所选的呈现算法将显著影响输出结果。只有一种 Graphviz 过滤器(fdp)是专门用来绘制无向图的,但是其他过滤器也能够正确地处理 dotFile.slash 语法。使用 fdp dotFile.slash -Tpng -o graph.png 命令创建位图化的输出。该命令在 Linux 和 Windows 上是相同的。在您的查看器中打开 graph.png 文件,将看到类似图 1 所示的图形。
图 1. 无向图输出
结束语
本文介绍的逻辑步骤和程序为您实现 Web 页面链接可视化提供了一个很好的起点。一定要查看 参考资料 中完整的 Graphviz 文档的链接。您可以阅读有关为节点和边创建可点击的图像地图的内容。定制边的形状、颜色以及图形语法生成步骤中的其他修改,从而增强可视化效果。考虑修改脚本来显示 Web 站点的所有页面,使用亮红色表示访问者可能会访问各种 404 路径。Graphviz 及其处理定向和无向图的过滤器,以及 Perl 强大的文本处理能力是实现可视化的最佳组合。
参考资料 学习
获得产品和技术
讨论
关于作者  | |  | Nathan Harrington 是 IBM 的一位程序员,目前从事 Linux、WatchPad 1.5 和资源定位技术方面的工作。 |
对本文的评价
|