1つの.Netプロジェクトで作業する過程で、特定のリクエストのYandex検索結果を取得する必要がありました。 この記事では、.Net環境からYandex APIを使用した経験についてお話します。
もちろん、最初は自分でYandex APIラッパーを実装したくありませんでした(誰かが私の前にすでにこれを行っていたことを望みました)。いや その結果、Yandex APIのドキュメントはパブリックドメインであり、非常に詳細であるため、私は自分で作成するしかありませんでした。
Yandex.XMLサービスは、検索クエリを受け入れ、検索結果と共にXML応答を返します。 これを使用するには、Yandexで標準登録を行い、アクセスキーを取得する必要があります。 キーは、受信したユーザーのIPに厳密に関連付けられていることに注意してください。 1日あたりのリクエスト数の制限は最初は10ですが、電話番号を確認すると1000に増えます。
キーを受信した後、タスクは2つの段階に分割されました:要求の送信とYandex.XMLからの応答の受信、およびこの回答の解析。
リクエスト構造
Yandex.XMLにリクエストを行うには、このリクエストがどの要素で構成されているかを理解する必要があります。
< query > - .
< sortby > - :
< rlv > - ,
< tm > - .
< maxpassages > - ( - 5, -2).
< groupings > - < groupby > .
< groupby > - , :
< attr = > - , :
< d > - .
<> - .
< mode = > - :
< flat > - .
< deep > - .
< groups-on-page = > - ( 100).
< docs-in-group = > - .
* This source code was highlighted with Source Code Highlighter .
リクエストの構造を整理しました。今度はリクエストを送信します。 これを行うには、POSTメソッドとGETメソッドの2つの方法があります。 それぞれについて個別に説明します。
投稿方法
postメソッドの本質は、要求がXML形式で生成され、ストリームに書き込まれ、サービスに送信されることです。 根拠にならないように、上記が発生するコードを提供します。
ServicePointManager.Expect100Continue = false ;
/* , IP,
API.*/
string url = @"http://xmlsearch.yandex.ru/xmlsearch?
user=**********&
key=**********************************" ;
// XML
string command =
@"<?xml version=" "1.0" " encoding=" "UTF-8" "?>
<request>
<query>- </query>
<groupings>
<groupby attr=" "d" "
mode=" "deep" "
groups-on-page=" "10" "
docs-in-group=" "1" " />
</groupings>
</request>" ;
byte [] bytes = Encoding .UTF8.GetBytes(command);
// , .
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST" ;
request.ContentLength = bytes.Length;
request.ContentType = "text/xml" ;
// XML-
using ( Stream requestStream = request.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
}
//
HttpWebResponse response =(HttpWebResponse)request.GetResponse();
* This source code was highlighted with Source Code Highlighter .
HttpWebRequestオブジェクトは、POSTメソッドでリクエストを送信するときにHTTPヘッダー「Expect:100-Continue」を追加するため、一部のサービス(Yandex.XMLを含む)を誤解させ、「(417)Expectation Failed 」
Getメソッド
GETメソッドは、リクエストがXML形式の文字列ではなく、単純な文字列であるという点でPOSTメソッドと異なります。 サービスを受信すると、サービス自体が要求テキストからXMLを形成し(文字列要求の各要素をXML属性に変換)、応答を(XML形式で)送信します。 コード例:
//, IP.
string key = "***********************************" ;
// .
string user = "*****************" ;
// .
string url = @"http://xmlsearch.yandex.ru/xmlsearch?
query={0}&
groupby=attr%3Dd.
mode%3Ddeep.
groups-on-page%3D10.
docs-in-group%3D1&
user={1}&
key={2}" ;
// .
string completeUrl = String .Format(url, searchQuery, user, key);
//, .
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(completeUrl);
// .
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
* This source code was highlighted with Source Code Highlighter .
そのため、サービスからの応答が受信されます。 ここから、検索結果に関する必要なすべての情報を抽出する必要があります。 .Net環境でXMLドキュメントを操作するための強力なメカニズムがあるため、これには特別な問題はありませんでした。 最初に、受信したHttpWebResponse応答に基づいてXML応答を処理するオブジェクトを作成します。
XmlReader xmlReader = XmlReader.Create(response.GetResponseStream());
XDocument xmlResponse = XDocument .Load(xmlReader);
* This source code was highlighted with Source Code Highlighter .
残っているのは、受信したXML応答を解析することだけです。 しかし、これを行う前に、この答えの構造を知る必要があります。 Yandex.XMLのドキュメントで詳細に説明されています 。 このプロジェクトでは、検索結果に関する一般的な情報は不要であり、個々の検索結果を個別の構造として扱うことが計画されていたとしか言えません。 各検索結果で、次のことに興味がありました。
• < url > - URL
• < title > -
• < headline > -
• < modtime > -
• < saved-copy-url > -
* This source code was highlighted with Source Code Highlighter .
最初に、検索結果が書き込まれる構造が準備されました。
public struct YaSearchResult
{
//url
public string DisplayUrl,
//saved-copy-url
CacheUrl,
//title
Title,
//headline
Description,
//modtime
IndexedTime;
public YaSearchResult( string url,
string cacheUrl,
string title,
string description,
string indexedTime)
{
this .DisplayUrl = url;
this .CacheUrl = cacheUrl;
this .Title = title;
this .Description = description;
this .IndexedTime = indexedTime;
}
}
* This source code was highlighted with Source Code Highlighter .
XMLドキュメント自体では、各検索結果はグループと呼ばれ、次の構造を持ちます。
<group>
<categ attr= "" name= "" />
<doccount> </doccount>
<relevance priority= "" />
-<doc id= "" >
<relevance priority= "" />
<url> </url>
<domain> </domain>
<title> </title>
<modtime> </modtime>
<size> </size>
<charset> </charset>
+<passages>
+<properties>
<mime-type> </mime-type>
<saved-copy-url> </saved-copy-url>
</doc>
</group>
* This source code was highlighted with Source Code Highlighter .
最後に、解析メソッド自体(最初は+、XML値を引き出すための補助メソッド):
// doc,
// GetValue , ,
public static string GetValue( XElement group, string name)
{
try
{
return group.Element(«doc»).Element(name).Value;
}
// ,
// .
catch
{
return string .Empty;
}
}
* This source code was highlighted with Source Code Highlighter .
public static List <YaSearchResult> Search( string searchQuery)
{
// YaSearchResult, .
List <YaSearchResult> ret = new List <YaSearchResult>();
// XML' "group" -
var groupQuery = from gr in response.Elements().
Elements( "response" ).
Elements( "results" ).
Elements( "grouping" ).
Elements( "group" )
select gr;
// group SearchResult
for ( int i = 0; i < groupQuery.Count(); i++)
{
string urlQuery = GetValue(groupQuery.ElementAt(i), "url" );
string titleQuery = GetValue(groupQuery.ElementAt(i), "title" );
string descriptionQuery = GetValue(groupQuery.ElementAt(i), "headline" );
string indexedTimeQuery = GetValue(groupQuery.ElementAt(i), "modtime" );
string cacheUrlQuery = GetValue(groupQuery.ElementAt(i),
"saved-copy-url" );
ret.Add( new YaSearchResult(urlQuery, cacheUrlQuery, titleQuery, descriptionQuery, indexedTimeQuery));
}
return ret;
}
* This source code was highlighted with Source Code Highlighter .
検索結果シートが届きました!
おわりに
誰かが.NetのYandex APIを使用するトピックに興味がある場合は、次の記事でYandex APIジオコーディング/リバースジオコーディングAPIの使用方法を作成できます。
最後に、Yandex.XMLだけでなく、他のサービスも含めた.Net用のYandex APIの美しいフルラッパーを作成する予定です。