Grab today's news images for your web site or as an RSS feed, suitable for viewing in your favorite syndicated news application . News Wallpaper takes a command-line query and runs it against Yahoo!'s news photo archive, scraping image thumbnails as well as photo information into an RSS feed [Hack #94], which you can then view in an aggregator or add to your own web site [Hack #95]. There are plenty of text RSS feeds available, but this one gives you images to liven up your site and your reader's morning. The CodeSave the following code as wallpaper.pl : #!/usr/bin/perl -w use strict; use LWP::UserAgent; use XML::RSS; use URI; # how many RSS items? my $counterlimit = 10; # prefix for image URLs? # could be file:// or http://. my $url_prefix = " file:///Users/morbus/Desktop/ "; # get our query, else die miserably. my $query = shift @ARGV; die unless $query; # and grab our data. my $ua = LWP::UserAgent->new; my $url = URI->new('http://search.news.yahoo.com/search/news/'); $url->query_form(c => "news_photos", p => $query); my $photosource = $ua->get($url)->content; # if there was no luvin', then no RSS feed. die "There were no results for this search!\n" if $photosource =~ /Sorry, no News Photos Matches/i; # start the RSS feed. my $rss = new XML::RSS (version => '0.91'); $rss->channel( 'link' => $url_prefix, title => "Yahoo! News Photos Wallpaper", description => "News photos matching the keyword '$query'." ); # our counter. my $counter = 0; # get the pictures and descriptions while ($photosource =~ m!hr width=90%.*?<a href="(.*?)"><img src=(.*?) . [RETURN] *?size=2>(.*?)</font>.*?=timedate>.*?</span>!mgis) { last if $counter == $counterlimit; # reached our limit? move on. my ($url, $pictureurl, $desc) = (, , ); unless ($url && $pictureurl && $desc) { next; } # download this picture to the current directory. $ua->get($pictureurl, ':content_file' => "picture$counter.jpg"); # add this item # to our RSS feed. $rss->add_item( title => substr($desc, 0, 75) . "...", 'link' => $url, description => "<img # src=\"${url_prefix}picture${counter}.jpg\"> [RETURN] $desc", ); # NexxTXTt! $counter++; } # and save our RSS. $rss->save("wallpaper.rdf"); Running the HackThis script goes through three stages:
You can run this hack as a client-side applicationsomething to fill out your RSS readeror you can run it as a server application to add some color to your web site. If you run it as a server-side item, you'll want to use something that'll run it regularly; a cron job [Hack #90] to run it every day would work well. Hacking the HackThere are a few ways you can improve upon this hack. Picture limitsThe most obvious change for this hack would be to change how many pictures the script gathers. To do so, change the $counterlimit to whatever you like: # how many RSS items? my $counterlimit = 15; Note that, as a best practice, RSS files generally stay under 15 items. RSS versionRSS wonks will note that the version of RSS used in this script is RSS 0.91. There are two reasons for this. First, it's well-known and supported by all the RSS readers I've ever heard of. Second, for what this script is doing, a version more sophisticated than 0.91 is not required. If you want to use a newer version of RSS, take a look at the XML::RSS documentation at http://search.cpan.org/author/KELLAN/XML-RSS/lib/RSS.pm. Image::SizeAs they are now, you might decide that the pictures in the feed are too large; you may want them, for example, only half this size. You can do just that, thanks to a Perl module called Image::Size (http://search.cpan.org/author/RJRAY/). Use it by adding the following line to the top of the program, along with the other use statements: use Image::Size; Now, as you grab picture URLs, you'll want to glean their sizes: $ua->get($pictureurl, ':content_file' => "picture$counter.jpg"); (my $height, $width) = imgsize("picture$counter.jpg"); Now that you have the sizes, decide how much smaller you want them. How about half their original size? Calculate the new sizes like so: $ua->get($pictureurl, ':content_file' => "picture$counter.jpg"); (my $height, my $width) = imgsize("picture$counter.jpg"); my $newheight = $height/2; my $newwidth = $width/2; Now, all you have to do is add that height and width to your RSS feed. Change the line that creates an RSS description with no size attributes: description => "<img src=\"${url_prefix}picture${counter}.jpg\"> $desc", to this: description => "<img src=\"${url_prefix}picture${counter}.jpg\" height=\ [RETURN] " $newheight\" width=\"newwidth\"> $desc" , This produces the same feed, but with smaller pictures. Note that you're just decreasing the rendered size of the image in your RSS reader, not changing the actual image file itself. If the Image::Magick (http://www. imagemagick .org/www/perl.html) module is installed, you can actually reduce the size of the image file with the following code: use Image::Magick open(JPEG, "<picture$counter.jpg ") or die $!; read(JPEG, my $blob, -s JPEG) or die $!; my $image = Image::Magick->new( ); $image->BlobToImage($blob); $magick->Scale(geometry=>"$newheight x $newwidth"); open(NEW, ">picture$conter.jpg"); print NEW $magick->ImageToBlog( ); close(NEW); |