根据客户端不提供aspNetHidden div

Ces*_*Gon 6 html c# asp.net dotnet-httpclient

我正在开发一个 C# 应用程序,它可以获取网页并逐行处理它们的内容。为此,我使用HttpClient该类,并通过ReadAsStreamAsync(). 然后我将流读入一个线数组并对其进行迭代。到现在为止还挺好。

但是,如果我使用 Chrome 或 Edge 导航到网页并使用“查看源”获取 HTML,我使用此方法获得的 HTML 与我观察到的 HTML 不同。特别是,__VIEWSTATE 和 __VIEWSTATEGENERATOR 隐藏input元素被div具有以下元素的元素包围class="aspNetHidden",当我使用的浏览器,而不是当我编程方式获得的HTML。这破坏了我的行跟踪逻辑,因为浏览器看到的页面中有额外的行,与我在代码中获取的页面相关。

编辑。经过一些测试,我确信客户端使用的用户代理标头决定了是否class="aspNetHidden" div提供服务。当我模仿浏览器的用户代理(“Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36 Edg/83.0.478.37”)时,服务div是 如果我使用其他代理,例如“测试客户端”,div则不会提供服务。

我的问题是,是否有任何文档说明哪些用户代理字符串会导致div提供服务,哪些不提供服务?另外,我可以防止这种情况发生吗?

谢谢。

pfx*_*pfx 3

简而言之,它不是根据用户代理来记录/指定的,而是根据浏览器功能来记录/指定的。

基于浏览器的用户代理,设置了一组功能。
这些功能在网络服务器上的配置文件中配置.browser
例如,您可以在、 例如、等.NET 4中找到这些文件。%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\config\browsers
chrome.browseriphone.browser

这样的.browser文件包含一种tagwriter能力。
例如chrome.browser

<browsers>
    <!-- Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/530.1 (KHTML, like Gecko) Chrome/2.0.168.0 Safari/530.1 -->
    <browser id="Chrome" parentID="WebKit">
        <identification>
            <userAgent match="Chrome/(?'version'(?'major'\d+)(\.(?'minor'\d+)?)\w*)" />
        </identification>

        <capabilities>
          <capability name="browser"   value="Chrome" />
          <capability name="tagwriter" value="System.Web.UI.HtmlTextWriter" />

          <!-- ... -->  
        </capabilities>
    </browser>
</browsers> 
Run Code Online (Sandbox Code Playgroud)

tagwriter功能指定是否将 aSystem.Web.UI.HtmlTextWriter或 aSystem.Web.UI.Html32TextWriter实例化以写入输出。

文件中的默认配置Default.browser声明tagwriter为:

<capability name="tagwriter" value="System.Web.UI.Html32TextWriter" />
Run Code Online (Sandbox Code Playgroud)

此外,如果tagwriter缺少该功能,Html32TextWriter则会使用正在使用的功能。
来自微软参考来源

internal HtmlTextWriter CreateHtmlTextWriterInternal(TextWriter tw) {
    Type tagWriter = TagWriter;
    if (tagWriter != null) {
        return Page.CreateHtmlTextWriterFromType(tw, tagWriter);
    }

    // Fall back to Html 3.2
    return new Html32TextWriter(tw);
}
Run Code Online (Sandbox Code Playgroud)

声明Html32TextWriter不渲染div隐藏输入字段周围的区域。
来自微软参考来源

internal override bool RenderDivAroundHiddenInputs {
    get {
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

至于是否HtmlTextWriter返回,请参阅Microsoft 参考源trueRenderDivAroundHiddenInputs

在这里阅读更多有关这一切的内容。


你可以做什么。

如果您总是想要包装div,请使用众所周知的用户代理之一,否则使用像您Test Client已经使用的自定义用户代理。如果您控制所请求的网站,您可以为自定义用户代理
设置自定义文件......但我宁愿不这样做.......browser

发出请求时,只需User-Agent在您的 上设置适当的请求标头HttpClient,例如:

var client = new HttpClient();
var userAgent = "Test Client"; // Or "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36 Edg/83.0.478.37"
client.DefaultRequestHeaders.Add("User-Agent", userAgent);
Run Code Online (Sandbox Code Playgroud)