Съемка клика хар перед новой страницей с Selenium 2 и 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

Из этих пар фрагментов видно, что я запускаю функцию "щелчка", которая возвращает сетевой трафик. Внутри функции click вы можете видеть, что она ссылается на класс "_check_for_page_load". Однако в первый раз он достигает этой строки:

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

Журнал (если он включен) показывает, что идентификаторы элементов не совпадают при первом входе в систему, что указывает на то, что загрузка страницы уже началась. Я сейчас застрял, потому что перепробовал все, что мог придумать, чтобы реализовать эту функциональность.

1 ответ

Решение

Я нашел решение своего собственного вопроса - хотя он не идеален. Я сказал своим сетевым вызовам захватывать заголовки:

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

Затем, когда я получаю данные har, я могу найти заголовок "Referer" и сравнить его со страницей, которая была первоначально загружена (до перенаправления с клика). Оттуда я могу разбить хар на два отдельных списка сетевых вызовов для дальнейшей обработки позже.

Это работает для моих нужд, но не идеально. Некоторые вещи, такие как запросы изображений, иногда получают тот же реферер, с которым совпал URL предыдущей страницы, поэтому разбиение помещает их в первый сегмент, а не в соответствующий второй. Однако, так как меня больше интересуют запросы, которые не относятся к одному домену, это на самом деле не проблема.

Другие вопросы по тегам