c# - 如何在 Azure 托管网站上设置浏览器模拟
问题描述
在尝试决定采取哪条路线之前,我想检查一下我是否已经考虑了所有选择。
我目前已经将一个小型网站部署到免费层 Azure AppService(.NET Core + SQL Server,在他们会给你的免费微型 SQL DB 上)
我希望这个站点能够获取一些需要浏览器模拟的幕后数据。
- 我的浏览器模拟最终是从浏览器屏幕上抓取一些信息,并下载并保存文件,但我必须模拟登录和复杂的导航,所以我认为它需要是一个完整的浏览器模拟,而不仅仅是手动发送 HTTP 请求,为了在没有对目标站点进行大量逆向工程的情况下工作。
- 我正在抓取的网站预计不会被抓取,并且没有任何我可以使用的 API。
- 为避免任何疑问,我所做的抓取绝对不是非法或不道德的。可以想象它会破坏一些 Ts&C,但我已经在单独检查它。
- 这是一个个人项目,因此重要的是我要让它适合可以免费托管的内容。
我认为这很简单——我只需要在我的站点中运行 Selenium。
唉,我发现 AppServices 不支持安装 Chrome 或类似的,而且 Selenium 可能无论如何都无法工作。(引文)
有哪些方法可以解决这个问题? 我认为我可以:
- 将我的 Azure 设置为 VM
- 让我完全控制托管环境。
- 更多的 DevOps 工作。
- 我在 Azure 中没有看到明显的免费 VM 选项。
- “在容器中进行”。
- 我发现一个消息来源暗示容器将允许浏览器安装,但保持较低的 DevOps 开销。
- 我认为 Azure确实免费支持 Kubernetes。
重新构建我的代码,使其不会尝试模拟浏览器,而只是猜测正确的 HTTP 请求。- (我认为这是一个难以置信的大量开发工作)
- 使用其他一些纯 C# 浏览器模拟。?头孢夏普?
- 我认为当前的症结在于 Selenium 要求 Chrome 与我正在运行的 C# 应用程序分开存在。如果我可以使“浏览器”成为 C# 的直接部分,也许效果会更好?
- 看起来
CefSharp
可能无需安装单独的 Chrome 实例就可以模拟 Chromium,那么这是一个可行的选择吗? - 可能会遇到与 AppServices 相同的“不受支持”的问题。
- 我认为这种方法可能会失去使用起来非常愉快的 IWebDriver 界面,尽管 :(
- 不要在 Azure 上托管。
- 可能涉及某种自托管,我设置我的个人计算机来托管该站点,并通过适当的 IP 映射、防火墙开放和其他 DevOps 问题将该站点公开给全世界。
还有其他我不知道的选择吗?(尤其是 Azure 中内置的!)
我上面列出的选项中还有其他考虑因素吗?
解决方案
我已经这样做了:
CefSharp(您可以设置用户代理来模拟 chrome 版本)(无头模式)。
Docker 容器(代理)中的 .NET Core 控制台应用程序,用于处理来自 Azure 服务队列的请求。这将允许您扩展您的代理并获得更多可用性。如果没有 VM,我认为你不能仅仅因为无服务器的图形支持限制。
这是此映像的 docker 示例,用于在构建时下载并安装 .net 框架:
FROM microsoft/windowsservercore
ADD . /ScrapingService
WORKDIR /ScrapingService
ADD https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe /vc_redist.x64.exe
RUN C:\vc_redist.x64.exe /quiet /install
ENTRYPOINT ["cmd.exe", "/k", "Scraper.exe"]
- Selenium 与 ChromeDriver。
当一切正常时,在本地测试这个(没有无头模式)构建一个 docker 映像并将其部署到 Azure。
您可以通过创建一个容器化的 .net 控制台应用程序,在本地运行它然后部署它来做到这一点。对您的方法的一个警告是,如果网站更改其结构,您将不得不重新制定您的抓取规则,如果网站使用验证码,您无法抓取它,如果您发送许多请求,它可能会在网站上触发警报尽可能攻击。
推荐阅读
- c# - 如果条件满足,C# double for loop stringbuilder
- angular - 当我们使用 this.sanitizer.bypassSecurityTrustHtml(value) 时如何停止重新渲染 html?
- foreach - Mule ForEach 无法获得第一个值
- php - 如何让字符串类型变成数组类型
- jquery - Ajax 和 jQuery 页面重载
- embedded - 为什么 u-boot "gzwrite" 命令不能正常工作?
- reactjs - 如何在 React 中单击按钮时获取文本框值?
- javascript - 如何在 TypeScript 中重用参数类型声明
- c# - 是否可以防止 Trim() 删除空格?
- intellij-idea - Intellij 中的“运行”选项卡消失了