【问题标题】:Value Scraping Error C# [closed]值抓取错误 C# [关闭]
【发布时间】:2014-01-14 19:05:49
【问题描述】:

我是 C# 编码的新手,正在编写一个小程序来从 Mt.Gox 中获取当前比特币值。

这是我目前使用的代码:

namespace BitcoinValueScraper
{
    public partial class GetValue : Form
{
        public GetValue()
        {
            InitializeComponent();
        }

        private void GetValue_Load(object sender, EventArgs e)
        {
            System.Windows.Forms.WebBrowser wb = new System.Windows.Forms.WebBrowser();
            wb.Navigate("www.mtgox.com");
            wb.Stop();
            wb.Document.GetElementById("lastPrice").SetAttribute("value", textBox1.Text);
        }

    }

}

这会返回:

“'System.NullReferenceException' 类型的未处理异常 发生在 BitcoinValueScraper.exe 附加信息:对象 引用未设置为对象的实例。”

请帮忙!

【问题讨论】:

标签: c# html screen-scraping getelementbyid scrape


【解决方案1】:

您必须绑定到 webbrowser 控件上的 LoadCompleted 事件。如果您不这样做,控件上的文档将为空。该页面可能尚未下载。

示例代码:

    public WebBrowser webb;

    public MainWindow()
    {
        InitializeComponent();

        webb = new WebBrowser();
        webb.LoadCompleted += webb_LoadCompleted;
        webb.Navigate("http://www.google.com");

    }

    void webb_LoadCompleted(object sender, NavigationEventArgs e)
    {
        //NOW DOCUMENT SHOULD NOT BE NULL
        MessageBox.Show("Completed loading the page");

        mshtml.HTMLDocument doc = webb.Document as mshtml.HTMLDocument;
        mshtml.HTMLInputElement obj = doc.getElementById("gs_taif0") as mshtml.HTMLInputElement;
        mshtml.HTMLFormElement form = doc.forms.item(Type.Missing, 0) as mshtml.HTMLFormElement;
    }

以上是针对windows 演示基础的webbrowser 控件。在 Windows 窗体中,我认为该事件是:DocumentCompleted 参考:http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser%28v=vs.110%29.aspx

这是 windows 窗体代码(我刚刚测试过):

    private System.Windows.Forms.WebBrowser wb;

    public Form1()
    {
        InitializeComponent();
        GetValue_Load(null, EventArgs.Empty);
    }

    private void GetValue_Load(object sender, EventArgs e)
    {
        wb = new System.Windows.Forms.WebBrowser();
        wb.DocumentCompleted += wb_DocumentCompleted;
        wb.Navigate("http://www.google.com");
    }

    void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        MessageBox.Show("Document loading completed");
        //GET YOUR DOCUMENT HERE
    }

【讨论】:

    【解决方案2】:

    虽然不是您当前遇到的代码问题的直接答案,但我强烈建议您尝试以不同的方式做事,因为在这样的网站上尝试从 HTML 中提取信息非常脆弱(如果他们会在您的所有代码被破坏时更改他们的标记)并且在很多级别上都是错误的。通常,程序员通常依靠数据 API 来查询此类信息,因为它提供了一种标准化且(希望)经过测试的信息查询方式。一个快速的谷歌搜索出现了一些由 BlockChain 提供的比特币 API,这些 API 在比特币世界中似乎很受欢迎。以下是查询比特币汇率的示例 API 调用:

    http://blockchain.info/api/exchange_rates_api

    通过向他们的 API 发出 HTTP 请求,您可以更可靠地提取您正在寻找的信息并将其显示在您的用户界面中。

    更多比特币 API 资源可以在这里找到:

    http://blockchain.info/api

    不幸的是,由于您既不熟悉编程又不熟悉 API 交互,如果不花时间亲自为您编写代码,很难给您答案。但是,我可以说,目前,您的方法是错误的。 WebBrowser 对象不是与 Web API 交互的合适机制。更合适的方法是对您发布的 API URL 进行 HTTP 调用,然后从响应中读取 JSON。然后需要将其解析为对您的应用程序有意义的某种格式(例如简单的 Price 对象等)。网上有很多关于用 C# 解析 JSON 以及通过 HTTP 协议与基于 Web 的 API 交互的文章。我绝对建议您从那里开始。

    这是一篇很棒的入门文章,它将引导您创建一个与 JSON API 交互的基本应用程序。只需将 Bing URL 替换为适当的比特币 URL,您就应该有一个很好的起点。

    【讨论】:

      【解决方案3】:

      如果有什么尝试:

          namespace BitcoinValueScraper
          {
              public partial class GetValue : Form
              {
                  System.Windows.Forms.WebBrowser wb = new System.Windows.Forms.WebBrowser();
                  public GetValue()
                  {
                      InitializeComponent();
                  }
      
                  private void GetValue_Load(object sender, EventArgs e)
          {
              wb.Navigate("www.mtgox.com");
              wb.DocumentCompleted += wb_LoadCompleted;
          }
          void wb_LoadCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
          {
              HtmlDocument doc = wb.Document;
              textBox1.Text = doc.GetElementById("lastPrice").ToString();
          }        
               }
      

      【讨论】:

      • while (wb.ReadyState != WebBrowserReadyState.Complete) { Application.DoEvents(); } wb.Document.GetElementById("lastPrice").SetAttribute("value", textBox1.Text);
      • 但我仍然得到:“Debugger:Exception Intercepted: GetValue_Load, Form1.cs line 28 一个异常被截获,调用堆栈展开到发生异常的用户代码调用之前的位置。” Unwind the call stack on unhandled exceptions”在调试器选项中被选中。”
      • user2453734 解释了为什么它为空,您必须等待页面下载才能查询 html。只需将他的 GetElementById 换成 lastPrice。
      猜你喜欢
      • 1970-01-01
      • 2021-01-31
      • 1970-01-01
      • 2011-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多