C#代码获取或设置Iframe中的HTML

在最近的数据采集研究中, 发现很多页面的内容都是在iframe中的, 这位采集带来了不少困难. 经过一番思考之后, 我想到了C#的解决办法:

1. 运行Spider Studio, 加载页面 http://www.w3school.com.cn/tiy/t.asp?f=html_iframe

2. 编辑代码, 将iframe指向 http://www.w3school.com.cn

3. 这个页面具备如下结构:

Page > IFrame1 -> IFrame2 (就是我们代码中写的那个IFrame)

我的目标是通过C#代码先获取IFrame1的内容, 然后继续获取IFrame2的内容, 继而设置IFrame2的src到 GDT首页 去. 

4. 获取IFrame1

var iframe1 = Default.SelectSingleNode("#result iframe").Contents().SelectSingleNode("body");
if(iframe1.IsEmpty() == false)
{
    MessageBox.Show(iframe1.Html());
}

 

此时显示结果正确, 证明成功取到了IFrame1的内容:

5. 获取IFrame2

var iframe2 = Default.SelectSingleNode("#result iframe").Contents().SelectSingleNode("iframe").Contents().SelectSingleNode("body");
if(iframe2.IsEmpty() == false)
{
    MessageBox.Show(iframe2.Html());
}

 

此时显示结果正确, 证明也成功取到IFrame2的内容了:

6. 设置IFrame2的Src

iframe2 = Default.SelectSingleNode("#result iframe").Contents().SelectSingleNode("iframe"); //重新定位iframe2到IFrame元素上
iframe2.Attr("src", "http://www.gdtsearch.com");

 

此时IFrame2已经跳转, 结果正确!

7. 全部预期功能实现, 现在所说已知的局限性:

7.1 不兼容跨域访问

如果iframe中的页面和父页面不在一个域名下面, 这段代码因为安全性的原因是失效的. 比如我将iframe2的src换成 http://www.gdtsearch.com, 那么相应的取iframe2.Body的时候就会报错:

7.2 判断IFrame中页面何时加载完成的代码逻辑有点复杂, 我写了一个方法供大家参考:

public void IFrameReady(JQueryContext iframe, string jQueryExpr)
{
    while(Default.Available)
    {
        var contents = iframe.Contents();
        if(contents.IsEmpty() == false)
        {
            var node = contents.SelectSingleNode(jQueryExpr);
            if(node.IsEmpty() == false && node.Html().Trim().Length > 10)
            {
                return;
            }
        }
        Thread.Sleep(1000);
        Application.DoEvents();
    }
}

 

8. 和Spider Studio采集以及相关脚本编写的其他文章:

示例 - C#脚本代码采集搜狐NBA球员, 球队和比赛实况

C#中利用JQuery实现视频网站的缩略图采集

API - 使用Default对象 - 基础篇

示例 - 如何翻页

示例 - 向百度说 Hello world! 并获得回应.

Spider Studio 社区信息

posted @ 2013-11-28 23:24  Ivan Zou  阅读(10435)  评论(5编辑  收藏  举报