通过命令行或本地脚本与浏览器JavaScript进行交互?

7
我们提供类似于ImageMagick的浏览器页面JavaScript,可帮助人们将图像转换为不同的大小和格式。但是,它需要网页交互。
是否可能让人们自动化这种交互--而无需将图像发送到我们的服务器(从而增加带宽成本和服务器负载)无需要求用户下载像Puppeteer这样的无头浏览器库?
例如,以下流程是否可行:
  1. 通过命令行(或本地脚本)打开Chrome到特定的网页。
  2. 将图像上传到该网页。
  3. 调用网页上的脚本。
  4. 接收脚本结果并允许进行本地操作。
启动Chrome是可能的,但不清楚在启动后是否可以与特定的浏览器窗口交互。

理想情况如问题所述,但从概念上讲,目标是让开发人员重用此图像代码(这样他们就不需要编写自己的代码或处理imagemagick),同时不会给我们的服务器带来负担,因此如果您能实现概念目标,可以建议其他上下文。@Nicolas - Crashalot
请通过一个纯粹的.js脚本来提供您的代码,然后您可以将其提供给开发人员,他们可以通过脚本标签将其包含在自己的网站中或者下载并在本地使用。您所需要做的就是提供这个脚本。 - MauriceNino
你也可以将它提供为一个npm模块。这样用户就可以方便地将你的代码集成到他们的产品中。如果你想确保用户可以从CLI中使用它,你可以提供一个像这样的接口:https://blog.bitsrc.io/how-to-build-a-command-line-cli-tool-in-nodejs-b8072b291f81 - MauriceNino
这些都是不错的建议,但它们仍需要开发人员在更新时修补代码。也许我们只需承担带宽费用,但强制在浏览器中进行客户端处理。 - Crashalot
你应该能够与 Chrome 无头浏览器进行交互...但是如果你不想捆绑 Puppeteer,那么你就必须自己手动编写交互...这甚至更糟糕。 - Christopher Francisco
显示剩余12条评论
3个回答

5

理论上是可以自动化的,但实现起来却不容易。

你的问题可以分为两部分:离线处理和上传自动化。


离线处理

假设你的图像处理代码完全由浏览器JavaScript编写(而不是调用本地库的模块化node程序),则可以全部在浏览器中进行处理。

“上传”的文件可以被读取、处理并下载,而无需将任何内容发送到服务器。 处理甚至可以在后台线程中进行,使用户界面保持响应,例如一个漂亮的进度条。

代码本身可以使用Service Worker或静态html+javascript在线托管。 一旦访问或部署,两者都可以脱机打开和执行。 (请注意,Chrome严重限制静态html,包括对Web Workers的严格限制。Google更喜欢您保持联网状态。)


上传自动化

如上所述,通过文件输入选择或拖入浏览器的文件可以由页面中的JavaScript读取,但出于传统原因,我仍然将其称为“上传”操作。

Chrome有一些自动化扩展程序,尤其是Kantu,但由于Chrome的安全限制,它们无法处理文件上传。

因此,如果您想自动选择文件,需要使用本地的、超出浏览器范围的自动化工具,例如Kantu的XModulesAutoHotkeySikuliX。商业解决方案存在,但考虑到您的非常规要求(不能使用无头浏览器),也存在类似的限制。

  • AutoHotkey将专注于模拟键盘操作(打开浏览器,等待5秒钟,按Tab键10次,按回车键,等待2秒钟,输入文件名等),并可以编译成可部署的exe。

  • Sikulix更强大,但也更难分发;仅Java运行时就比浏览器更大。

  • Kantu + XModules介于两者之间。用户需要安装浏览器扩展程序和其本地扩展程序,但一旦完成,所有操作都在浏览器内部进行(或多或少)。

这三种方法都涉及模拟输入文件名,因为据我所知,在用户启动的(非无头)Chrome中自动化没有更简单的方法。

文件名可以作为参数传递给AutoHotkey和Sikulix的命令行,或在Kantu脚本中存储在文件中并读取。

在这三种情况下,自动化模拟了用户,真实用户在脚本运行时不得触摸计算机,否则自动化将停止。


那命令行呢?

或者,如果您的目标是自动化而不部署浏览器,则可以考虑将其制作为命令行Node.js程序,并将其打包为exe。

可分发的内容比编译后的AutoHotkey重,但移动部件要少得多,因此更可靠:

  • 独立于Chrome版本或XModules的存在。
  • 所有处理都在自己的进程中进行,而不是劫持用户的Chrome。
  • 可以无头执行,对于自动化非常重要。
  • 灵活的命令行参数。

但我喜欢浏览器自动化,它很简单

再想一想。

从我的经验来看,许多事情会使浏览器/GUI自动化失效:

  1. 不寻常的屏幕分辨率、浏览器缩放、操作系统缩放或最后记住的Chrome大小,会使您的页面变形不成。
  2. 更改页面元素的浏览器扩展程序,例如广告拦截程序。
  3. 使用热键拦截键盘输入的IME和其他程序。
  4. 弹出式程序,例如防病毒软件、Windows更新或插入CD。
  5. 意外锁定、休眠、注销、键盘上留下的键或电源中断。
  6. 或一个简单的Chrome更新会破坏您依赖的100个事情中的任何一个。

所以,是的,这就是为什么计算机自动化最好无头执行的原因。


我的代码会安全吗?

如果您担心脚本的安全性,请放心。 一旦您想要在客户端上处理,猫就跑了。

从技术上讲,您的代码受版权保护。但是如果你想执行保护工作,祝你好运。 如果您希望使您的代码免于被提取/解密/反混淆等操作(咳咳),您需要将其保持为在线黑盒子,不进行客户端处理。


非常感谢!不用担心代码盗窃,只是想让这项服务可用而无需额外的服务器/带宽费用(超出加载页面之外),并且比发布开源代码更容易消费。不幸的是,看起来这是不可能的,因为你们的解决方案需要额外的下载。一旦页面加载完毕,只要有一种方式与页面JavaScript交互,该服务理论上应该可以离线工作。 - Crashalot
@Crashalot 在你的情况下,客户端处理似乎是比较容易的部分。上传要求才是有问题的地方。经过几十年的滥用后,浏览器现在非常安全,因此无法从浏览器内部读取本地图像文件(或跨站点图像)。Chrome正在尝试使用本机文件系统API,但我认为这是一个非常高风险的功能,所以我建议不要依赖它。还有Chrome应用程序,但我缺乏相关经验。 - Sheepy
是的,客户端处理很容易。关键是在不产生带宽费用的情况下传输原始和转换后的图像。如果您想到其他方法,请分享。否则,非常感谢您迄今为止的帮助! - Crashalot
@Crashalot 抱歉我们似乎使用了不同的术语。假设你的代码是JavaScript,那么在浏览器中完成这些操作几乎是轻而易举的。数据URI转换器就是一个例子。我的答案中有关于离线处理部分读取和输出文件的链接,只要文件是由用户加载和保存的。这是你想要做的吗? - Sheepy
是的,代码是用JS编写的,而且很简单。不幸的是,不同平台需要进行调整大小,开发人员经常自己编写这个微不足道的代码。这只是一个烦恼,没有人应该去处理它,所以我们想要免费提供我们的版本作为服务,这样人们就可以专注于重要的代码。一种选择是开源代码,但我们想要让它更简单,并提供服务,这样人们就不需要处理更新或首次安装代码的问题。挑战在于避免带宽费用过高。 - Crashalot
显示剩余2条评论

2

围绕您的Web应用程序构建的一种方法是:

1)将console.log重定向到标准输出(请参见此处:在Chrome中,如何将JavaScript控制台输出重定向到标准输出/标准错误),可能需要适当的--log-level标志和将错误消息重定向到其他位置,以便某些随机消息不会破坏整个过程,

2)从脚本级别开始/除了保存结果文件之外,以Base64格式记录console.log信息,

3)从CLI侧面,使用一个管道(管道),使Base64成为一个合适的文件(以及任何其他处理)。


这很有趣。你以前试过吗?这种方法没有任何陷阱或潜在的问题吗? - Crashalot
1
不,这只是我在构思想法。 - mbojko
我明白了,这是一个聪明的主意。 :) 你看到没有绕过服务器上传图像到网页的方法?在 curl 命令中 POST 图像可以工作,但会导致我们产生带宽费用。 - Crashalot

1
使用PowerShell可以实现所有这些功能。使用PowerShell,您可以打开浏览器(IE会更容易,因为它是自然支持的)。您可以打开网页,填写表单,下载或上传数据,获取对象,检查等等。
访问以下网页以获取更多详细信息:
希望这能帮到您。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接