Google的搜索API的Delphi封装
这个东西实现了已经有一段时间了,那个时候谷歌还没有退出中国内地呢!而现在呢,谷歌都退了有一些日子了!紧以此纪念一番!
话说谷歌API,我相信很多人应该都知道!不晓得在实际应用中,用的人多不多(我说的不是Web方面的)。谷歌API提供了很多接口,但是貌似唯独没有提供对Delphi的接口(我们Delphi程序员果然很尴尬啊,很多类库,都没有我们的份,都需要自己来实现)。而我又需要这么个东西,于是,我就写了这么个东西,完全基于搜索API的封装!用来实现在自己的软件中实现搜索的目的!

谷歌的搜索API的详细资料在:
http://code.google.com/intl/zh-CN/apis/ajaxsearch/documentation/reference.html#_class_GSearch
有兴趣的,可以自行参考一下!因为这个资料已经说的很详细了,所以我也就不多费口舌了,直接上代码
代码:

代码
{Google搜索API
参考资料:
http://code.google.com/intl/zh-CN/apis/ajaxsearch/documentation/reference.html#_class_GSearch
作者:不得闲 2010-4-1
}
unit DxGoogleSearchApi;
interface
uses Classes,SysUtils,msxml,uLkJSON,Variants;
type
//搜索类型 Web搜索 本地搜索 视频搜索 博客 新闻 书籍 图片 专利搜索
TDxSearchType = (Sh_Web,Sh_Local,Sh_Video,Sh_Blog,Sh_News,Sh_Book,Sh_Image,Sh_patent);
//搜索返回的结果
TDxSearchRecord = class
private
RetList: TStringList;
function GetFieldCount: Integer;
function GetFields(index: Integer): string;
function GetValues(index: Integer): string;
public
constructor Create;
procedure FromJsonObj(JsonObj: TlkJSONobject);
destructor Destroy;override;
property FieldCount: Integer read GetFieldCount;
property Fields[index: Integer]: string read GetFields;
property Values[index: Integer]: string read GetValues;
function FieldByName(FieldName: string): string;
end;
TDxSearchRecords = class
private
List: TList;
FSearchType: TDxSearchType;
function GetCount: Integer;
function GetRecords(index: Integer): TDxSearchRecord;
public
procedure Clear;
constructor Create;
property SearchType: TDxSearchType read FSearchType;
destructor Destroy;override;
property Count: Integer read GetCount;
property Records[index: Integer]: TDxSearchRecord read GetRecords;
end;
//搜索API
TDxGoogleSearch = class
private
FSearchType: TDxSearchType;
FBigSearchSize: Boolean;
FSearchStart: Integer;
FVersion: string;
HttpReq: IXMLHttpRequest;
FRecords: TDxSearchRecords;
Pages: array of Integer;
FCurSearchInfo: string;
ClearOld: Boolean;
FCurPageIndex: Integer;
function GetPageCount: Integer;
public
constructor Create;
destructor Destroy;override;
procedure Search(SearchInfo: string);
property CurPageIndex: Integer read FCurPageIndex;
function NextSearch: Boolean;//搜索下一个页
property PageCount: Integer read GetPageCount;
property Records: TDxSearchRecords read FRecords;
property BigSearchSize: Boolean read FBigSearchSize write FBigSearchSize default true;//rsz参数
property SearchStart: Integer read FSearchStart write FSearchStart default 0;//搜索开始的位置,start参数
property Version: string read FVersion write FVersion;
property SearchType: TDxSearchType read FSearchType write FSearchType default Sh_Web;//搜索类型
end;
implementation
type
TBytes = array of Byte;
function BytesOf(const Val: AnsiString): TBytes;
var
Len: Integer;
begin
Len := Length(Val);
SetLength(Result, Len);
Move(Val[1], Result[0], Len);
end;
function ToUTF8Encode(str: string): string;
var
b: Byte;
begin
for b in BytesOf(UTF8Encode(str)) do
Result := Format('%s%s%.2x', [Result, '%', b]);
end;
{ TDxGoogleSearch }
constructor TDxGoogleSearch.Create;
begin
HttpReq := CoXMLHTTPRequest.Create;
ClearOld := True;
FRecords := TDxSearchRecords.Create;
FVersion := '1.0';
FSearchType := Sh_Web;
FBigSearchSize := True;
FSearchStart := 0;
end;
destructor TDxGoogleSearch.Destroy;
begin
HttpReq := nil;
SetLength(Pages,0);
FRecords.Free;
inherited;
end;
function TDxGoogleSearch.GetPageCount: Integer;
begin
Result := High(Pages) + 1;
end;
function TDxGoogleSearch.NextSearch: Boolean;
var
i: Integer;
begin
Result := False;
for i := 0 to High(Pages) do
begin
if Pages[i] = FSearchStart then
begin
if i + 1 <= High(Pages) then
begin
FSearchStart := Pages[i + 1];
Result := True;
end;
Break;
end;
end;
if Result then
Search(FCurSearchInfo);
end;
procedure TDxGoogleSearch.Search(SearchInfo: string);
const
BaseUrl = 'http://ajax.googleapis.com/ajax/services/search/';
var
Url: string;
Json: TlkJsonObject;
ChildJson,tmpJson: TlkJSONbase;
SRecord: TDxSearchRecord;
procedure OnSearch;
var
i: Integer;
begin
Url := Url + '&start='+inttostr(FSearchStart);
HttpReq.open('Get', Url, False, EmptyParam, EmptyParam);
HttpReq.send(EmptyParam);//开始搜索
Url := HttpReq.responseText;
Json := Tlkjson.ParseText(url) as TlkJSONobject;
ChildJson := Json.Field['responseData'];
if ChildJson.SelfType = jsObject then
begin
ChildJson := ChildJson.Field['results'];
if ChildJson.SelfType = jsList then
begin
for i := 0 to ChildJson.Count - 1 do
begin
tmpJson := ChildJson.Child[i];
SRecord := TDxSearchRecord.Create;
SRecord.FromJsonObj(tmpJson as TlkJSONobject);
FRecords.List.Add(SRecord);
end;
end;
if ClearOld or (Length(Pages) = 0) then
begin
//查看分页情况,获得分页情况
ChildJson := Json.Field['responseData'].Field['cursor'].Field['pages'];
if ChildJson.SelfType = jsList then
begin
SetLength(Pages,ChildJson.Count);
for i := 0 to ChildJson.Count - 1 do
begin
tmpJson := ChildJson.Child[i];
Pages[i] := StrToInt(VarToStr(tmpJson.Field['start'].Value));
end;
end;
ChildJson := Json.Field['responseData'].Field['cursor'];
FCurPageIndex := strtoint(vartostr(ChildJson.Field['currentPageIndex'].Value));
end
else
begin
ChildJson := Json.Field['responseData'].Field['cursor'];
FCurPageIndex := strtoint(vartostr(ChildJson.Field['currentPageIndex'].Value));
end;
end;
Json.Free;
end;
begin
FCurSearchInfo := SearchInfo;
case FSearchType of
Sh_Web: Url := BaseUrl + 'web?v='+FVersion+'&q=';
Sh_Local: Url := BaseUrl + 'local?v='+FVersion+'&q=';
Sh_Video: Url := BaseUrl + 'video?v='+FVersion+'&q=';
Sh_Blog: Url := BaseUrl + 'blogs?v='+FVersion+'&q=';
Sh_News: Url := BaseUrl + 'news?v='+FVersion+'&q=';
Sh_Book: Url := BaseUrl + 'books?v='+FVersion+'&q=';
Sh_Image: Url := BaseUrl + 'images?v='+FVersion+'&q=';
Sh_patent: Url := BaseUrl + 'patent?v='+FVersion+'&q=';
else Url := '';
end;
if Url <> '' then
begin
FRecords.FSearchType := FSearchType;
if ClearOld then
FRecords.Clear;
Url := Url + ToUTF8Encode(SearchInfo);
if FBigSearchSize then
Url := Url + '&rsz=large'
else Url := Url + '&rsz=small';
if FSearchStart < 0 then
begin
//搜索返回所有结果
ClearOld := False;
FSearchStart := 0;
OnSearch;
while NextSearch do;//搜索下一个
end
else
begin
OnSearch;
end;
end;
end;
{ TDxSearchRecord }
constructor TDxSearchRecord.Create;
begin
RetList := TStringList.Create;
end;
destructor TDxSearchRecord.Destroy;
begin
RetList.Free;
inherited;
end;
function TDxSearchRecord.FieldByName(FieldName: string): string;
var
index: Integer;
begin
index := RetList.IndexOfName(FieldName);
if (index > -1) and (index < FieldCount) then
Result := RetList.ValueFromIndex[index]
else Result := '';
end;
procedure TDxSearchRecord.FromJsonObj(JsonObj: TlkJsonObject);
var
i: Integer;
str: String;
begin
RetList.Clear;
for i := 0 to JsonObj.Count - 1 do
begin
str := JsonObj.NameOf[i];
str := str + '=' + VarToStr(JsonObj.FieldByIndex[i].Value);
RetList.Add(str);
end;
end;
function TDxSearchRecord.GetFieldCount: Integer;
begin
Result := RetList.Count;
end;
function TDxSearchRecord.GetFields(index: Integer): string;
begin
if (index > -1) and (index < FieldCount) then
Result := RetList.Names[index]
else Result := '';
end;
function TDxSearchRecord.GetValues(index: Integer): string;
begin
if (index > -1) and (index < FieldCount) then
Result := RetList.ValueFromIndex[index]
else Result := '';
end;
{ TDxSearchRecords }
procedure TDxSearchRecords.Clear;
begin
while List.Count > 0 do
begin
TDxSearchRecord(List[List.Count - 1]).Free;
List.Delete(List.Count - 1);
end;
end;
constructor TDxSearchRecords.Create;
begin
List := TList.Create;
FSearchType := Sh_Web;
end;
destructor TDxSearchRecords.Destroy;
begin
clear;
List.Free;
inherited;
end;
function TDxSearchRecords.GetCount: Integer;
begin
Result := List.Count;
end;
function TDxSearchRecords.GetRecords(index: Integer): TDxSearchRecord;
begin
if (index > -1) and (index < Count) then
Result := List[index]
else Result := nil;
end;
end.
Google的搜索API的Delphi封装的更多相关文章
- 使用Javascript从Google Places搜索api获取纬度和经度
如何使用谷歌地图搜索框api从搜索到的位置获取经度和纬度. 我使用与谷歌演示相同的代码 – https://developers.google.com/maps/documentation/javas ...
- 通过Google Custom Search API 进行站内搜索
今天突然想把博客的搜索改为google的站内搜索,印象中google adsense中好像提高这个站内搜索的代码,但苦逼的是google adsense帐号一直审核不通过,所以只能通过google c ...
- Google地图接口API之申请免费API Key(一)
使用谷歌地图API V3创建交互式地图,首先需要拥有一个免费的 Google 地图 API key. 如果想调用Google地图的接口,首先需要拥有一个免费的 Google 地图 API key.想要 ...
- google map android api v2
我在这主要列举几个需要注意的问题: 1.需要注意使用的api版本的问题,例如google map android api v1就和v2差别很大,包括申请key方面,所以在搜索资料的时候一定注意版本问题 ...
- ElasticSearch查询 第一篇:搜索API
<ElasticSearch查询>目录导航: ElasticSearch查询 第一篇:搜索API ElasticSearch查询 第二篇:文档更新 ElasticSearch查询 第三篇: ...
- [转]MBTiles 离线地图演示 - 基于 Google Maps JavaScript API v3 + SQLite
MBTiles 是一种地图瓦片存储的数据规范,它使用SQLite数据库,可大大提高海量地图瓦片的读取速度,比通过瓦片文件方式的读取要快很多,适用于Android.IPhone等智能手机的离线地图存储. ...
- 如何使用google地图的api(整理)
如何使用google地图的api(整理) 一.总结 一句话总结:直接用script标签引google地图api即可. 1.如何使用google地图的api? 页面引用javascript文件<s ...
- google批量搜索实现方式
本文主要记录一下最近所做的关于Google批量搜索的实现方式. 搜索目的: 获取关键词在某个域名下对应的Google搜索结果数 搜索方式: 关键词+inurl 例如:"爬虫" in ...
- 一个扩展搜索API的优化过程
概述 API 是一个服务的门面,就像衣装是人的形象一样. 优雅的 API 设计,能让业务方使用起来倍儿爽,提升开发效率,降低维护成本:糟糕的 API 设计,则让业务方遭心,陷入混沌. 本文将展示一个扩 ...
随机推荐
- Session共享解决方案
使用nginx做的负载均衡添加一个ip_hash配置 一.开两个Tomcat写测试程序 @WebServlet("/nginxSessionServlet") public cla ...
- Python学习 —— 实现简单的爬虫
为了加快学习python3.x,查了许多资料后写了这个脚本,这个脚本主要是爬取百度图片'东方幻想乡'的图片,但还是有很多问题存在. 下面给出代码: # 更新了一下代码 from urllib impo ...
- 「SDOI2013」森林
「SDOI2013」森林 传送门 树上主席树 + 启发式合并 锻炼码力,没什么好说的. 细节见代码. 参考代码: #include <algorithm> #include <cst ...
- 124、Java面向对象之引用传递实例二,String类型按值传递
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- MacBook OSX VMWare Fusion 11安装 Tools For Windows
需要加载对应客户机系统的安装文件,可以在/Applications/VMware\ Fusion.app/Contents/Library/isoimages文件夹下找到: 设置虚拟机的光驱: 在虚拟 ...
- TCP/IP,三次握手四次挥手,TCP/UDP , HTTP/HTTPS
internet:通用名词,由多个计算机网络组成的网络,网络间的通信协议是任意的 Internet:专用名词,当前全球最大的开放计算机网络,采用TCP/IP协议族作为通信的规则.www万维网是广泛应用 ...
- 这两天的pwn学习总结
总是一会儿切到那里,一会儿切到那里,要明确一条主线,就是buu的题,而不是按着什么视频教程还有linux和python教程去学习.那样效率比较低. 一切为了写wp为本,不胡乱点击就是提高效率的最好办法 ...
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 按钮:制作一个小按钮
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- layer 点击yes后在回调函数里获取layer.open({})iframe里面元素
参考:http://fly.layui.com/jie/19690/ yes: function(index, layero) { uid.value = $(layero).find('iframe ...
- KDE Plasma 5.17 即将发布
导读 Plasma 5.17上个月达到了beta版本,而下周将发布Plasma 5.17.0版本!KDE桌面的大更新只有几天了.因此,开发人员一直在整理它,同时也集思广益讨论Plasma 5.18应该 ...