首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Frame/IFrame值中获取HtmlElement值?

如何在Frame/IFrame值中获取HtmlElement值?
EN

Stack Overflow用户
提问于 2018-11-09 02:12:54
回答 1查看 910关注 0票数 6

我正在使用Winforms WebBrowser控件从下面链接的站点收集视频剪辑的链接。

LINK

但是,当我逐个滚动元素时,我找不到<video>标记。

代码语言:javascript
复制
void webBrowser_DocumentCompleted_2(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    try
    {
        HtmlElementCollection pTags = browser.Document.GetElementsByTagName("video");
        int i = 1;
        foreach (HtmlElement link in links)
        {

            if (link.Children[0].GetAttribute("className") == "vjs-poster")
            {
                try
                {

                    i++;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
    }   // Added by edit
}

在使用

代码语言:javascript
复制
HtmlElementCollection pTags = browser.Document.GetElementsByTagName("video");

我已经返回0了

我需要调用ajax吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-09 08:17:07

您链接的网页包含IFrames

IFrame包含自己的HtmlDocument。到目前为止,您只解析了主文档容器。

因此,您需要解析其他一些FrameHtmlElements标记。

网页框架列表由返回HtmlWindowCollectionWebBrowser.Document.Window.Frames属性引用。

集合中的每个HtmlWindow都包含自己的HtmlDocument对象。

大多数情况下,我们需要解析Frames集合中的每个HtmlWindow.Document,而不是解析由WebBrowser返回的Frames对象属性;当然,除非我们已经知道所需的元素是主文档或另一个已知Frame的一部分。

示例(与当前任务相关):

  • 订阅WebBrowser Control/Class.

备注:

请记住,一个网页可能由Frame/IFrame中包含的多个文档组成,如果使用ReadyState = WebBrowserReadyState.Complete多次引发该事件,我们也不会感到惊讶。

WebBrowser加载完成后,每个帧的Document将引发事件。

备注:

由于DocumentCompleted事件被多次引发,因此我们需要验证HtmlElement属性值是否也没有多次存储。

在这里,我使用了一个支持自定义类,它包含所有收集的值以及每个引用链接的HashCode (在这里,依赖于GetHasCode()的默认实现)。

每次解析文档时,我们都会检查是否已经存储了一个值,并比较它的Hash。

  • 在确认找到重复的哈希时停止解析:框架文档元素已被提取。

便笺

在解析HtmlWindowCollection时,不可避免地会引发一些特定的异常:

  1. UnauthorizedAccessException:某些框架无法访问某些元素/后代无法访问。

我们无法避免这一点:元素不是null,当我们试图访问其属性的任何时,它们只是抛出这些异常。

在这里,我只是捕捉和忽略这些特定的异常:我们知道我们最终会得到它们,我们无法避免它,继续前进。

代码语言:javascript
复制
public class MovieLink
{
    public MovieLink() { }
    public int Hash { get; set; }
    public string VideoLink { get; set; }
    public string ImageLink { get; set; }
}

List<MovieLink> moviesLinks = new List<MovieLink>();

private void Browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    var browser = sender as WebBrowser;
    if (browser.ReadyState != WebBrowserReadyState.Complete) return;

    var documentFrames = browser.Document.Window.Frames;
    foreach (HtmlWindow Frame in documentFrames) {
        try {
            var videoElement = Frame.Document.Body
                .GetElementsByTagName("VIDEO").OfType<HtmlElement>().FirstOrDefault();

            if (videoElement != null) {
                string videoLink = videoElement.Children[0].GetAttribute("src");
                int hash = videoLink.GetHashCode();
                if (moviesLinks.Any(m => m.Hash == hash)) {
                    // Done parsing this URL: remove handler or whatever 
                    // else is planned to move to the next site/page
                    return;
                }

                string sourceImage = videoElement.GetAttribute("poster");
                moviesLinks.Add(new MovieLink() {
                    Hash = hash, VideoLink = videoLink, ImageLink = sourceImage
                });
            }
        }
        catch (UnauthorizedAccessException) { } // Cannot be avoided: ignore
        catch (InvalidOperationException) { }   // Cannot be avoided: ignore
    }
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53213782

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档