在最近的數據采集研究中, 發現很多頁面的內容都是在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(); } }
查看本欄目