MacOSでMemo帳からGoogle検索をしたい

解決


Noby  2018-07-27 22:47:43  No: 49336

いつもお世話になります。

Delphi  Commminity EdでMacOS用のMemo帳を作っているのですが、

以下の点で困っております。

選択文字列をGoogleで検索するために以下のコードを記述しています。

   Moji:='あいうえお';

  SURL:='https://www.google.com/search?hl=ja&output=search&q='+Moji;

  _system(PAnsiChar('open ' + AnsiString(SURL)));//MacOSの場合

ところが、ブラウザ(Chrome)でGoogleは開くのですが、

URL部分は、
https://www.google.com/search?hl=ja&output=search&q=あいうえお

にはなっておらず、下記のようになってしまいます。

https://www.google.com/webhp?hl=ja

Memo1.Text:=SURL  と追加してみると、
SURL部分にはきちんと下記の値が代入されています。
https://www.google.com/search?hl=ja&output=search&q=あいうえお

何が原因なのでしょうか?


Mr.XRAY  2018-07-29 19:33:33  No: 49337

MacOS のことは分かりませんが,
Google 日本のウェブサイトは https://www.google.com/

https://www.google.com/webhp?hl=ja 
は日本語表示されている Google のウェブページのことです.

つまり,単に Google の大元のウェブページを表示しているだけだと思います.
と言うことで,

>何が原因なのでしょうか? 

検索オプションの指定の問題なのではないかと思います.
あるサイト内の URL を指定した時,該当ページがない時の動作のようなものだと思います.

# MacOS って AnsiString 使うんですね.


Nov  2018-07-30 09:37:09  No: 49338

単純に、アンパサントのエスケープ漏れの気がします...


Noby  2018-07-30 18:41:17  No: 49339

Mr.Xrayさん、Novさん

お世話になります。書き込みありがとうございます。

実は、Windows版では下記で正常に動作しています。

var
  SURL:String;
  GoogleS:String;
begin
  GoogleS:='https://www.google.com/search?hl=ja&output=search&q=';
  SURL:=GoogleS + HTTPEncode(UTF8Encode(Edit1.Text));
  ShellExecute(Application.Handle,'open',Pchar(SURL),NiL,NiL,SW_SHOW);
end;

Mac用のGoogleChromだと仕様が異なるのでしょうか、

不思議なのですが、

https://www.google.com/search?hl=ja&output=search&q=あいうえお  部分を

Google  Chrom  Mac版のURLフィールドに直接コピペして改行すると

検索後のページが正常に表示されています。


tor  2018-07-30 20:14:16  No: 49340

Mac版だとShellExecuteではなく、_system() 関数を使っていて
「『open URL文字列』 というコマンドライン文字列を作って、それをシェルに実行させる」という手順になっていますよね?
そのような場合、'&' とか '|' とか '<' とか '>' とかいった文字はシェルにとって特別な意味を持つので、
そういう特殊な解釈をされたくなければエスケープする必要があります。
(ShellExecuteの場合は、cmd.exeを経由するわけではないのでそのような配慮が不要だっただけです)

Macのコマンドラインの仕様はよく知りませんが、一般的には引数を二重引用符("")で囲むとかですかね?
_system('open "' + URL文字列 + '"');

ついでですが、渡される文字列に&とか引用符のような特殊文字が含まれているとやはり困ったことになるので、URLエンコードしておいた方が良いかと。
SURL := ... TIdURI.URLEncode(検索する文字列);


Harry  2018-07-30 22:32:43  No: 49341

質問者ではないですが…、
なるほど、URLのうち & の前までの
https://www.google.com/search?hl=ja をブラウザへ入れて移動すると、
https://www.google.com/webhp?hl=ja  に遷移しますね。

ところで、
>  _system(PAnsiChar('open ' + AnsiString(SURL)));//MacOSの場合 
これだと検索クエリがAnsiString、つまりシフトJISに限定されてしまいますよね?

「OSX ブラウザ Delphi」で検索してみたら別の方法がありました。

FireMonkey - OS X で URLをデフォルトブラウザで開く - MASA Lab softlab
http://softlab.masa-lab.net/modules/d3blog/details.php?bid=21

こちらだとUnicodeで行けるような気が? 試してみてはいかがでしょう。

URLエンコード(パーセントエンコード)には、これはどうでしょう。HTTPEncodeは非推奨のようなので。
http://docwiki.embarcadero.com/Libraries/ja/System.NetEncoding.TURLEncoding

以上、環境がないためまったく試していませんから無責任ですが、ご参考までに。


Noby  2018-08-01 23:43:35  No: 49342

torさん  Harryさん

書き込みありがとうございます。

  KStr:='あいうえお';

  SURL:=TIdURI.URLEncode('https://www.google.com/search?hl=ja&output=search&q='+KStr);//+Memo1.SelText;

  _system(PAnsiChar('open ' + AnsiString(SURL)));//MacOSの場合
 
 Memo1.Text:= SURL;

上記のコードでもやはり  https://www.google.com/webhp?hl=ja  のままとなります。

正常にエンコードされているのは、 Memo1.Text:= SURL;  部分で確認しています。

ためしに、GoogleChromのMac版で、検索文字列のあいうえおを検索したときに生成されるURL【下記①】を直接上記のSURLに

セットしてみましたが、やはり症状は変わらないようです。EnCodeの問題ではないのでしょうか?

ただ気になるのが、Windows用には出てこないUTF8以外の文字列です。

 もう一つ不思議なのが、

https://www.google.com/search?hl=ja&output=search&q=あいうえお  部分を 

Google  Chrom  Mac版のURLフィールドに直接コピペして改行するとURLはコンバートされずにそのままそのURLが表示され

検索結果画面が正常に表示されているという点です。

検索文字列を付加してでMemo帳からGoogle起動する時に、検索文字列部分が

無視されてhttps://www.google.com/webhp?hl=ja  へ全てリダイレクトされているという感じです。

Chrome Mac版の仕様なのでしょうか??

【下記①】は、https://www.google.com/  で表示させたあとに、Google検索フィールドから  あいうえお  と検索した際に
URL部分に表記されているURLです。

SURL:='https://www.google.com/search?hl=ja&source=hp&ei=8UJhW-H4MZLXhwP-5JyYCA&q=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A'
+'&oq=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A&gs_l=psy-ab.3..35i39k1j0i131i4k1j0i4k1j0i131i4k1j0i4k1l4.40489.43943.0.44487.13.8.'
+'2.0.0.0.91.554.7.8.0....0...1c.1j4.64.psy-ab..3.10.753.6..0j0i131k1j0i67k1.194.G-yNQr6sOzE ';


Mr.XRAY  2018-08-02 04:28:11  No: 49343

検索文字列を 
KStr:='あいうえお'; 

ではなく,例えば
KStr:='Delphi';
にするとどうなりますか ?


tor  2018-08-02 06:11:04  No: 49344

で、'open "' + URL文字列 + '"' と二重引用符で囲む方は試してみたのでしょうか?

今回の問題の本質は、例えば
> _system('open a&b&c')
とsystem関数を使って実行すると、その中の "&" がシェルによって
「複数のコマンドを並列して実行しろ」という指示だと解釈されるということにあります。

上の文字列は、次のように3つのコマンドを実行する指示になります。
1. 「open a」というコマンドをバックグラウンドで実行して、
2. 「b」というコマンドをバックグラウンドで実行して
3. 「c」というコマンドを実行する

このように解釈されるのは、URLエンコードしても防ぐことはできません
(URLエンコードしても '&' は '&' のままなので)。

防ぐためには、"" で囲んで「この中は特別な解釈をしないで、一塊の文字列として扱ってください」ということをシェルに伝える必要があります。
> _system('open "a&b&c"')
としなくてはいけないのです。あるいは & の前に \ を付けてエスケープして
> _system('oepn a\&b\&c')
とします。これで、
1. 「open」コマンドに「a&b&c」という文字列を引数として与えて実行する
という本来意図した意味になります、たぶん。


Noby  2018-08-02 18:34:31  No: 49345

Mr.xrayさん、torさん

お世話になります。

教えていただきました下記①では出来ました。本当にありがとうございます。

試してみてはいたのですが、セットの仕方が間違っていたようで・・・

  ただ、URLを変数SURLにセットして実行するとエラーなくコンパイルは出来ますが、

Paseverのターミナル上では、>sh: o: command not found と出てブラウザも起動しない状況です。

  ①_system(PAnsiChar('open "https://www.google.com/search?hl=ja&output=search&q=Delphi"'));//MacOSの場合

  ②_system(PAnsiChar('open "' + SURL +'"'));//MacOSの場合

念のため、きちんとセットされているかも下記で試してみましたが、

  Memo1.text:='open "' + SURL +'"'

  open "https://www.google.com/search?hl=ja&output=search&q=Delphi"  と表記されていますので変数セットは大丈夫だと思うのですが・・・


KONNOYA  2018-08-02 21:39:10  No: 49346

このやり方はどうでしょう?
検索文字列の日本語部分はパーセントエンコーディングを行う必要があります。

パーセントエンコーディング
https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%BC%E3%82%BB%E3%83%B3%E3%83%88%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0

下記のコードは、エディットに検索文字列を入れ、検索ボタンを押すとブラウザが開くという単純なコードです。
検索文字列「あいうえお」でもOK。

Macintosh実機で実行させてみましたが、普通に動きました。
手元の環境のMacintoshには、Google Chromeを入れていないので、Safariで起動しますが。

unit MainUnit;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls, FMX.Controls.Presentation, FMX.Edit,
  IdURI,
  Macapi.Helpers, Macapi.Foundation, Macapi.AppKit;

type
  TMainForm = class( TForm )
    SearchEdit   : TEdit;
    SearchButton : TButton;
    procedure SearchButtonClick( Sender : TObject );
    procedure OpenBrowser( const AURL : String; const ASearchText : String );
  private
    { private 宣言 }
  public
    { public 宣言 }
  end;

var
  MainForm : TMainForm;

implementation

{$R *.fmx}

// 検索ボタン押下時処理
procedure TMainForm.SearchButtonClick( Sender : TObject );

begin
  OpenBrowser( 'https://www.google.com/search?hl=ja&output=search&q=', SearchEdit.Text );
end;

// ブラウザオープン処理
procedure TMainForm.OpenBrowser( const AURL : String; const ASearchText : String );

var
  WorkSpace : NSWorkspace;
  URL       : NSURL;

begin
  WorkSpace := TNSWorkspace.Wrap( TNSWorkspace.OCClass.sharedWorkspace );
  URL       := TNSURL      .Wrap( TNSURL.OCClass.URLWithString( StrToNSStr( TIdURI.URLEncode( AURL + ASearchText ) ) ) );
  WorkSpace.openURL( URL );
end;

end.

【環境】
・Windows 10 - Delphi 10.2.3 Tokyo
・macOS 10.13.4


Noby  2018-08-03 01:57:40  No: 49347

KONNNOYAさん

いつもありがとうございます。

ご提供いただきましたコードでSafari、Chrom(それぞれデフォルトブラウザを変更して)両方で

&を含まない文字列でしたら検索はできるのですが、

例えば、

  DELPHI  Q&A  で検索をすると

  DELPHI  Q  で検索をしてしまいます。

&を含む検索文字列の場合このようになるようなので、試しに  DELPHI Q\&A  としみても変わりはありませんでした。

たびたびで申し訳ございませんが、他に対応方法はございますでしょうか?


KONNOYA  2018-08-03 02:21:41  No: 49348

あらら、その様な事が(汗
試してみた所、ホントですね。

こちらではどうでしょうか?
System.NetEncoding の TNetEncoding.URL.Encodeならうまくいくようです。
※ さっきのサンプルで、URLを含めてのエンコードも良くなかったです。
   検索ワードのみをエンコードする様にしました。

uses
  …System.NetEncoding;

  URL       := TNSURL.Wrap( TNSURL.OCClass.URLWithString( StrToNSStr( AURL + TNetEncoding.URL.Encode( SearchWord ) ) ) );

うまくいくのですが、ただ気になる記事を発見しました。

https://qiita.com/pik/items/2e6355c3f674699a1340

Noby様の健闘を祈ります。


Noby  2018-08-03 02:49:33  No: 49349

KONNOYAさん

お蔭様で、出来ました!本当にありがとうございました。

Mr.XRAYさん、Novさん、torさん、Harry さん  

皆様、本当にご親切に教えていただきまして本当にありがとうございます。

いつも助けてくださって心から感謝申し上げます。

  しかし、マルチデバイス(今回はiOSのみ向けですが)用の開発は

VCLとは結構異なるようで、結構苦労しそうです(^^;)


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加