如何从Google搜索结果中提取目标网址?

时间:2011-10-11 19:28:12

标签: delphi delphi-7

我正在尝试从Google搜索结果中提取网址。我使用Indy IdHTTP从Google获取HTML结果,并使用Achmad Z's code for getting the link hrefs from the page。如何获取每个网址的真实链接目标,而不是通过Google重定向程序的网址?


我试过了,但是在这部分代码中我得到了“操作数不适用”错误:

function ToUTF8Encode(str: string): string;
var
  b: Byte;
begin
  for b in BytesOf(UTF8Encode(str)) do
  begin
    Result := Format('%s%s%.2x', [Result, '%', b]);
  end;
end;

我使用Delphi 7和Indy 9.00.10。也许indy update会有帮助吗?

3 个答案:

答案 0 :(得分:5)

如果我做对了,您正尝试使用TIdHTTP.Get方法获取Google搜索结果。如果是这样,那么您应该专注于某些Google Search API实施,因为

  1. 以这种方式获取结果是不可能的,因为您无法访问搜索结果所在的iframe内的文档,因此在这种情况下您不会通过使用HTTP GET获得任何搜索结果(或至少我还没有听说过能做到这一点的请求。)
  2. 这违反了Google政策,您应该使用正确的Google搜索API,例如Google SOAP Search API,还有几种类型的Google搜索API用于各种目的
  3. 你可以找到,例如here使用Google搜索API的demo代码的Delphi包装器。我已经在Windows 7/64上使用Delphi 2009进行了测试,它对我来说很好。

答案 1 :(得分:4)

在上一篇文章中,我试图解释为什么你应该使用谷歌搜索API,在这一篇中,我将试着给你一个例子,希望它能在你的Delphi 7中运行。

你需要SuperObject(Delphi的JSON解析器),我使用了this version(目前最新)。然后你需要Indy;如果可能的话,最好的是升级到最新版本。我使用过Delphi 2009附带的那个,但我认为TIdHTTP.Get方法非常重要,它在9.00.10版本中也必须正常工作。

现在你需要一个列表框和一个表格上的按钮,下面的一段代码和一点运气(兼容性:)

您可以在之前提到的DxGoogleSearchApi.pas中看到的URL请求构建,但最好是遵循Google Web Search API reference。在DxGoogleSearchApi.pas中,您可以获取灵感,例如:如何获取多个页面。

所以把它当作灵感

uses
  IdHTTP, IdURI, SuperObject;

const
  GSA_Version = '1.0';
  GSA_BaseURL = 'http://ajax.googleapis.com/ajax/services/search/';

procedure TForm1.GoogleSearch(const Text: string);
var
  I: Integer;
  RequestURL: string;
  HTTPObject: TIdHTTP;
  HTTPStream: TMemoryStream;
  JSONResult: ISuperObject;
  JSONResponse: ISuperObject;
begin
  RequestURL := TIdURI.URLEncode(GSA_BaseURL + 'web?v=' + GSA_Version + '&q=' + Text);

  HTTPObject := TIdHTTP.Create(nil);
  HTTPStream := TMemoryStream.Create;

  try
    HTTPObject.Get(RequestURL, HTTPStream);
    JSONResponse := TSuperObject.ParseStream(HTTPStream, True);

    if JSONResponse.I['responseStatus'] = 200 then
    begin
      ListBox1.Items.Add('Search time: ' + JSONResponse.S['responseData.cursor.searchResultTime']);
      ListBox1.Items.Add('Fetched count: ' + IntToStr(JSONResponse['responseData.results'].AsArray.Length));
      ListBox1.Items.Add('Total count: ' + JSONResponse.S['responseData.cursor.resultCount']);
      ListBox1.Items.Add('');

      for I := 0 to JSONResponse['responseData.results'].AsArray.Length - 1 do
      begin
        JSONResult := JSONResponse['responseData.results'].AsArray[I];
        ListBox1.Items.Add(JSONResult.S['unescapedUrl']);
      end;
    end;

  finally
    HTTPObject.Free;
    HTTPStream.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  GoogleSearch('Delphi');
end;

答案 2 :(得分:1)

回答我的问题,也许它可以帮助某人: 获取网页:

memo1.Lines.Text := idhttp1.Get('http://ajax.googleapis.com/aja...tart=1&rsz=large&q=max');

提取网址:

function ExtractText(const Str, Delim1, Delim2: string; PosStart: integer; var PosEnd: integer): string;
var
  pos1, pos2: integer;
begin
  Result := '';
  pos1 := PosEx(Delim1, Str, PosStart);
  if pos1 > 0 then
  begin
    pos2 := PosEx(Delim2, Str, pos1 + Length(Delim1));
    if pos2 > 0 then
    begin
      PosEnd := pos2 + Length(Delim2);
      Result := Copy(Str, pos1 + Length(Delim1), pos2 - (pos1 + Length(Delim1)));
    end;
  end;
end;

在Button1上就放了:

procedure TForm1.Button1Click(Sender: TObject);
var Pos: integer;
    sText: string;
begin
  sText := ExtractText(Memo1.Lines.Text, '"url":"', '","visibleUrl"', 1, Pos);
  while sText <> '' do
  begin
    Memo2.Lines.Add(sText);
    sText := ExtractText(Memo1.Lines.Text, '"url":"', '","visibleUrl"', Pos, Pos);
  end;
end;

www.delphi.about.com有关于字符串操作的精彩文档,Zarko Gajic在该网站上做得很好:) 注意:如果谷歌更改它的来源,这将是无用的。