我该如何说明页面已完成加载



我正在使用Chromium的无头Web浏览器API。基于Chrome_remote_shell源代码,我提出了以下代码:

#!/usr/bin/env python
import json
import requests
import pprint
import websocket
tablist = json.loads(requests.get("http://%s:%s/json" % ("localhost", 9222)).text)
print(tablist)
wsurl = tablist[0]['webSocketDebuggerUrl']
conn = websocket.create_connection(wsurl)
navcom = json.dumps({"id":0, "method":"Network.enable"})
conn.send(navcom)
navcom = json.dumps({"id":1, "method":"Page.navigate", "params":{"url":"https://news.ycombinator.com/"}})
conn.send(navcom)
while True:
    packet = json.loads(conn.recv())
    if 'method' in packet:
        print(packet['method'])
    else:
        print(packet)

此处的示例输出:

[{u'description': u'', u'title': u'Hacker News', u'url': u'https://news.ycombinator.com/', u'webSocketDebuggerUrl': u'ws://localhost:9222/devtools/page/7d03a57d-77a9-4ceb-b645-3b85461de5be', u'type': u'page', u'id': u'7d03a57d-77a9-4ceb-b645-3b85461de5be', u'devtoolsFrontendUrl': u'/devtools/inspector.html?ws=localhost:9222/devtools/page/7d03a57d-77a9-4ceb-b645-3b85461de5be'}]
{u'id': 0, u'result': {}}
Network.requestWillBeSent
{u'id': 1, u'result': {u'frameId': u'21045.1'}}
Network.responseReceived
Network.dataReceived
Network.dataReceived
Network.loadingFinished
Network.requestWillBeSent
Network.requestWillBeSent
Network.requestServedFromCache
Network.responseReceived
Network.dataReceived
Network.loadingFinished
Network.requestWillBeSent
Network.requestServedFromCache
Network.responseReceived
Network.dataReceived
Network.loadingFinished
Network.requestWillBeSent
Network.requestServedFromCache
Network.responseReceived
Network.dataReceived
Network.loadingFinished
Network.responseReceived
Network.dataReceived
Network.loadingFinished
Network.requestWillBeSent
Network.requestServedFromCache
Network.responseReceived
Network.dataReceived
Network.loadingFinished

我注意到我收到了很长的消息,其中最后一条是网络。LoadingFined,但我为多个请求ID提供了一个。我如何修改脚本,以便该页面满载时终止并逃脱循环?

事实证明,我还应该通过页面订阅页面事件。

#!/usr/bin/env python
import json
import requests
import pprint
import websocket
import sys
tablist = json.loads(requests.get("http://%s:%s/json" % ("localhost", 9222)).text)
print(tablist)
wsurl = tablist[0]['webSocketDebuggerUrl']
conn = websocket.create_connection(wsurl)
navcom = json.dumps({"id":0, "method":"Network.enable"})
conn.send(navcom)
navcom = json.dumps({"id":1, "method":"Page.enable"})
conn.send(navcom)
navcom = json.dumps({"id":2, "method":"Page.navigate", "params":{"url":sys.argv[1]}})
conn.send(navcom)
while True:
    s = conn.recv()
    packet = json.loads(s)
    if packet.get('method') == 'Page.loadEventFired':
        break
    print(s)

我们在这里做的是启用页面和网络项目的通知,然后打开网站并阅读此后发生的所有消息。一旦到达页面。LoadeVentFired,我们可以假设页面完成的加载,这是我们可以退出循环并执行任何依赖此条件的动作的时候。

在任何一般意义上,您都不是……

给定的动态网页如今,您需要了解页面实际上在做什么,并查找DOM元素的某些特定事件/存在或其他线索。

正如您所看到的,您正在获得很多加载的事件,但是您怎么知道这是"最后"呢?您需要了解页面。例如,您能否通过观察页面每个特定的DOM元素类或基于JavaScript变量或XHR响应来确定将发送多少个请求?如果是这样,那么您可以在获得 n 响应后停止。或者,关于最后一个请求(目标或有效载荷(或最后一个响应(例如,零长度(包含文本" last", ^d或 ^z(。

另外,如果该页面在轮询服务器(通常带有插座(,那么"完成加载"甚至是什么意思?

onload

更新

如果您正在寻找onload事件,则不必做任何特别的事情。driver.get(<url>)块直到那时。

WebDriver将等到该页面已满载(即onload事件已经启动(,然后将控件返回到您的测试或脚本之前。值得注意的是,如果您的页面在加载上使用了大量Ajax,那么WebDriver可能不知道何时完全加载它。如果您需要确保已满载此类页面,则可以使用等待。

我不确定Websockets的工作原理,而是在插座上,当您连接到远程服务器时,您会在块中接收数据。因此,要接收整个响应,您应该在循环中进行操作,然后执行此操作,直到您得到比块长度较小的块,我的意思是,当您的块是4096比较时,最后一个块将是0或x<4096,其中x是长度是收到的部分。因此,有了这些信息,您知道所有数据都是从远程服务器收到的。请阅读有关插座的信息。

最新更新