[perl] hoe: een plaatje van internet downloaden en opslaan?

Pagina: 1
Acties:

  • Algurgazan
  • Registratie: Juli 2002
  • Laatst online: 09-04 13:59
ik moet voor een opdracht met perl een plaatje van internet downloaden en locaal saven, dmv de net:http module. nou ben ik absoluut niet bekend met perl, en dus is er een vraag gerezen, waar ik het antwoord maar niet op kan vinden.

het punt is dat niet alleen het plaatje opgeslagen wordt, maar in de file ook de http headers enzo komen te staan, en ik kan maar niet vinden hoe ik die daar makkelijk weg kan krijgen.. scriptje ziet er ongeveer zo uit:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$p = &getHttp("host", "url");

open (OUTFILE, ">file.jpg");
print OUTFILE $p;
close (OUTFILE);

sub getHttp {
    use Net::HTTP;

    $s = Net::HTTP->new(Host => $_[0]) || die "couldnt connect";
    $s->write_request(GET => $_[1],  'User-Agent' => "Mozilla/5.0");

    $page = "";

    while (1) {
        $n = $s->read_entity_body($buf, 1024);
        die "read failed: $!" unless defined $n;
        last unless $n;
        $page = $page.$buf
    }
    return $page;
}

"When you hear the beeb, it will be three o'clock." | muzak


  • muba
  • Registratie: April 2002
  • Laatst online: 19-10-2013

muba

Prince of Persia!

Hmm, bekijk het binnengehaalde bestand eens goed... Wat valt je op aan de HTTP headers?
Hoe worden de HTTP headers gescheiden van het werkelijke bestand (zoek ook ff op internet hoe HTTP werkt)...

En dan strip je gewoon het kenmerkende gedeelte voor headers weg. Regular expressions, split(), naar tijdelijk bestand schrijven en dan de header lines lezen en discarden... tal van mogelijkheden.

Bovendien is er mogelijk een header die zegt content-length: xxx. Als je die nou weet te extracten kun je gewoon xxx bytes vanaf het einde richting het begin nemen, dan heb je de hele afbeelding als het goed is.

Reporter: Mister Gandhi, what do you think of western civilisation?
Gandhi: I think it would be a good idea


  • Algurgazan
  • Registratie: Juli 2002
  • Laatst online: 09-04 13:59
hmm wat ik heb kunnen vinden is dat die headers altijd eindigen met een lege regel.. dus wat ik geprobeerd heb is alles na die lege regel opslaan, want dan zou ik het plaatje moeten hebben.. en dat heb ik op deze manier geprobeer:

code:
1
2
3
4
5
6
7
8
$p = &getHttp("host", "path");

if ($p =~ /(.*?)\n\n(.*?)/)
            {$p = $2}

open (OUTFILE, ">plaatje.jpg");
print OUTFILE $p;
close (OUTFILE);


maar als ik dat doe krijg ik een leeg bestand, dus dat gaat ook niet goed helaas.. komt dat omdat ik andere tekens moet gebruiken ipv \n ??

"When you hear the beeb, it will be three o'clock." | muzak


  • muba
  • Registratie: April 2002
  • Laatst online: 19-10-2013

muba

Prince of Persia!

Zoals ik het zie zou het moeten werken zo. Maar probeer het eens anders...
Perl:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!usr/bin/perl

use strict;
use warnings;

#...
#...
#...

my $p = &getHttp("host", "path") or die "getHttp returned empty value";

($p) = $p =~ m/.+?\n\n(.+)/;

open OUTFILE, ">plaatje.jpg" or die "Could not open plaatje.jpg for output: $!";
print OUTFILE $p;
close OUTFILE or die "Could not close plaatje.jpg (opened for output): $!";


Dat is in elk geval duidelijker.
Met strict en warnings word je ook nog eens op de hoogte gehouden van fouten of andere minder plezante dingetjes.
En met die or die stukjes kapt het script er gewoon mee als er iets niet goed gaat. Makkelijker debuggen!

Reporter: Mister Gandhi, what do you think of western civilisation?
Gandhi: I think it would be a good idea


  • Algurgazan
  • Registratie: Juli 2002
  • Laatst online: 09-04 13:59
hmm heb het opgelost.. door dit:

code:
1
my($code, $mess, %h) = $s->read_response_headers;


toe te voegen aan de getHttp sub kreeg ik de headers er niet meer bij... bedankt voor de hulp!

"When you hear the beeb, it will be three o'clock." | muzak