【发布时间】:2018-02-05 19:56:30
【问题描述】:
我在 Mac 上使用 Python、Jupyter、Selenium webdriver 和无头 Chrome(带有 Canary)。
我写了一个脚本来抓取一个非常旧的网站, 为了从该网站下载文件,我需要点击几个按钮,最终将我带到一个按钮,一旦点击它就会下载一个 CSV 文件
问题是,当无头 Chrome 尝试下载目标文件时,它会挂起并且什么都不做(即不下载所需的文件),即使脚本完成运行(是的,我确实在脚本末尾关闭了它)
我试过了:
- 下载其他文件(来自不同网站)和无头 Chrome 似乎可以毫无问题地下载它们(我启用了无头 chrome 选项以成功下载文件)
- 拍摄网站快照以确保其正确导航到下载页面(是的,其导航正确)
- 修改用户代理(它似乎正在使用我期望的用户代理)
- 在没有 headless 选项的情况下运行完全相同的代码 - 它使用常规 chrome 成功下载文件
- 使用
driver.execute_script(js_that_changes_plugins_and_langs)更改驱动程序上的插件和语言 JS 脚本,但我不太确定如何检查它是否真的在执行它(它仍然不工作)
我面临的问题:
- 我找不到只获取最后一个下载 URL 的方法,因为它似乎使用了一些沿途生成的唯一 ID(当您转到主页和在网站中的页面之间导航时给出)所以每次会话都会发生变化
- 导航 URL 似乎来自主页内的 iframe(以及以下 URL),我不太清楚如何检查它生成的 Javascript
我提供网站 URL 没有任何问题,但是:
- 您必须在不同的页面上点击大约 6 次才能到达带有下载按钮的最后一页。这些点击并不直观,需要大量时间才能解释如何导航到我想要的位置
- 此网站不是英文的,因此更难解释如何导航
与常规 Chrome 相比,我需要它是无头的,因为我们要运行代码的机器非常弱,无法运行 chrome GUI
所以我的问题是:有谁知道这可能是什么问题?或者至少,我该如何调试它?
这或多或少是我正在使用的代码:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
def enable_download_in_headless_chrome(driver, download_dir):
"""
there is currently a "feature" in chrome where
headless does not allow file download: https://bugs.chromium.org/p/chromium/issues/detail?id=696481
This method is a hacky work-around until the official chromedriver support for this.
Requires chrome version 62.0.3196.0 or above.
"""
# add missing support for chrome "send_command" to selenium webdriver
driver.command_executor._commands["send_command"] = ("POST", '/session/' + driver.session_id + '/chromium/send_command')
params = {'cmd': 'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': download_dir}}
command_result = driver.execute("send_command", params)
print("response from browser:")
for key in command_result:
print("result:" + key + ":" + str(command_result[key]))
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('headless')
chrome_options.add_argument('no-sandbox')
chrome_options.add_argument('disable-gpu')
chrome_options.add_argument('remote-deubgging-port=9222')
chrome_options.add_argument('disable-popup-blocking')
chrome_options.add_argument('enable-logging')
download_dir = # some path here
driver = webdriver.Chrome(chrome_options=chrome_options)
enable_download_in_headless_chrome(driver, download_dir)
ok_button = driver.find_element_by_id('the-button-name')
ok_button.click()
感谢您的帮助
【问题讨论】:
-
你试过加
user-agent吗?还有其他技术可以检测无头 Chrome 以让服务器决定做什么(例如中断下载),您可能需要查看 intoli.com/blog/making-chrome-headless-undetectable -
也可以看看at this,这基本上是对@hurturk 建议的跟进。
-
具体挂在哪一点?在哪一行代码之后?您是否检查了运行浏览器进程的用户具有写入权限的“下载”目录?
-
您可以使用 zaproxy 监控请求以进行调试。
-
我确实尝试通过添加
user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36' chrome_options.add_argument(f'user-agent={user_agent}')来使用用户代理,但它仍然不起作用,我需要确保您提供的链接中建议的其他选项也设置正确它挂起点击之后。我看到无头 chrome 已打开(当我 alt 选项卡时)但没有任何反应。我会看看 zaproxy 感谢您的建议:)
标签: python python-3.x selenium-webdriver google-chrome-headless