Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

OPPS - Grab weather from yahoo (2)

by scribe (Initiate)
on May 24, 2000 at 10:18 UTC ( #14511=sourcecode: print w/ replies, xml ) Need Help??

Category: Utility / Web
Author/Contact Info scribe@ziplip.com
Description: Grabs weather from yahoo. One of my first perl scripts
and my first use of IO::Socket. It could use some work
but I only use it as part of an efnet bot.
#!/usr/bin/perl

use IO::Socket;

if ($#ARGV < 0) { die "usage: weather.pl <zipcode | city>\n"; }

$server = 'search.weather.yahoo.com';
$serverPort = '80';
$get = '/weather/query.cgi?q=';

$zipcode = $ARGV[0];

$remote = new IO::Socket::INET (
                  Proto=>'tcp',
                  PeerAddr=>$server,
                  PeerPort=>$serverPort,
                  Reuse=>1 ) or die $!;

$remote -> autoflush(1);

print $remote "GET $get"."$zipcode HTTP/1.0\n\n";

while ( $location = <$remote>) {
  if ( $location =~ /Location:/ ) {
    $redir = $location;
    $redir =~ s/Location: //;
  }
}

close $remote;

if ($redir eq '') {
  print "Sorry, unable to gather weather data for $zipcode\n";
  exit;
}

@temp = split(/\//, $redir);
$server = $temp[2];
$get = "\/"."$temp[3]"."\/"."$temp[4]";

$remote = new IO::Socket::INET (
                  Proto=>'tcp',
                  PeerAddr=>$server,
                  PeerPort=>$serverPort,
                  Reuse=>1 ) or die $!;

$remote -> autoflush(1);

print $remote "GET $get HTTP/1.0\n\n";

while ( $raw = <$remote>) {

  if ($raw =~ /Appar Temp:/) {
    $temp = $raw;
  } elsif ($raw =~ /Humidity:/) {
    $humidity = $raw;
  } elsif ($raw =~ /Wind:/) {
    $wind = $raw;
  } elsif (($raw =~ /^<font size=\"-2\" face=\"arial\">.+<\/font><\/td
+>$/) && ($condFound ne 1)) {
    $conditions = $raw;
    $condFound = 1;
  } elsif ($raw =~ / Forecast<\/title>/) {
    $city = $raw;
  }

}

close $remote;

$conditions =~ s/^<font size=\"-2\" face=\"arial\">//;
$conditions =~ s/<\/font><\/td>$//;
chomp $conditions;

$temp =~ s/<tr><td><font size=-1>//;
$temp =~ s/<\/font><\/td>//g;
$temp =~ s/<td><font size=-1>//;
$temp =~ s/<\/tr>//;
$temp =~ s/:/: /;
$temp =~ s/Appar //;
$temp =~ s/&#176\;/ degrees/;
chomp $temp;

$humidity =~ s/<tr><td><font size=-1>//;
$humidity =~ s/<\/font><\/td>//g;
$humidity =~ s/<td><font size=-1>//;
$humidity =~ s/<\/tr>//;
$humidity =~ s/:/: /;
$humidity =~ s/% /%/;
chomp $humidity;

$wind =~ s/<tr><td><font size=-1>//;
$wind =~ s/<\/font><\/td>//g;
$wind =~ s/<td><font size=-1>//;
$wind =~ s/<\/tr>//;
$wind =~ s/&nbsp\;/ /;
$wind =~ s/:/: /;
chomp $wind;

$city =~ s/<title>//;
$city =~ s/<\/title>//;
$city =~ s/Weather Forecast//;
chomp $city;

print "Weather for $city(( $temp $humidity ) ( $conditions $wind ))\n"
+;

Comment on OPPS - Grab weather from yahoo (2)
Download Code
RE: OPPS - Grab weather from yahoo (2)
by Adam (Vicar) on May 24, 2000 at 20:55 UTC
    This worked really well the first time. Then I ran it again with a different zip code and it crashed thusly:
    IO::Socket::INET: Bad peer address at D:\FileBin\weather.pl line 36
    Bad file descriptor at D:\FileBin\weather.pl line 36.
    
    Line 36 is this one:$remote = new IO::Socket::INET ((I think)
      I believe this is caused when yahoo splits that
      zipcode / city up into differnt weather reports or
      the city is found in multiple states.

      On yahoo's site it lists options of differnt locations
      in such instances and the users is expected to drill down
      by clicking one of the links.

      I've added an if statement to make it quit nicely.
      Maybe I'll reqrite it using one of the modules KM has
      pointed out.

      -scribe
RE: OPPS - Grab weather from yahoo (2)
by KM (Priest) on May 24, 2000 at 21:01 UTC
      I used one of the CPAN weather grabbers with mixed results.

      Often the ports would time out when I used the module as written.

      My solution was to dupe the .pm and localize it to pull only from the Los Angeles NOAA station instead of the central/national one. This one had a lot less traffic, and I haven't seen any lost results since I made the switch.

      In case anyone is interested, I modified Geo::WeatherNOAA as Geo::LAWeatherNOAA.
      In the subroutine get_city_zone I changed my $URL = $URL_BASE . lc $state . '/zone.html'; to my $URL = 'http://www.nwsla.noaa.gov/zones/LAXZFPLOX'; and that took care of just about everything.

Back to Code Catacombs

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://14511]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2014-10-26 07:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (152 votes), past polls