使用Selenium 2和Browsermob在新页面之前捕获click har

时间:2016-02-24 19:33:24

标签: python selenium browsermob

我有这个自动化工具,我使用Selenium 2和Browsermob代理构建,可以很好地满足我的需要。但是,我在捕获网络流量方面遇到了麻烦。

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

我目前的所有尝试都是太晚了,所以我看到点击分析调用和页面加载一个。有没有办法让这个工作?我已将我目前的相关代码部分包括在下面

在帮助类内部的方法
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

您可以从这些情节片段中看到我发起了&#34;点击&#34;返回网络流量的功能。在click函数中,您可以看到它引用了类&#34; _check_for_page_load&#34;。但是,它第一次到达这一行:

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

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

1 个答案:

答案 0 :(得分:0)

我找到了解决自己问题的方法 - 虽然它并不完美。我告诉我的网络电话来捕获标题:

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

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

这符合我的需要,但并不完美。某些内容(如图像请求)有时会获得与上一页网址匹配的引荐来源相同的内容,因此拆分会将这些内容放入第一个存储桶而不是相应的第二个存储桶中。但是,由于我对不在同一个域中的请求更感兴趣,因此这不是一个问题。