【问题标题】:Get requests body using selenium and proxies使用 selenium 和代理获取请求正文
【发布时间】:2019-05-01 06:02:32
【问题描述】:

我希望能够使用代理后面的 selenium 获取特定子请求的主体。

现在我正在使用 python + selenium + chromedriver。通过日志记录,我可以获取每个子请求的标头,但不能获取正文。我的日志记录设置:

caps['loggingPrefs'] = {'表现':'所有', “浏览器”:“全部”}

caps['perfLoggingPrefs'] = {"enableNetwork": True, “启用页面”:真, “启用时间线”:真}

我知道有几种选择可以用硒形成 HAR:

window.foo = HAR.triggerExport().then(harLog => { return(harLog); }); 返回window.foo;

很遗憾,我在返回的数据中没有看到响应的正文。

  • 使用 browsermob 代理。该解决方案似乎完全没问题,但我没有找到让 browsermob 代理在代理后面工作的方法。

所以问题是:如何在使用 selenium 和使用代理的网页下载过程中获取特定网络响应的主体。

UPD:实际上,har-export-trigger 我得到了响应正文,但不是全部:我需要的响应正文是 json,它的 MIME 类型是 'text/html; charset=utf-8' 并且我生成的HAR文件中缺少它,因此仍然缺少解决方案。

UPD2:经过进一步调查,我意识到当har-export-trigger 附加组件打开时,即使在我的桌面Firefox 上也缺少响应正文,因此此解决方案可能是死胡同(issue on Github

UPD3:只有最新版本的 har-export-trigger 才能看到此错误。使用版本 0.6.0。一切正常。

因此,对于未来的谷歌员工:您可以使用 har-export-trigger v. 0.6.0。或接受答案的方法。

【问题讨论】:

  • 您需要调用 JSON.stringify(harLog) 将 webdriver 中的 json 对象转换为 python 调用者脚本。你可以在答案中看到我的实现

标签: python-3.x selenium selenium-webdriver browsermob-proxy


【解决方案1】:

我实际上刚刚使用问题中提到的工具实现了一个 selenium HAR 脚本。从 har-export-trigger 和 BrowserMob 获取的 HAR 均通过 Google HAR Analyser 进行验证。

使用 selenium、gecko 驱动程序和 har-export-trigger 的类:

class MyWebDriver(object):
    # a inner class to implement custom wait
    class PageIsLoaded(object):
        def __call__(self, driver):
            state = driver.execute_script('return document.readyState;')
            MyWebDriver._LOGGER.debug("checking document state: " + state)
            return state == "complete"

    _FIREFOX_DRIVER = "geckodriver"
    # load HAR_EXPORT_TRIGGER extension
    _HAR_TRIGGER_EXT_PATH = os.path.abspath(
        "har_export_trigger-0.6.1-an+fx_orig.xpi")
    _PROFILE = webdriver.FirefoxProfile()
    _PROFILE.set_preference("devtools.toolbox.selectedTool", "netmonitor")
    _CAP = DesiredCapabilities().FIREFOX
    _OPTIONS = FirefoxOptions()
    # add runtime argument to run with devtools opened
    _OPTIONS.add_argument("-devtools")
    _LOGGER = my_logger.get_custom_logger(os.path.basename(__file__))

    def __init__(self, log_body=False):
        self.browser = None
        self.log_body = log_body

    # return the webdriver instance
    def get_instance(self):
        if self.browser is None:
            self.browser = webdriver.Firefox(capabilities=
                                             MyWebDriver._CAP,
                                             executable_path=
                                             MyWebDriver._FIREFOX_DRIVER,
                                             firefox_options=
                                             MyWebDriver._OPTIONS,
                                             firefox_profile=
                                             MyWebDriver._PROFILE)
            self.browser.install_addon(MyWebDriver._HAR_TRIGGER_EXT_PATH,
                                       temporary=True)
            MyWebDriver._LOGGER.info("Web Driver initialized.")
        return self.browser

    def get_har(self):
        # JSON.stringify has to be called to return as a string
        har_harvest = "myString = HAR.triggerExport().then(" \
                      "harLog => {return JSON.stringify(harLog);});" \
                      "return myString;"
        har_dict = dict()
        har_dict['log'] = json.loads(self.browser.execute_script(har_harvest))
        # remove content body
        if self.log_body is False:
            for entry in har_dict['log']['entries']:
                temp_dict = entry['response']['content']
                try:
                    temp_dict.pop("text")
                except KeyError:
                    pass
        return har_dict

    def quit(self):
        self.browser.quit()
        MyWebDriver._LOGGER.warning("Web Driver closed.")

添加 BrowserMob 代理的子类也供您参考:

class MyWebDriverWithProxy(MyWebDriver):

    _PROXY_EXECUTABLE = os.path.join(os.getcwd(), "venv", "lib",
                                     "browsermob-proxy-2.1.4", "bin",
                                     "browsermob-proxy")

    def __init__(self, url, log_body=False):
        super().__init__(log_body=log_body)
        self.server = Server(MyWebDriverWithProxy._PROXY_EXECUTABLE)
        self.server.start()
        self.proxy = self.server.create_proxy()
        self.proxy.new_har(url,
                           options={'captureHeaders': True,
                                    'captureContent': self.log_body})
        super()._LOGGER.info("BrowserMob server started")
        super()._PROFILE.set_proxy(self.proxy.selenium_proxy())

    def get_har(self):
        return self.proxy.har

    def quit(self):
        self.browser.quit()
        self.proxy.close()
        MyWebDriver._LOGGER.info("BroswerMob server and Web Driver closed.")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-03
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 2020-11-04
    • 1970-01-01
    • 2015-07-10
    相关资源
    最近更新 更多