Accessing MSN Search Web Service from Perl

I've been trying to build a MSN Search API client with Perl using SOAP::Lite to interface with the SOAP server. I'm not an expert using Perl or SOAP so any help would be appreciated.

Perl Code

use SOAP::Lite +trace;
my $appID = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
my $msn = SOAP::Lite->service( 'http://soap.search.msn.com/webservices.asmx?wsdl' );
my $response = $msn->Search( (
'Request' => (
'AppID' => $appID,
'Query' => 'xbox',
'CultureInfo' => 'en-US',
'SafeSearch' => 'Off',
'Requests' => (
'SourceRequest' => (
'Source' => 'Web',
'Offset' => 0,
'Count' => 10,
'ResultFields' => 'All' ) ) ) ) );

XML Request

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<Search xmlns="">
<parameters>Request</parameters>
<c-gensym4 xsi:type="xsd:string">AppID</c-gensym4>
<c-gensym6 xsi:type="xsd:string">216E46FB39A188C9863A21371B087D82D6B74B23</c-gensym6>
<c-gensym8 xsi:type="xsd:string">Query</c-gensym8>
<c-gensym10 xsi:type="xsd:string">xbox</c-gensym10>
<c-gensym12 xsi:type="xsd:string">CultureInfo</c-gensym12>
<c-gensym14 xsi:type="xsd:string">en-US</c-gensym14>
<c-gensym16 xsi:type="xsd:string">SafeSearch</c-gensym16>
<c-gensym18 xsi:type="xsd:string">Off</c-gensym18>
<c-gensym20 xsi:type="xsd:string">Requests</c-gensym20>
<c-gensym22 xsi:type="xsd:string">SourceRequest</c-gensym22>
<c-gensym24 xsi:type="xsd:string">Source</c-gensym24>
<c-gensym26 xsi:type="xsd:string">Web</c-gensym26>
<c-gensym28 xsi:type="xsd:string">Offset</c-gensym28>
<c-gensym30 xsi:type="xsd:int">0</c-gensym30>
<c-gensym32 xsi:type="xsd:string">Count</c-gensym32>
<c-gensym34 xsi:type="xsd:int">10</c-gensym34>
<c-gensym36 xsi:type="xsd:string">ResultFields</c-gensym36>
<c-gensym38 xsi:type="xsd:string">All</c-gensym38>
</Search>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

XML Response

<?xml version="1.0" encoding="utf-8" ?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Client</faultcode>
<faultstring>Client Error</faultstring>
<detail>Invalid request</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>

As you can see, I'm getting an INVALID REQUEST. Does anyone have a working Perl example? Thanks.

[3427 byte] By [Daniel2005] at [2008-1-26]
# 1
From another thread here found a useful SOAP example request.
from http://www.richardkmiller.com/files/msnsearch_nusoap.html
As I code in Visual Foxpro - once you have a good example of what it should look like hopefully you can make perl produce it (sorry dont use perl so cannot give any more help).

The example below was changed to replace ;

MSN_SEARCH_API_KEY
SEARCHTERM
RESULTCOUNT

and it worked fine, when SOAP URL of
"http://soap.search.msn.com/webservices.asmx?wsdl"
used.

Stephen
<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body><ns3849:Search xmlns:ns3849="http://tempuri.org">
<Request><AppID xsi:type="xsd:string">MSN_SEARCH_API_KEY</AppID>
<Query xsi:type="xsd:string">SEARCHTERM</Query>
<CultureInfo xsi:type="xsd:string">en-US</CultureInfo>
<SafeSearch xsi:type="xsd:string">Strict</SafeSearch>
<Flags xsi:type="xsd:string"></Flags>
<Location xsi:type="xsd:string"></Location>
<Requests><SourceRequest><Source xsi:type="xsd:string">Web</Source>
<Offset xsi:type="xsd:int">0</Offset>
<Count xsi:type="xsd:int">RESULTCOUNT</Count>
<ResultFields xsi:type="xsd:string">All</ResultFields>
</SourceRequest></Requests></Request></ns3849:Search></SOAP-ENV:Body>
</SOAP-ENV:Envelope>

StephenW at 2007-9-9 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Search: Development...
# 2
Yeah. It isn't a particularly good way, but it seems to work. Instead of using the Perl return data structure I parse the XML directly with XML::Simple. This should print the title, url and description for each return.
#!/usr/bin/perl
use SOAP::Lite;
use XML::Simple;
my $xml = << "END";
<Request>
<AppID xsi:type="xsd:string" >you app id</AppID>
<Query xsi:type="xsd:string" >your query</Query>
<CultureInfo xsi:type="xsd:string" >en-US</CultureInfo>
<SafeSearch xsi:type="SafeSearchOptions" >Moderate</SafeSearch>
<Flags xsi:type="SearchFlags" >None</Flags>
<Location>
<Longitude xsi:type="xsd:double" />
<Radius xsi:type="xsd:double" />
</Location>
<Requests>
<SourceRequest>
<Source xsi:type="SourceType" >Web</Source>
<Offset xsi:type="xsd:int" />
<Count xsi:type="xsd:int" />
<ResultFields xsi:type="ResultFieldMask" >All</ResultFields>
</SourceRequest>
</Requests>
</Request>
END
my $elem = SOAP::Data->type('xml' => $xml);
my $som = SOAP::Lite
->outputxml(true)
-> uri('http://schemas.microsoft.com/MSNSearch/2005/09/fex/Search')
-> proxy('http://soap.search.msn.com:80/webservices.asmx')
-> Search($elem);

my $ref = XMLin($som);
my $results = $ref->{'soapenv:Body'}->{'SearchResponse'}->{'Response'}->{'Responses'}->{'SourceResponse'}->{'Results'}->{'Result'};
my $result_count = $ref->{'soapenv:Body'}->{'SearchResponse'}->{'Response'}->{'Responses'}->{'SourceResponse'}->{'Total'};
my ($description, $title, $url);
foreach my $result (@$results){
$description = $result->{'Description'};
$title = $result->{'Title'};
$url = $result->{'Url'};
print "$title\n";
print "$url\n";
print "$description\n\n";
}

Matthewsnape at 2007-9-9 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Search: Development...
# 3
So, my script works perfectly. I get back proper results for every query ... but I noticed something weird, I always get back 0 results for the query "xbox". Does this happen to anyone else?
Daniel2005 at 2007-9-9 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Search: Development...
# 4
How does one specify the count and offset for each query?

sgollapu at 2007-9-9 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Search: Development...
# 5
Like so:

<SourceRequest>
<Source xsi:type="SourceType" >Web</Source>
<Offset xsi:type="xsd:int" > OFFSET </Offset>
<Count xsi:type="xsd:int" > RESULTS_PER_QUERY </Count>
<ResultFields xsi:type="ResultFieldMask" >All</ResultFields>
</SourceRequest>

fmccown at 2007-9-9 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Search: Development...
# 6
Can you send me the fully working code? I can't get it to work, and when I try some of the examples on this page I get the same "client error" that you originally posted about.

You can email me at

nospam [[at]] inblosam dot com

Thanks!!

inblosam at 2007-9-9 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Search: Development...

Windows Live Developer Forums

Site Classified