Az alábbi módosítás sztem megoldja a problémát, lementi amit le lehet. Általánosságban a probléma hogy a mai weboldalak többségében js vezérli a betöltéseket (lazy loading, on-demand loading), ezért az "oldal betöltődése kész" esemény nehezen értelmezhető. Új resource betöltődése a LoadEvent.FINISHED esemény után! is történhet, szerencsére a webkit-et használó programban követhető az oldalhoz tartozó resource-ok betöltődési folyamata. Erre épül a következő módosítás (alapja az első hozzászólásom ), amely nem csinál képernyőmentést rögtön a LoadEvent.FINISHED után, ehelyett megvárja resource-ok betöltődését is.
Ahogy korábban most is hozzáadjuk a GLib-et az import-okhoz:
from gi.repository import Gtk, Gdk, GLib, WebKit2
A Browser osztályt egészben közlöm:
class Browser(base):
def __init__(self, uri):
super(Browser, self).__init__()
self.webview = WebKit2.WebView.new_with_context(ctx)
self.webview.connect("load-changed", self.on_load_changed)
# Uj sorok
self.timer_ms = 500
self.resource_count_total = 0
self.resources_loading_set = set()
self.webview.connect("resource-load-started", self.on_resource_load_started)
self.webview.load_uri(uri)
self.add(self.webview)
self.connect("destroy", Gtk.main_quit)
self.set_size_request(render_width, 600) # set minimum size allowed
self.set_title("Bongeszo - " + uri)
self.show_all()
def restart_timer(self):
self.remove_timer()
# Start timer only if the page is "loaded" and all resource load is finished
if not self.webview.props.is_loading and len(self.resources_loading_set) == 0:
self.timer_id = Gdk.threads_add_timeout(GLib.PRIORITY_DEFAULT_IDLE, self.timer_ms, self.on_timeout)
def remove_timer(self):
print("\t\t\t\t\t\t\t\t(resources loading: ", len(self.resources_loading_set), ", webview loading: ", self.webview.props.is_loading, ")", sep="")
if hasattr(self, "timer_id"):
GLib.source_remove(self.timer_id)
del self.timer_id
# WebView events
def on_resource_load_started(self, web_view, resource, request):
print("Resource load STARTED :", resource.get_uri())
resource.connect("finished", self.on_resource_finished)
if resource.get_response() is None:
self.resources_loading_set.add(resource)
self.remove_timer()
self.resource_count_total += 1
def on_resource_finished(self, resource):
print("Resource load FINISHED:", resource.get_uri())
self.resources_loading_set.discard(resource)
self.restart_timer()
def on_load_changed(self, web_view, load_state):
print("\nLoad-state:", load_state, "\n")
self.restart_timer()
def on_timeout(self, *args):
print("Resources loaded total:", self.resource_count_total)
print("No load activity for", self.timer_ms, "ms, taking snapshot ...")
self.webview.get_snapshot(WebKit2.SnapshotRegion.FULL_DOCUMENT, snapshot_opts, cancellable=None, callback=self.on_snapshot_finish)
return GLib.SOURCE_REMOVE
def on_snapshot_finish(self, web_view, result):
print("Snapshot ready")
cairo_surf = web_view.get_snapshot_finish(result)
cairo_surf.write_to_png(dst_png_path)
print("Snapshot saved to", dst_png_path)
self.close()
A megértéséhez talán annyi elég, hogy ha a WebKit2.LoadEvent.FINISHED megvolt, és az utolsó resource is betöltődött, akkor elindít egy timer-t, amely self.timer_ms = 500 ideig vár. Ha a várakozás alatt új resource betöltés indul el, akkor a timer-t lelövi, később a betöltés befejezésekor újraindítja. Ha megszakítás nélkül lefut a timer, akkor menti a képernyőt és kilép.
Megjegyzés: a js lusta (kép)betöltést erősen használó oldalak, mint a youtube csak akkor töltenek be bizonyos képeket, ha lefelé görgeted az oldalt, sőt a görgetést figyelve akár bővítik is az oldalt. Ilyen esetek részben kezelhetőek azzal hogy a self.set_size_request(render_width, 600) sorban növeljük a 600-as height-et pár ezerre, vagy meg kell írni az szimulált (végig)görgetést.
Érdekesség, hogy a https://hup.hu cimlapjához a böngészőink 140 db resource-ot töltenek le, sok a google és a twitter. Itt a log vége:
Resource load STARTED : https://ton.twimg.com/tfw/assets/news_stroke_v1_78ce5b21fb24a7c7e528d22…
Resource load FINISHED: https://ton.twimg.com/tfw/assets/news_stroke_v1_78ce5b21fb24a7c7e528d22…
Resources loaded total: 140
No load activity for 500 ms, taking snapshot ...
Snapshot ready
Snapshot saved to hup.png