无法使用带有 BrowserMob-Proxy 的 Python Selenium 脚本捕获 HAR

Posted

技术标签:

【中文标题】无法使用带有 BrowserMob-Proxy 的 Python Selenium 脚本捕获 HAR【英文标题】:Can't capture HAR using Python Selenium Script with BrowserMob-Proxy 【发布时间】:2014-11-19 15:18:08 【问题描述】:

目标: 我想通过 BrowserMob-Proxy 运行一个 Selenium Python 脚本,它将捕获并输出一个 HAR 文件捕获。

问题: 我有一个功能性(非常基本的)Python 脚本(如下所示)。然而,当它被更改为使用 BrowserMob-Proxy 来捕获 HAR 时,它会失败。下面我提供了两个不同的脚本,它们都失败了,但是出于不同的原因(在代码 sn-ps 之后提供了详细信息)。

BrowserMob-Proxy 说明: 如前所述,我同时使用 0.6.0 和 2.0-beta-8。这样做的原因是 A) LightBody(BMP 的首席设计师)最近表示他的最新版本(2.0-beta-9)没有功能,并建议用户改用 2.0-beta-8 和 B)尽我所能从阅读各种站点/*** 信息可以看出,0.6.0(通过 PIP 获取)用于调用 Client.py/Server.py,而 2.0-beta-8 用于启动服务器。老实说,这让我很困惑。然而,当导入 BMP 的服务器时,它需要一个批处理 (.bat) 文件来启动服务器,这在 0.6.0 中没有提供,但在 2.0-beta-8 中提供......如果有人能对这个领域有所了解的话困惑(我怀疑这是我下面描述的问题的根源),那么我将不胜感激。

软件规格:

操作系统:Windows 7 (64x) -- 在 VirtualBox 中运行 浏览器:FireFox (32.0.2) 脚本语言:Python (2.7.8) 自动 Web 浏览器:Selenium (2.43.0) -- 通过 PIP 安装 BrowserMob-Proxy:0.6.0 AND 2.0-beta-8 -- 请参阅下面的说明

Selenium 脚本(此脚本有效):

"""This script utilizes Selenium to obtain the Google homepage"""
from selenium import webdriver

driver = webdriver.Firefox()       # Opens FireFox browser.
driver.get('https://google.com/')  # Gets google.com and loads page in browser.

driver.quit()                      # Closes Firefox browser

此脚本成功运行并且不会产生任何错误。它是为了说明目的而提供的,以表明它在添加 BMP 逻辑之前可以工作。

使用 BMP 编写 ALPHA(不起作用):

"""Using the same functional Selenium script, produce ALPHA_HAR.har output"""
from browsermobproxy import Server
server = Server('C:\Users\Matt\Desktop\\browsermob-proxy-2.0-beta-8\\bin\\browsermob-proxy')
server.start()
proxy = server.create_proxy()

from selenium import webdriver
driver = webdriver.Firefox()           # Opens FireFox browser.

proxy.new_har("ALPHA_HAR")             # Creates a new HAR
driver.get("https://www.google.com/")  # Gets google.com and loads page in browser.
proxy.har                              # Returns a HAR JSON blob

server.stop()

此代码将成功运行脚本并且不会产生任何错误。但是,在搜索整个硬盘驱动器时,我从未成功找到 ALPHA_HAR.har。

使用 BMP 编写 BETA 脚本(不起作用):

"""Using the same functional Selenium script, produce BETA_HAR.har output"""
from browsermobproxy import Server
server = Server("C:\Users\Matt\Desktop\\browsermob-proxy-2.0-beta-8\\bin\\browsermob-proxy")
server.start()    
proxy = server.create_proxy()

from selenium import webdriver
profile = webdriver.FirefoxProfile()
profile.set_proxy(proxy.selenium_proxy())
driver = webdriver.Firefox(firefox_profile=profile)

proxy.new_har("BETA_HAR")             # Creates a new HAR
driver.get("https://www.google.com/") # Gets google.com and loads page in browser.
proxy.har                             # Returns a HAR JSON blob

server.stop()

此代码取自 http://browsermob-proxy-py.readthedocs.org/en/latest/。运行上述代码时,FireFox 将尝试获取 google.com,但永远无法成功加载页面。最终它将超时而不会产生任何错误。而且 BETA_HAR.har 在我的硬盘上的任何地方都找不到。我还注意到,当尝试使用此浏览器访问任何其他站点时,它同样会无法加载(我怀疑这是由于代理配置不正确造成的)。

【问题讨论】:

【参考方案1】:

我用的是phantomJS,下面是一个如何与python一起使用的例子:

import browsermobproxy as mob
import json
from selenium import webdriver
BROWSERMOB_PROXY_PATH = '/usr/share/browsermob/bin/browsermob-proxy'
url = 'http://google.com'

s = mob.Server(BROWSERMOB_PROXY_PATH)
s.start()
proxy = s.create_proxy()
proxy_address = "--proxy=127.0.0.1:%s" % proxy.port
service_args = [ proxy_address, '--ignore-ssl-errors=yes', ] #so that i can do https connections
driver = webdriver.PhantomJS(service_args=service_args)
driver.set_window_size(1400, 1050)
proxy.new_har(url)
driver.get(url)
har_data = json.dumps(proxy.har, indent=4)
screenshot = driver.get_screenshot_as_png()
imgname = "google.png"
harname = "google.har"
save_img = open(imgname, 'a')
save_img.write(screenshot)
save_img.close()
save_har = open(harname, 'a')
save_har.write(har_data)
save_har.close()
driver.quit()
s.stop()

【讨论】:

【参考方案2】:

当你这样做时:

proxy.har

你需要解析那个响应,proxy.har是一个JSON对象,所以如果你需要生成一个文件,你需要这样做:

myFile = open('BETA_HAR.har','w')
myFile.write( str(proxy.har) )
myFile.close()

然后你会找到你的 .har

【讨论】:

【参考方案3】:

试试这个:

from browsermobproxy import Server
from selenium import webdriver
import json

server = Server("path/to/browsermob-proxy")
server.start()
proxy = server.create_proxy()
profile = webdriver.FirefoxProfile()
profile.set_proxy(self.proxy.selenium_proxy())
driver = webdriver.Firefox(firefox_profile=profile)
proxy.new_har("http://***.com", options='captureHeaders': True)
driver.get("http://***.com")    
result = json.dumps(proxy.har, ensure_ascii=False)
print result
proxy.stop()    
driver.quit()

【讨论】:

我遇到了错误。 Raceback(最近一次通话最后):文件“e:sample.py”,第 10 行,在 profile.set_proxy(self.proxy.selenium_proxy()) NameError: name 'self' is not defined【参考方案4】:

查找您的 HAR 文件

本质上,代理生成的 HAR 对象就是:内存中的一个对象。您无法在硬盘上找到它的原因是因为除非您自己将它写在那里,否则它不会保存在那里。这是一个非常简单的操作,因为 HAR 只是 JSON。

with open("harfile", "w") as harfile:
    harfile.write(json.dumps(proxy.har))

为什么 ALPHA 不起作用?

当您开始转储您的 HAR 文件时,您会发现您的 HAR 文件是空的,其中包含 ALPHA 脚本。这是因为您没有将代理添加到 Firefox 的设置中,这意味着它只会绕过您的代理直接连接。

测试版呢?

就连接到代理而言,此代码编写正确,尽管我个人更喜欢将代理添加到功能中并通过这些功能。代码是:

cap = webdriver.DesiredCapabilities.FIREFOX.copy()
proxy.add_to_capabilities(cap)
driver = webdriver.Firefox(capabilities=cap)

我猜你的问题在于代理本身。检查 python 脚本所在位置的 bmp.log 和/或 server.log 文件,如果出现问题,看看它在说什么。

另一种选择是 selenium 在实际完成获取所有元素之前报告网页已加载,因此您的代理关闭得太早了。尝试让脚本在关闭代理之前等待更长的时间,或者通过解释器以交互方式运行它。

【讨论】:

【参考方案5】:

对我有用的是将 java 版本降级到 java11。我使用 jenv 安装和管理多个 java 版本。

【讨论】:

以上是关于无法使用带有 BrowserMob-Proxy 的 Python Selenium 脚本捕获 HAR的主要内容,如果未能解决你的问题,请参考以下文章

Selenium通过设置代理实现抓取HTTPS请求

无法使用 % url % 模板标签正确生成带有捕获参数的 URL

无法使用 AFNetworking 发布带有数组的字典

无法使用存储过程过滤带有 % mysql 的行

无法使用带有自定义单元的 BaseButtonBarPagerTabStripViewController 连接 XLPagertabStrip 插座

我无法使用带有 jquery 的 Handsontable 加载数据