Webkorpora: Yahoo API og perl Jakob Halskov jh.id@cbs.dk Ph.d.-studerende Terminologi og korpuslingvistik den 21. februar 2006 1. Hvad er et API? 2. Hent din egen udviklernøgle! 3. Gennemgang af koden 4. Udvidelse af koden 5. Øvelser
Hvad er et API? Application Programming Interface the interface that a computer system, library or application provides in order to allow requests for service to be made of it by other computer programs, and/or to allow data to be exchanged between them. (wikipedia.org) In short, an API can be thought of as a company's internal telephone book with descriptions of key personnel's titles and job descriptions where you (the outsider) are free to call those people up to do your bidding. (John Maeda, MIT Media Lab) Yahoos web search API: en slags filter som definerer og begrænser vores adgang til at bruge søgemaskinen i vores egne programmer
Yahoos API'er map API, weather API, music API,... Yahoo Search Web Services API Hvad kræver det? En application ID (= en Yahoo! konto) Et par perl moduler a) enten Yahoo::Search (fra http://developer.yahoo.net/download/) b) eller LWP::Simple og XML::SIMPLE (fra www.cpan.org)
Få din egen udviklernøgle! 1. Gå til http://developer.yahoo.net/search 2. Get an application ID 3. Sign up (for at få en Yahoo! ID) 4. Find en ledig Yahoo! ID og udfyld formularen 5. Find en ledig application ID 6. Tjek din mailbox og bekræft registreringen
Gennemgang af koden (løsning b) NB: koden stammer fra Yahoo! Hacks (O'Reilly) - www.oreilly.com/catalog/yahoohks/chapter/hack68.pdf #!/usr/bin/perl -w use strict; #Alle variable skal erklæres med local scope! Besværligt, men sund praksis. use LWP::Simple; use XML::Simple; # Set your unique Yahoo! Application ID my $appid = "XXXXXXXX"; # Grab the incoming search query my $query = join(' ', @ARGV) or die "Usage: yahoo_search.pl <query>\n";
Koden (løsning b) # Construct a Yahoo! Search Query with only required options my $req_url = "http://api.search.yahoo.com/"; $req_url.= "WebSearchService/V1/webSearch?"; $req_url.= "appid=$appid"; $req_url.= "&query=$query"; $req_url.= "&language=en"; $req_url.= &results=10 ; $req_url.= &format=any ; basis URL søgeparametre # Make the request my $yahoo_response = get($req_url); #konstruér et XML-Simple-objekt my $xmlsimple = XML::Simple->new( ); #invokér metoden XMLin på objektet, xml -> en kompleks datastruktur my $yahoo_xml = $xmlsimple->xmlin($yahoo_response);
Koden (løsning b) # Initialize results counter my $i; # Loop through the items returned, printing them out foreach my $result (@{$yahoo_xml->{result}}) { $i++; my $title = $result->{title}; my $summary = $result->{summary}; my $url = $result->{url}; print "$i. $title\n$summary\n$url\n\n"; } #kompleks datastruktur #forklaring følger...
Eksempel på programoutput
Hvad indeholder $yahoo_response? <?xml version="1.0" encoding="utf-8"?> <ResultSet xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns="urn:yahoo:srch" xsi:schemalocation="urn:yahoo:srch http://api.search.yahoo.com/websearchservice/v1/websearchresponse.xsd" totalresultsavailable="12900000" totalresultsreturned="20" firstresultposition="1"> <Result> <Title>Fortinet Remote VPN Fortinet Remote VPN Fortinet Remote VPN Fortinet Remote VPN Client V1.4 Client V1.4 Client V1.4 </Title> <Summary>Fortinet Remote VPN. Fortinet Remote VPN. Fortinet Remote VPN. Fortinet Remote VPN. Client V1.4. Client V1.4. Client V1.4. Client V1.4. User Manual. User Manual. User Manual. User Manual. Fortinet Inc. Copyright 2002 Fortinet Inc. All rights reserved. </Summary> <Url>http://www.fortinet.com/doc/vpn/FortinetRemoteVPNClientUserManual.pdf </Url> <ClickUrl>http://www.fortinet.com/doc/vpn/FortinetRemoteVPNClientUserManual.pdf#search='' </ClickUrl> <ModificationDate>1039593600 </ModificationDate> <MimeType>application/pdf </MimeType> <Cache> <Url>http://66.218.69.11/search/cache?appid=terminoweb&query=client&language=en&results=20&format=&u=w ww.fortinet.com/doc/vpn/fortinetremotevpnclientusermanual.pdf&w=client&d=towy8m1amsld&icp=1&.intl=us </Url> <Size>1965039 </Size> </Cache> </Result> <Result>...
Hvad så med $yahoo_xml? $yahoo_xml er en scalar som indeholder en reference til en hash Hashens nøgle-værdi-par svarer til XML'ens øverste niveau: while ((my($k,$v)) = each %{$yahoo_xml}){ print $k, " => ", $v, "\n"; } firstresultposition => 1 xmlns => urn:yahoo:srch Result => ARRAY(0x83cdc38) totalresultsreturned => 10 xmlns:xsi => http://www.w3.org/2001/xmlschema-instance totalresultsavailable => 615000000 xsi:schemalocation => urn:yahoo:srch http://api.search.yahoo.com/...xsd
Kort om referencer Hvad er referencer?
Referencer og komplekse datastrukturer Referencer bruges i perl til indlejring af datastrukturer Referencer er scalars som skal pakkes ud for at tilgå de faktiske datastrukturer de refererer til (~pointers i C). @en_array = ( det, er, lidt, tricky ); $en_anden_array[0] = @en_array; print $en_anden_array[0]; #output er 4! PROBLEM: elementer i lister skal være scalars! LØSNING: erklær en reference til array1, gem den i en scalar og put den så i array2! $array_ref = \@en_array; $en_anden_array[0] = $array_ref;
Pile og Tuborg $en_anden_array[0] = $array_ref; print $en_anden_array[0]; #output er ARRAY(0x814e630) #Pak referencen ud med Tuborg-klammer print @{$en_anden_array[0]}; #output er deterlidttricky print ${$en_anden_array[0]}[0]; #output er det LETTERE SYNTAKS: ${$en_anden_array[0]}[0] er det samme som $en_anden_array[0]->[0]
Hvad indeholder @{$yahoo_xml{result}} så? $yahoo_xml: reference til en hash med 7 nøgler my %yahoo_xml = %{$yahoo_xml}; #1. udpakning @{$yahoo_xml{result}}: værdien af nøglen er en reference til en array som indeholder referencer til 10 hashes (standard antal søgeresultater) foreach my $element (@{$yahoo_xml{result}}){ print $element, ; } #2. udpakning HASH(0x864da3c) HASH(0x864da48) HASH(0x864db68) HASH(0x864e354) HASH(0x864dc34)...
Hvad er der i de 10 hashes? foreach my $hash_ref (@{$yahoo_xml{result}}){ while ((my($k,$v) = each %{$hash_ref}){ print $k, =>, $v, \n ; } print \n ; } #3. udpakning MimeType => text/html Cache => HASH(0x8649334) ModificationDate => 1139126400 #antal sekunder siden 1. januar 1970! ClickUrl => http://httpd.apache.org/ Url => http://httpd.apache.org/ Summary => Effort to develop and maintain an open-source HTTP server for modern operating systems including UNIX and Windows NT. Title => Apache HTTP Server Project MimeType => text/html Cache => HASH(0x8649334) ModificationDate => 1139126400...
Næste gang: Udvidelse af koden Mål: vi vil ikke kun printe dokumenternes titler og summaries, men selve den tekstressource som URL'erne peger på.... open (KORPUS, >>webkorpus_om_$query ); #bruge file handles foreach my $result (@{$yahoo_xml->{result}}) { $i++; my $title = $result->{title}; my $url = $result->{url}; print KORPUS TITEL: $title\nurl: $url\ntekst:\n\n ; if ($url =~ /\.pdf$/) {... } #bruge pdftotext hvis PDF else { print KORPUS `lynx -dump -nolist $url`; } #konvertere med lynx... }
Øvelser Hent en udviklernøgle, download scriptet yahoo_api_orig.pl og indsæt nøglen. Find 5 relevante dokumenter om navigationsstruktur ved at køre scriptet og kigge på resultaterne Tilpas søgningen ved at stille på de to søgeparametre, format (fx. pdf) og results (max 100) Eksperimentér evt. med flere søgeparametre fra http://developer.yahoo.net/search/web/v1/websearch.html