AngleSharp 表单提交示例
标准表单
动态 DOM 所需的功能之一就是提交表单的能力。使用 AngleSharp 提交表单可以非常简单:
IBrowsingContext context = BrowsingContext.New(Configuration.Default.WithDefaultLoader());
IDocument queryDocument = await context.OpenAsync("https://google.com");
IHtmlFormElement form = queryDocument.QuerySelector<IHtmlFormElement>("form");
IDocument resultDocument = await form.SubmitAsync(new { q = "anglesharp" });
// 例如,输出搜索结果的链接:resultDocument.QuerySelectorAll<IHtmlAnchorElement>("#ires .g h3.r a").Select(m => m.Href).Dump();
上述示例使用了 IHtmlFormElement
的 SubmitAsync
方法的一个特殊重载,它允许我们传入一个匿名对象,该对象由表单字段名及其期望值组成。或者,我们也可以编写如下代码:
// ...
var queryInput = form.Elements["q"] as IHtmlInputElement;
if (queryInput != null)
{
queryInput.Value = "anglesharp";
}
后一种版本更为冗长,并要求我们在代码中进行额外的检查。这种版本的优点是,我们可以处理错误情况(即,预期名称为 q
的字段未找到或不是 IHtmlInputElement
),而在前一种版本中这种情况会被完全忽略。
提交表单的一个重要方面是,我们至少需要一个默认加载器。表单通常需要发出 HTTP 请求以加载新文档(主要使用 POST 动词),这就需要预先配置请求器。请注意,有时表单甚至会有更严格的要求,特别是当它们被正确保护时。在这种情况下,使用 WithCookies()
来配置一个 cookie 容器可能是必须的。
使用 cookie
容器的代码看起来几乎相同:
IConfiguration config = Configuration.Default
.WithDefaultLoader()
.WithCookies();
IBrowsingContext context = BrowsingContext.New(config);
// ...
AJAX / JavaScript 驱动的表单
AngleSharp
本身不提供 JavaScript
解析器或引擎。虽然存在一些库尝试解决这个问题,但目前没有库成熟或功能强大到足以普遍应对 JavaScript
驱动的表单。
一旦表单不再是真正的表单,而是依赖于 JavaScript
操作(或者只是使用一组输入字段来形成最终通过构造的 XHR
/ fetch
调用传输到服务器的数据集),AngleSharp
基本上就无能为力了。此时,您可以尝试逆向工程 JavaScript
的逻辑来执行相同的步骤并提交相同的数据。虽然 AngleSharp
在这里可能会有所帮助,但它肯定不是最大的助力,甚至可能没有任何帮助。