---
title: "Hämta ut Title ur en HTML fil, går det?"
type: "forum-thread"
url: "https://www.webforum.nu/amne/perl-ruby/142706-hämta-ut-title-ur-en-html-fil-går-det"
topic: "Perl & Ruby"
topic_url: "https://www.webforum.nu/amne/perl-ruby"
author: "haider"
published: "2006-02-19T15:29:27.000Z"
updated: "2006-03-04T01:02:02.000Z"
replies: 17
views: 1802
page: 1
pages: 1
language: "sv-SE"
site: "webForum — webforum.nu"
rights: "Upphovsrätten till varje inlägg tillhör dess författare."
attribution: "Citera som: webForum, https://www.webforum.nu/amne/perl-ruby/142706-hämta-ut-title-ur-en-html-fil-går-det"
---

# Hämta ut Title ur en HTML fil, går det?

## #1 — haider, 2006-02-19T15:29Z

Hej kära tomma Perl-forumet. :-)

Jag har ett attribut som heter **$title =**  och sedan bland annat följande kodsnutt:

```
$query = $ENV{'QUERY_STRING'};
($name, $value) = split(/==/, $query);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
```

genom att printa ut **$FORM{url}** så kan jag få med filnamnet på den fil som anges i query strängen.
Kan man utläsa \<title\> taggen ur samma fil, och använda den till B\]$title =  som jag nämner ovan?

Tacksam för svar - man kan ju alltid hoppas på att det spökar här i CGI-forumet   :p

Permalänk: https://www.webforum.nu/p/142706

## #2 — Jojoxx, 2006-02-20T09:08Z

Nej, du måste först läsa in dokumentet. Kommer du bara åt det via http kan du använda lwp för att läsa det och html::headparser för att läsa i head;

```
use LWP::Simple;
use HTML::HeadParser;
my $p = HTML::HeadParser->new;
$p->parse(get($FORM{'url'}));

print $p->header('Title');
```

... om du har en komplett url i $FORM{'url'}.

Permalänk: https://www.webforum.nu/p/1769821

## #3 — haider, 2006-02-20T18:49Z

Tack Johan! När landet står tomt, så är du den som är kvar o vallar oss vilsna själar till rätta   :p 

Alltså, när du skriver "om du har en komplet url i $FORM{'url'}" - så förutsätter jag att jag får det, när jag har en sökväg i stil med:

<https://www.sidan.se/cgi-bin/link.cgi?url==/en_sida.html>

Eller?

Var någonstans ska jag klämma in din kod i förhållande till:

```
print "Content-type:text/html\n\n";

$query = $ENV{'QUERY_STRING'};
($name, $value) = split(/==/, $query);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;

print "<HTML>\n<HEAD>\n<meta name=\"description\" content=\"$meta_desc\">\n";
print "<meta name=\"keywords\" content=\"$meta_keywords\">\n<TITLE>$title</TITLE>\n</HEAD>\n";
print "<frameset cols=\"*,1000,*\"  frameborder=\"no\" border=\"0\" framespacing=\"0\">\n<frame src=\"\">\n";
print "<frameset rows=\"*,$frame_height\" frameborder=\"no\" border=\"0\" framespacing=\"0\">\n";
print "  <frame src=\"$FORM{url}\" name=\"mainFrame\" scrolling=\"yes\">\n";
print "  <frame src=\"$static_frame\" name=\"bottomFrame\" scrolling=\"No\" noresize=\"noresize\">\n";
print "</frameset>\n<frame src=\"\">\n</frameset>\n";
print "<noframes>\nSorry your browser does not support frames please<a href=\"$FORM{url}\">click here</a>.\n";
print "</NOFRAMES>\n</html>\n\n";

exit;
```

För övrigt, jag är mycket bristfällig i CGI; jag begriper det inte lika mkt som JS:

Angående "print $p-\>header('Title');", betyder det att jag ska strunta i att printa ut \<TITLE\>$title\</TITLE\>

Observera att $title och andra variabler anges lite tidigare i CGI-scriptet i stil med:

```
$title = "En titel";
```

tack för att du tar dig tiden.

Permalänk: https://www.webforum.nu/p/1770035

## #4 — Jojoxx, 2006-02-21T08:29Z

Vi kan ju enklast modifiera mitt exempel så du bara kan lägga in det i din kod:

```
print "Content-type:text/html\n\n";

$query = $ENV{'QUERY_STRING'};
($name, $value) = split(/==/, $query);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;

[b]use LWP::Simple;
use HTML::HeadParser;
my $p = HTML::HeadParser->new;
$p->parse(get($FORM{'url'}));
$title=$p->header('Title');[/b]

print "<HTML>\n<HEAD>\n<meta name=\"description\" content=\"$meta_desc\">\n";
print "<meta name=\"keywords\" content=\"$meta_keywords\">\n<TITLE>$title</TITLE>\n</HEAD>\n";
print "<frameset cols=\"*,1000,*\"  frameborder=\"no\" border=\"0\" framespacing=\"0\">\n<frame src=\"\">\n";
print "<frameset rows=\"*,$frame_height\" frameborder=\"no\" border=\"0\" framespacing=\"0\">\n";
print "  <frame src=\"$FORM{url}\" name=\"mainFrame\" scrolling=\"yes\">\n";
print "  <frame src=\"$static_frame\" name=\"bottomFrame\" scrolling=\"No\" noresize=\"noresize\">\n";
print "</frameset>\n<frame src=\"\">\n</frameset>\n";
print "<noframes>\nSorry your browser does not support frames please<a href=\"$FORM{url}\">click here</a>.\n";
print "</NOFRAMES>\n</html>\n\n";

exit;
```

... och din URL ser komplett ut, antar att du har http:// före.

Permalänk: https://www.webforum.nu/p/1770164

## #5 — haider, 2006-02-22T16:22Z

problem

Du, måste url:en vara helt komplett?
Så som jag körde innan, så räckte det med att URLen var utformad enligt tex: "/dir/file.html" så funkade det i detta sammanhang.

Jag kör alltid den korta versionen, för att spara på adressen.
Kanske ska man skriva in "http://www.domänen.se" manuellt så att den skrivs ut i cgi-scriptet?

För kanske de kommandon du har i din kod kräver en komplett URL?

tillägg: jag får nämligen ett Internal Server Error

Permalänk: https://www.webforum.nu/p/1770679

## #6 — Csson, 2006-02-22T21:55Z

[LWP::Simple](http://search.cpan.org/~gaas/libwww-perl-5.805/lib/LWP/Simple.pm) fungerar ungefär som en webbläsare, det vill säga att den kräver en komplett url.  Om du istället läser in filen i en variabel kan du få \<title\> genom (om $document innehåller hela htmlfilen):

```
my ($title) = $document =~ m{<title>([^<]*?)</title>}i;
```

Permalänk: https://www.webforum.nu/p/1770807

## #7 — haider, 2006-02-22T22:32Z

Csson: Kanske du kan förklara hur jag kombinerar samman din kod med Jojoxx?

Det betyder väl att jag inte kör med  **$title=$p-\>header('Title');**, men att bara ersätta raden med din kod räcker inte heller?

Hur gör man för att foga samman allt?

Permalänk: https://www.webforum.nu/p/1770818

## #8 — Csson, 2006-02-22T22:51Z

Om du i $FORM{'url'} har en fungerande sökväg till en lokal fil kan du byta ut det fetstilta i Jojoxx inlägg från igår till:

```
open my $htmlfile, '<', $FORM{'url'} or die $!;
    my $document = do { local $/; <$htmlfile> };
close $htmlfile or die $!;

my ($title) = $document =~ m{<title>([^<]*?)</title>}i;
```

Helt otestat men det borde funka :).

Permalänk: https://www.webforum.nu/p/1770822

## #9 — Jojoxx, 2006-02-23T08:02Z

> **haider skrev:**
>
> tillägg: jag får nämligen ett Internal Server Error

Det kan vara så att någon av modulerna saknas. Kolla i loggen och se vad du har för felmeddelande.

Tar vi bort HTML::HeadParser (vet inte hur vanlig den är) och kombinerar med Cssons exempel:

```
use LWP::Simple;
my $document = get($FORM{'url'});
my ($title) = $document =~ m{<title>([^<]*?)</title>}i;
```

Permalänk: https://www.webforum.nu/p/1770861

## #10 — haider, 2006-02-25T11:28Z

Jag tror inte jag kan se loggen, för jag har ju mina filer på ett webbhotell. Eller kan jag?

Så snart jag har med raden **use LWP::Simple;** så blir det problem.
Tar jag bort den, så kommer inte "Internal Server Error 500", men det händer heller inte mycket mer.

Jag håller på med en parallell lösning, med JS, kanske kommer jag att satsa på javascript istället.

Permalänk: https://www.webforum.nu/p/1771541

## #11 — Jojoxx, 2006-02-26T09:22Z

Webhotell brukar ge tillgång till loggfiler på olika sätt, vanligast via ftp eller ett admin-interface via http.

Då kan du i princip vara säker på att modulen lwp::simple inte finns installerad. Fråga ditt webhotell om du inte kan lägga till den. Den är rättså smidig att ha.

Permalänk: https://www.webforum.nu/p/1771772

## #12 — haider, 2006-02-26T17:29Z

Eine Idee doch!

Du verkar övertygad, och allt lutar åt det hållet som du nämner.

Men krävs det verkligen att man har lwp::simple installerad?
Om jag som amatör i CGI gör en jämförelse med JS, så kan man ganska lätt lösa title-grejen i JS.

Anledningen till att jag skulle vilja se det lösas i CGi är för att CGI är det som körs allra först.

Förresten, kan CGI avläsa referrer-data och "ta med sig den" vidare så att sidor skapta med CGI (som ovanstående process) kan ta del av referrer datan?

Alltså: position 1, Google \> position 2, en sida, som location.replace-ar till CGI \> position 3, ny sida med komplett frameset.

Jag fick ganska smarta tips av Nitro i JS sidan, men de byggde på att man lassade över referrer datan mellan position 1 o 3 genom att flytta referrer datan upp till URLen. Nu så har jag lagt hans tips på paus, eftersom detta här CGI scriptet inte kan separera URL datan från referrer datan.

Så ser URLen ut med JS lösningen:
www.domain.se/cgi-bin/link.cgi?url==/**sidan.html****&referrer==www.google.se/blah**

Rött är alltså URL datan endast och blått är referrer datan.
Vad scriptet alltså gör, är att klämma in allting i **$FORM{url}** vilket ju inte var tanken.

Så, frågan är om CGI kan läsa ut referrer data...

Permalänk: https://www.webforum.nu/p/1771897

## #13 — Hansen, 2006-02-28T04:55Z

> **haider skrev:**
>
> \[...\] Anledningen till att jag skulle vilja se det lösas i CGi är för att CGI är det som körs allra först.

Tyvärr går det inte att lösa någonting i CGI, CGI är en standard ([RFC 3875](http://www.faqs.org/rfcs/rfc3875.html)) för hur webservar kommunicerar med externa program, inte ett programmerings språk. Perl har inte mer gemensamt med CGI än C, C++, PHP eller andra programmerings språk.

> **haider skrev:**
>
> \[...\] Så, frågan är om CGI kan läsa ut referrer data...

 
Referer fältet är ett standard HTTP huvud fält definierat i [RFC 2616 14.36](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.36). CGI standarden definierar detta fält som ett meta protokoll fält vilket innebär att det ska ha prefixet *HTTP\_* i miljö variabeln.

Notera att det är Referer inte Referrer, detta tack vare en felstavning i en tidigare HTTP specifikation.

```
my $referrer = $ENV{HTTP_REFERER};
```

Permalänk: https://www.webforum.nu/p/1772382

## #14 — haider, 2006-02-28T09:19Z

Tack Hansen.

Angående "Perl har inte mer gemensamt med CGI än ..." - kanske är det jag som i min brist på kunskap uttryckte mig fel? När jag säger "CGI" så menar jag förstås Perl, för det är väl alltid perl som används i script med ändelsen .pl, eller? Eller är det två skilda saker?

Angående:

```
my $referrer = $ENV{HTTP_REFERER};
```

Då betyder det att perl/cgi (herregud, nu vet jag inte vad jag ska kalla det för :) ) klarar att läsa ut referern (med ett R alltså)?
Eftersom scriptet skapar en ny sida, en sida med ett frameset - Isåfall, kan man på nåt sätt göra så att den referer som utlästes tidigare blir den skapta sidans referer? Så att ett js-script som kör "document.referrer" läser ut den datan?

Om du har en möjlighet att berätta för mig hur koden ser ut, så vore jag mycket tacksam, så kan jag bara implentera den i cgi-scriptet ovan.

Permalänk: https://www.webforum.nu/p/1772414

## #15 — Hansen, 2006-02-28T18:24Z

> **haider skrev:**
>
> \[...\] När jag säger "CGI" så menar jag förstås Perl

Det är inte ovanligt att dessa två blandas ihop, många tror att CGI är Perl och tvärtom, men det är fel. Som sagt tidigare CGI är simpel standard för hur webservern kommunicerar med externa program med hjälp av miljö variabler, standard input, standard output och standard error. Det går alldeles utmärkt att skapa CGI program med Perl, vilket du redan har gjort.

```
                HTTP                   CGI
+-----------+          +-----------+         +---------+
|           | -------> |           | ------> |         |
| webläsare |          | webserver |         | program |
|           | <------- |           | <------ |         |
+-----------+          +-----------+         +---------+
```

Webläsaren skickar en HTTP begäran till servern som omvandlar denna till en CGI begäran vilket programmet bearbetar enligt CGI standarden. Programmet svarar med en CGI respons som webservern omvandlar till en HTTP respons som webläsaren svaras med.

> **haider skrev:**
>
> \[...\] för det är väl alltid perl som används i script med ändelsen .pl, eller? Eller är det två skilda saker?

Perl program/script associeras ofta med filändelserna *pl*, *plx*, *cgi* och moduler med *pm*.

*cgi* används om det är ett CGI program, detta för a webservern ska kunna "veta" att det är ett program som "förstår" CGI. Värt att påpeka att *cgi* filändelsen inte är unik för Perl utan delas med alla programmerings språk.

> **haider skrev:**
>
> \[...\]Då betyder det att perl/cgi (herregud, nu vet jag inte vad jag ska kalla det för :) ) klarar att läsa ut referern (med ett R alltså)?

Korrekt :)

> **haider skrev:**
>
> Eftersom scriptet skapar en ny sida, en sida med ett frameset - Isåfall, kan man på nåt sätt göra så att den referer som utlästes tidigare blir den skapta sidans referer? Så att ett js-script som kör "document.referrer" läser ut den datan?
> 
> 
> Om du har en möjlighet att berätta för mig hur koden ser ut, så vore jag mycket tacksam, så kan jag bara implentera den i cgi-scriptet ovan.

Visst kan jag hjälpa dig, men fört måste jag förstå vad du vill åstadkomma. Ta två steg tillbaka och förklara vad du vill åstadkomma istället för peka ut ett specifikt del problem.

Permalänk: https://www.webforum.nu/p/1772617

## #16 — haider, 2006-02-28T19:54Z

Hansen; tack för ditt schyssta svar. Tack för att du tog tid tiden. Nå, detta var långt större än jag trott, men din förklaring kastar lite ljus på problemet.

I grund och botten så ser problemet ut såhär:
På grund av ett system som jag använder till en webbshop tvingades jag byta över till framesystem. Webbshopmekanismen klarade inte att lagra köpen i cookies eller motsvarande, därför fick man inte lov att ladda om sidan (och shoppen) för då skulle varukorgen tömmas.
Så jag bytte alltså till frames.

Frames ledde till ett annat bekypper, men sökmotoroptimering och annat.
När en besökare går in i en sida som i själva verket ska finnas i ett frameset, så körs ett javascript. En if-sats som gör if self.location == top.location, så ersätts location med:

<https://www.sidan.se/cgi-bin/link.cgi?url==/sidan.html>

På så vis skapar scripet (sorry, men jag fattar tyvärr fortfarande inte till 100 om min ovanstående lösning är perl eller cgi   :r ) en framemiljö och klämmer in sidan som angivits i URLen i någon av src (det framgår i scriptet som du säkert sett).

Tracker/statistics till sidan: En normal "Entry" in till sidan genom index-filen, är inte nåt problem för trackern, för jag kan ta fram referrern åt tracking-sciptet genom att läsa in det med parent.document.referrer (javascript).

Däremot, om jag kör CGI-sciptet och på ett visuellt sätt skapar ett frameset, så funkar inte parent längre, eftersom processen ser ut så:

1\. Webben/google
2\. Sida utanför frame  (innehåller referrer-data), javascript körs för att anropa CGI-scriptet
3\. framesettet färdigbyggt och sidan ligger tillrätta inne i någon frame

Lösningen rent teoretiskt skulle kunna vara att jag vid punkt 2, när jag kör CGI-scriptet, så lagrar CGI-scriptet referrer data som den "spottar" ut vid punkt 3, så att man vid punkt3 åter kan komma åt referrer med javascript.

Om du kan JS så kan du titta här för lite bakgrundsinfo som en parantes:
<http://www.webforum.nu/showthread.php?p=1160307#post1160307>
Här har Nitro gett mig ett tips där man ur URLen kan bryta ut information som man "gör om" till referrer-data.
Han hade med ett JS som jag inte testat ännu (pga en brist i mitt CGI script (jag kan berätta om problemet om du vill)) men jag gissar att det är till för att läsa ut data ur querysträngen.

Om teorin funkar, att man kan "lassa över" referrer-data så som jag beskriver, så bör det väl funka att läsa ut den med gammal hederlig document.referrer i javascript?
Om det går - gör det det? Det är du som är experten. Jag är bara en teknikgalning som oftast letar efter de mest dramatiska lösningar (tar mig vatten över huvudet   ;) )

Snälla, skriv om jag är helt otydlig, eller nåt.

Permalänk: https://www.webforum.nu/p/1772688

## #17 — Hansen, 2006-03-01T19:53Z

Testa med detta scriptet:

```
#!/usr/bin/perl

use strict;
use warnings;

use CGI;

my $cgi     = CGI->new;
my $url     = $cgi->param('url')     || 'Inte angiven';
my $referer = $cgi->param('referer') || 'Inte angiven';

print $cgi->header( -type => 'text/html' );
print <<EOF;
<html>
  <head>
    <title>Testar CGI.pm</title>
  </head>
  <body>
     <p>url: $url</p>
     <p>referer: $referer</p>
  </body>
</html>
EOF
```

Anropa scriptet med något liknande: 

```
http://host/cgi-bin/script.cgi?url=%2Fen_sida.html&referer=http%3A%2F%2Fwww.webforum.nu%2F
```

Det är viktigt att urlen är rätt kodad, använd JavaScripts [encodeURI](http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Functions:encodeURI).

Något kortfattat svar, men har tyvärr lite bråttom. Testa och fråga om du undrar något eller stöter på problem.

Permalänk: https://www.webforum.nu/p/1776027

## #18 — haider, 2006-03-04T01:02Z

Jag fick det inte att funka.
Kan det vara så att dessa rader kräver nåt slags "tillägg" till CGI, precis som Jojoxx nämner en saknad modul tidigare?

```
use strict;
use warnings;

use CGI;
```

Nu fick jag visserligen inte riktigt svar på mina funderingar, om hurvida cgi/perl klarar av att ta en referrer (som man med javascript kan utläsa) och gör den tillgänglig "flera sidor senare", så att man återigen kan utläsa med javascript.

I väntan på att ovanstående besvaras (vare sig det går eller inte), så undrar jag hur detta kan lösas:

När sökvägen ser ut så här:
**<https://www.domain.se/cgi-bin/link.cgi?url==/sidan.html&referrer==www.google.se/blah>**
Så blir det problem med denna raden:

```
print "  <frame src=\"$FORM{url}\" name=\"mainFrame\" scrolling=\"yes\">\n";
```

eftersom $FORM{url} får strukturen "**/sidan.html&referrer==www.google.se/blah**" när jag endast behöver ha "**/sidan.html**".

Äni idea? Men om det går, så hjälp mig med ett förslag som inte ställer krav på moduler eller liknande...   :r

Permalänk: https://www.webforum.nu/p/1776802

---

Tråden på webben: https://www.webforum.nu/amne/perl-ruby/142706-hämta-ut-title-ur-en-html-fil-går-det
