Hallo Sascha.
$html =~ m/<body.*>(.*)</body>/si; # Hier ist der Fehler versteckt
Dein Ausdruck ist im untechnischen Sinne zu gierig. Wie dir Matti bereits antwortete, entspricht es deinem Suchmuster ".*", dass alles bis zum Ende erfasst wird, egal, was da steht. Ergo liefert dir "<body.*>" bereits den gesamten restlichen Inhalt, $1 muss also logischerweise leer sein. Du könntest diesen Fehler ausschließen, indem du ein genügsameres Suchmuster verwendest:
http://selfhtml.teamone.de/cgiperl/sprache/regexpr.htm#gierig_genuegsam
Also etwa so: "<body.+?>". Damit hättest du aber ein zweites Problem, denn der Klammerausdruck muss ja gierig sein, damit er alles bis zum Ende erfasst. Alles in allem deshalb auch von mir der Tipp, einen HTML-Parser zu verwenden, z.B. das bei Perl 5.8.0 standardmäßig verfügbare Modul HTML::Parser:
http://www.perldoc.com/perl5.8.0/lib/HTML/Parser.html
Grüße
Siechfred