c# - कैसे गतिशील रूप से एनआईटी के वेबब्राउजर या एमएसएसटीएल। एचटीएमएलडीकाट का उपयोग करते हुए एचटीएमएल कोड उत्पन्न करने के लिए?




javascript html (2)

मैं इस विषय बिंदु से संबंधित अधिकांश उत्तर या तो System.Windows.Forms.WebBrowser वर्ग या COM इंटरफ़ेस mshtml.HTML दस्तावेज़ को Microsoft HTML ऑब्जेक्ट लाइब्रेरी असेंबली से पढ़ा है।

वेबब्रेसर वर्ग ने मुझे कहीं नहीं चलाया मेरे वेब ब्राउज़र द्वारा प्रदान किए गए HTML कोड को प्राप्त करने के लिए निम्नलिखित कोड विफल हैं:

[STAThread]
public static void Main()
{
    WebBrowser wb = new WebBrowser();
    wb.Navigate("https://www.google.com/#q=where+am+i");

    wb.DocumentCompleted += delegate(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        mshtml.IHTMLDocument2 doc = (mshtml.IHTMLDocument2)wb.Document.DomDocument;
        foreach (IHTMLElement element in doc.all)
        {
                    System.Diagnostics.Debug.WriteLine(element.outerHTML);
        }     
    };
    Form f = new Form();
    f.Controls.Add(wb);
    Application.Run(f);
} 

उपरोक्त सिर्फ एक उदाहरण है। मुझे शहर के नाम का पता लगाने के लिए एक वैकल्पिक हल खोजने में वास्तव में दिलचस्पी नहीं है, जहां मैं स्थित हूं। मुझे समझने की आवश्यकता है कि इस प्रकार के गतिशील रूप से उत्पन्न डेटा प्रोग्राम को कैसे पुनर्प्राप्त करें।

(नई सिस्टम। नेट। वेबक्लेन्ट.डाउनलोडस्ट्रिंग (" https://www.google.com/#q=where+am+i ") को कॉल करें , परिणामस्वरूप टेक्स्ट को कहीं से बचाएं, उस शहर के नाम की खोज करें जहां आप वर्तमान में हैं स्थित है, और मुझे पता है अगर आप इसे खोजने में सक्षम थे।)

लेकिन फिर भी जब मैं अपने वेब ब्राउज़र (या फ़ायरफ़ॉक्स) से " https://www.google.com/#q=where+am+i " का उपयोग करता हूं, तो मुझे अपने शहर का नाम वेब पेज पर लिखा जाता है। फ़ायरफ़ॉक्स में, अगर मैं शहर के नाम पर सही क्लिक करता हूं और "तत्व का निरीक्षण (क्यू)" का चयन करता हूं, तो मैं स्पष्ट रूप से एचटीएमएल कोड में लिखे गए शहर का नाम देखता हूं जो वेब HTML से लौटा हुआ कच्चे एचटीएमएल से काफी अलग दिखता है। ।

मैं System.Net.WebBrowser खेलने के थक गए, मैं mshtml को देने का निर्णय लिया। एचटीएमएल दस्तावेज एक शॉट, बस एक ही बेकार कच्चे एचटीएमएल के साथ समाप्त करने के लिए:

public static void Main()
{
    mshtml.IHTMLDocument2 doc = (mshtml.IHTMLDocument2)new mshtml.HTMLDocument();
    doc.write(new System.Net.WebClient().DownloadString("https://www.google.com/#q=where+am+i"));

    foreach (IHTMLElement e in doc.all)
    {
            System.Diagnostics.Debug.WriteLine(e.outerHTML);
    }
} 

मुझे लगता है कि इस तरह की जानकारी प्राप्त करने के लिए एक शानदार तरीका होना चाहिए। अभी मैं सोच सकता हूं कि एक वेबब्राउज़र नियंत्रण को एक फार्म में जोड़ दिया जाए, तो उसे यूआरएल पर नेविगेट करें, "CLRL, A" की चाबियाँ भेजें, और कॉपी करें जो पृष्ठ पर क्लिपबोर्ड पर प्रदर्शित होने के लिए होता है और कोशिश करता है इसे पार्स करें यह भयानक समाधान है, हालांकि।


आपका वेब-ब्राउज़र कोड उचित दिखता है - कुछ के लिए प्रतीक्षा करें, जो वर्तमान सामग्री को पकड़ लेता है दुर्भाग्य से ब्राउज़र और जावास्क्रिप्ट से कोई आधिकारिक "मुझे जावास्क्रिप्ट निष्पादित नहीं किया जा रहा है, सामग्री चोरी करने के लिए नि:

कुछ प्रकार की सक्रिय प्रतीक्षा ( Sleep नहीं, लेकिन Timer ) आवश्यक हो सकती है और पेज-विशिष्ट यहां तक ​​कि अगर आप हेडलेस ब्राउज़र (यानी फेंटमोज) का उपयोग करते हैं, तो आपके पास एक ही समस्या है


मैं अलेक्सई के उत्तर में कुछ कोड का योगदान देना चाहता हूं। कुछ बिंदु:

  • कड़ाई से बोलते हुए, यह हमेशा निर्धारित करना संभव नहीं हो सकता है कि जब पृष्ठ 100% संभावना के साथ प्रतिपादन समाप्त हो गया हो। कुछ पृष्ठ काफी जटिल हैं और लगातार AJAX अपडेट का उपयोग करें। लेकिन हम बदलाव के लिए पृष्ठ के वर्तमान HTML स्नैपशॉट को मतदान करके और WebBrowser.IsBusy जाँच करके काफी करीब आ सकते हैं। WebBrowser.IsBusy संपत्ति यह क्या है LoadDynamicPage नीचे है

  • उपरोक्त के ऊपर कुछ समय-समय पर तर्क मौजूद होना चाहिए, यदि पेज रेंडरिंग कभी न खत्म हो रहा है (नोट CancellationTokenSource )।

  • Async/await यह कोडिंग के लिए एक महान उपकरण है, क्योंकि यह हमारे असिंक्रोनस पोलिंग तर्क के लिए रैखिक कोड प्रवाह देता है, जो इसे बहुत सरल करता है।

  • ब्राउजर फ़ीचर नियंत्रण का उपयोग करते हुए एचटीएमएल रेंडरिंग को सक्षम करना महत्वपूर्ण है, क्योंकि वेब ब्राउजर डिफ़ॉल्ट रूप से IE7 इम्यूलेशन मोड में चलता है। यही SetFeatureBrowserEmulation नीचे है

  • यह एक WinForms ऐप है, लेकिन इस अवधारणा को आसानी से कंसोल ऐप में रूपांतरित किया जा सकता है।

  • यह तर्क आपके द्वारा विशेष रूप से उल्लिखित यूआरएल पर अच्छा काम करता है: https://www.google.com/#q=where+am+i

using Microsoft.Win32;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WbFetchPage
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            SetFeatureBrowserEmulation();
            InitializeComponent();
            this.Load += MainForm_Load;
        }

        // start the task
        async void MainForm_Load(object sender, EventArgs e)
        {
            try
            {
                var cts = new CancellationTokenSource(10000); // cancel in 10s
                var html = await LoadDynamicPage("https://www.google.com/#q=where+am+i", cts.Token);
                MessageBox.Show(html.Substring(0, 1024) + "..." ); // it's too long!
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        // navigate and download 
        async Task<string> LoadDynamicPage(string url, CancellationToken token)
        {
            // navigate and await DocumentCompleted
            var tcs = new TaskCompletionSource<bool>();
            WebBrowserDocumentCompletedEventHandler handler = (s, arg) =>
                tcs.TrySetResult(true);

            using (token.Register(() => tcs.TrySetCanceled(), useSynchronizationContext: true))
            {
                this.webBrowser.DocumentCompleted += handler;
                try 
                {           
                    this.webBrowser.Navigate(url);
                    await tcs.Task; // wait for DocumentCompleted
                }
                finally
                {
                    this.webBrowser.DocumentCompleted -= handler;
                }
            }

            // get the root element
            var documentElement = this.webBrowser.Document.GetElementsByTagName("html")[0];

            // poll the current HTML for changes asynchronosly
            var html = documentElement.OuterHtml;
            while (true)
            {
                // wait asynchronously, this will throw if cancellation requested
                await Task.Delay(500, token); 

                // continue polling if the WebBrowser is still busy
                if (this.webBrowser.IsBusy)
                    continue; 

                var htmlNow = documentElement.OuterHtml;
                if (html == htmlNow)
                    break; // no changes detected, end the poll loop

                html = htmlNow;
            }

            // consider the page fully rendered 
            token.ThrowIfCancellationRequested();
            return html;
        }

        // enable HTML5 (assuming we're running IE10+)
        // more info: https://.com/a/18333982/1768303
        static void SetFeatureBrowserEmulation()
        {
            if (LicenseManager.UsageMode != LicenseUsageMode.Runtime)
                return;
            var appName = System.IO.Path.GetFileName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
            Registry.SetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION",
                appName, 10000, RegistryValueKind.DWord);
        }
    }
}




dynamic-html