0

我有这个用 Selenium 2 和 Browsermob 代理构建的自动化工具,它可以很好地满足我的大部分需求。但是,我在捕获网络流量时遇到了障碍。

我基本上想在页面重定向之前捕获单击提供的 har。例如,我在要捕获的点击上发生了一个分析调用,然后在我不想捕获的页面加载上发生了另一个分析调用。

目前我所有的尝试都为时已晚,因此我看到了点击分析调用和页面加载调用。有什么办法可以让这个工作吗?我在下面包含了我当前的相关代码部分

帮助类内部的方法
class _check_for_page_load(object):
    def __init__(self, browser, parent):
        self.browser = browser
        self.maxWait = 5
        self.parent = parent

    def __enter__(self):
        self.old_page = self.browser.find_element_by_tag_name('html')

    def wait_for(self,condition_function):
        start_time = time.time()
        while time.time() < start_time + self.maxWait:
            if condition_function():
                return True
            else:
                time.sleep(0.01)
        raise Exception(
            'Timeout waiting for {}'.format(condition_function.__name__)
        )

    def page_has_loaded(self):
        new_page = self.browser.find_element_by_tag_name('html')
        ###self.parent.log("testing ---- " + str(new_page.id) + " " + str(self.old_page.id))
        return new_page.id != self.old_page.id

    def __exit__(self, *_):
        try:
            self.wait_for(self.page_has_loaded)
        except:
            pass


def startNetworkCalls(self):
    if self._p != None:
        self._p.new_har("Step"+str(self._currStep))


def getNetworkCalls(self, waitForTrafficToStop = True):
    if self._p != None:
        if waitForTrafficToStop:
            self._p.wait_for_traffic_to_stop(5000, 30*1000);
        return self._p.har
    else:
        return "{}"    


def click(self, selector):
    ''' clicks on an element '''
    self.log("Clicking element '" + selector + "'")
    el = self.findEl(selector)
    traffic = ""

    with self._check_for_page_load(self._d, self):
        try:
            self._curr_window = self._d.window_handles[0]
            el.click()
        except:
            actions = ActionChains(self._d);
            actions.move_to_element(el).click().perform()
    traffic = self.getNetworkCalls(False)

    try:
        popup = self._d.switch_to.alert
        if popup != None:
            popup.dismiss()
    except:
        pass
    try:
        window_after = self._d.window_handles[1]
        if window_after != self._curr_window:
            self._d.close()
            self._d.switch_to_window(self._curr_window)
    except:
        pass

    return traffic
运行多个硒操作的内部文件
##inside a for loop, we get an action that looks like "click('#selector')"
util.startNetworkCalls()
if action.startswith("click"):
    temp_traffic = eval(action)


if temp_traffic == "":
    temp_traffic = util.getNetworkCalls()
traffic = json.dumps(temp_traffic, sort_keys=True) ##gives json har info that is saved later

您可以从这几个片段中看到我启动了返回网络流量的“点击”功能。在 click 函数中,您可以看到它引用了“_check_for_page_load”类。但是,它第一次到达这条线:

###self.parent.log("testing ---- " + str(new_page.id) + " " + str(self.old_page.id))

日志(启用时)显示元素 ID 在第一次记录时不匹配,这表明页面加载已经开始发生。我现在很困惑,因为我已经尝试了我能想到的一切来尝试完成这个功能。

4

1 回答 1

0

我找到了解决我自己问题的方法——尽管它并不完美。我告诉我的网络调用来捕获标头:

def startNetworkCalls(self):
    if self._p != None:
        self._p.new_har("Step"+str(self._currStep),{"captureHeaders": "true"})

然后,当我检索 har 数据时,我可以查找“Referer”标题并将其与最初加载的页面(在单击重定向之前)进行比较。从那里,我可以将 har 拆分为两个单独的网络调用列表,以便以后进一步处理。

这可以满足我的需要,但并不完美。有些事情,比如图像请求,有时会得到与前一页的 url 匹配的相同引用,因此拆分会将它们放入第一个存储桶而不是适当的第二个存储桶。但是,由于我对不在同一个域中的请求更感兴趣,所以这不是一个真正的问题。

于 2016-02-29T22:12:32.590 回答