2015-03-23 1 views
3

У меня есть приложение, написанное на Python, с использованием GTK3 через интроспекцию GObject (Python 2.7 и PyGObject 3.14). Я пытаюсь загрузить веб-страницу с помощью WebKit и получить доступ к содержимому всех ресурсов, которые он загружает. Я могу это сделать, подключившись к сигналу resource-load-finished объекта WebKitWebView, который я использую для загрузки страницы.Как получить сырые байты из GLib.GString в Python?

Внутри обработчика сигнала я использую объект WebKitWebResource в параметре web_resource для доступа к загруженным данным. Все отлично работает с GLib.GString, возвращаемым из get_data(), когда он не содержит NULL-байт, я могу получить доступ к тому, что мне нужно, используя data.str. Однако, когда данные содержат NULL-байты, что часто бывает, когда тип загружаемого ресурса MIME является изображением, data.len верен, но data.str содержит только данные до первого байт NULL. Я могу получить доступ к необработанным байтам, вызвав data.free_to_bytes(), который возвращает экземпляр GLib.GBytes, однако, когда обработчик сигнала возвращает segfaults приложения. Я пытаюсь получить доступ ко всем данным в загруженном ресурсе.

Надеюсь, следующий код поможет продемонстрировать эту проблему.

from gi.repository import Gtk 
from gi.repository import WebKit 

def signal_resource_load_finished(webview, frame, resource): 
    gstring = resource.get_data() 
    print(resource.get_mime_type()) 
    desired_len = gstring.len 
    # gstring.str is missing data because it returns the data up to the first NULL byte 
    assert(gstring.str == desired_len) # this assertion fails 

    # calling this causes a segfault after the handler returns, but the data is accessible from gbytes.get_data() 
    #gbytes = gstring.free_to_bytes() 
    #assert(len(gbytes.get_data()) == desired_len) # this assertion succeeds before the segfault 
    return 

webview = WebKit.WebView() 
webview.connect('resource-load-finished', signal_resource_load_finished) 
webview.connect('load-finished', Gtk.main_quit) 
# lol cat for demo purposes of a resource containing NULL bytes (mime type: image/png) 
webview.load_uri('http://images5.fanpop.com/image/photos/30600000/-Magical-Kitty-lol-cats-30656645-1280-800.png') 
Gtk.main() 

ответ

2

Вы не хотите использовать free_to_bytes как это не только даст вам байт вы хотите, но и освободить строку из памяти без Python, зная об этом, - которые, как вы обнаружили, сбой программы. К сожалению, не существует соответствующего метода get_bytes, поскольку GLib.String не был предназначен для хранения двоичных данных.

На самом деле я считаю ошибкой в ​​API WebKit, что полезная нагрузка ресурса доступна только как GLib.String. Они, похоже, исправили эту ошибку в WebKit2: http://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebResource.html

Рассмотрите возможность перехода на WebKit2, если можете (from gi.repository import WebKit2).

Смежные вопросы