1

私は研究のために PyObjC に最小限のブラウザーを実装しています。まず、pyobjc から webkit を使用する方法についてググって、次のようなコードを書きました。

#coding: utf-8

import Foundation
import WebKit
import AppKit
import objc

def main():
    app = AppKit.NSApplication.sharedApplication()
    rect = Foundation.NSMakeRect(100,350,600,800)
    win = AppKit.NSWindow.alloc()
    win.initWithContentRect_styleMask_backing_defer_(
        rect,
        AppKit.NSTitledWindowMask |
            AppKit.NSClosableWindowMask |
            AppKit.NSResizableWindowMask |
            AppKit.NSMiniaturizableWindowMask,
        AppKit.NSBackingStoreBuffered,
        False)
    win.display()
    win.orderFrontRegardless()

    webview = WebKit.WebView.alloc()
    webview.initWithFrame_(rect)

    pageurl = Foundation.NSURL.URLWithString_("http://twitter.com")
    req = Foundation.NSURLRequest.requestWithURL_(pageurl)
    webview.mainFrame().loadRequest_(req)

    win.setContentView_(webview)
    app.run()

if __name__ == '__main__':
    main()

うまくいきました。しかし、このブラウザは Safari と Cookie を共有していることに気付きました。Safari.app から独立させたい。それで、もう一度グーグルで調べたところ、 NSMutableURLRequestを使用して cookie-handling-methods をオーバーライドできることがわかりました。以下は、私がテストした2番目のコードです。

#coding: utf-8

import Foundation
import WebKit
import AppKit
import objc

def main():
    app = AppKit.NSApplication.sharedApplication()
    rect = Foundation.NSMakeRect(100,350,600,800)
    win = AppKit.NSWindow.alloc()
    win.initWithContentRect_styleMask_backing_defer_(
        rect,
        AppKit.NSTitledWindowMask |
            AppKit.NSClosableWindowMask |
            AppKit.NSResizableWindowMask |
            AppKit.NSMiniaturizableWindowMask,
        AppKit.NSBackingStoreBuffered,
        False)
    win.display()
    win.orderFrontRegardless()

    webview = WebKit.WebView.alloc()
    webview.initWithFrame_(rect)

    pageurl = Foundation.NSURL.URLWithString_("http://twitter.com")
    req = Foundation.NSMutableURLRequest.requestWithURL_(pageurl)
    Foundation.NSMutableURLRequest.setHTTPShouldHandleCookies_(req, False)
    webview.mainFrame().loadRequest_(req)

    win.setContentView_(webview)
    app.run()

if __name__ == '__main__':
    main()

このコードは twitter のログイン画面を表示します :-) しかし、このブラウザでは twitter にログインできませんでした。アカウント名、パスワードを入力してエンターキーを押しました。すると、Safari.app でいつも使っているアカウントのタイムラインがブラウザに表示されます。

はい、私はそれが正しい結果であることを知っています。クッキーの取り扱いについては何も書いていません。そして私の質問はこの点についてです。私はそれを知りたい:

  1. NSHTTPCookieStorageのようなものを実装して使用するにはどうすればよいですか?
  2. pythonで書けますか?

ありがとうございました。

4

1 に答える 1

0

簡単な部分から始めます。Objective-C でこれが可能であれば、PyObjC でも可能であるはずです。

とはいえ、これが可能かどうかは私にはわかりません。Cookie を共有せずに Webkit の複数のインスタンスを作成するにはどうすればよいですか? Webkitデリゲートを介して何かを行うことができるかもしれませんが、そうではないことを示しているようです.

もう 1 つの方法は、NSURLProtocol を使用し、http/https 要求を処理するためのカスタム NSURLProtocol クラスを登録し、Python の urllib または urllib2 を使用してそれを実装することです。PyDocURLの例は、これを行う方法を示しています (この例では、pydoc:// URL のサブクラスを登録しています)。

NSURLConnection の詳細については、Apple の Web サイトを参照してください。

実装のヒントで更新:

別の方法として、NSHTTPCookieStorage (NSHTTPCookieStorage.sharedHTTPCookieStorage.setCookieAcceptPolicy_(NSHTTPCookieAcceptPolicyNever)) によって Cookie ストレージを無効にすることもできます。次に、Webkit リソース ロード デリゲートを使用して、Cookie を自分で処理します。

  • 独自の Cookie ストアを維持する (おそらく urllib2 のクラスを使用)

  • webView:resource:willSendRequest:redirectResponse:fromDataSource: そのストアの情報に基づいて Cookie ヘッダーを追加します。

  • webView:resource:didReceiveResponse:fromDataSource: 「set-cookie」ヘッダーを確認し、独自の Cookie ストアを更新します。

これを行うのはそれほど難しいことではありません。私は、この機能を PyObjC Web サイトの例として (または PyObjC の WebKit バインディングのユーティリティ クラスとして) 提供したいと考えています。

于 2013-02-25T08:08:02.870 に答える