我要抓取页面的信息。但url重新过了。
http://flights.ctrip.com/booking/bjs-sha----adu-1/?dayoffset=7&ddate1=2013-01-12&dcityname1=%u5317%u4eac&acityname1=%u4e0a%u6d77
我用了很笨的办法。把页面保存在本地。然后读取,用正则匹配
WebClient wc = new WebClient();
string html = wc.DownloadString(url);
////////////
当我用webClient直接读取网上的页面的时候很多很多内容读取不到。保存在可这远远不够。我想直接去读取那个页面。然后匹配。下载源代码。是不是要读取流才能做到,大家给我点思路。谢谢

解决方案 »

  1.   

    是抓取某个页面的html源代码呢。我用 
    WebClient wc = new WebClient();
    string html = wc.DownloadString(url);
    不行。有动态生成的信息抓取不到。你说的意思我不太明白。能详细点不
      

  2.   

    我的意思是。怎么可以编程实现获取页面的源代码和我在页面右键查看源代码是相同的。现在。我用
    WebClient wc = new WebClient();
    string html = wc.DownloadString(url);
    获取的源码跟我在页面右键看的源码不同。
      

  3.   

    我写过,有个不错的插件可以用:HtmlAgilityPack.1.4.6
    不过算法还是要自己写!
      

  4.   

    这个网站的很多东西是由javascript生成的,
    你直接抓取这个网址得不到由javascript生成的信息。
      

  5.   


    百度搜索HtmlAgilityPack,会有实例,不难的!
      

  6.   


     其实一个抓取页面很简单的,用httpwebrequst技术get去请求页面
     返回的是一个流
     然后把流转化为字符串
     做好用正则得到你要的内容信息,
    思路就是这样的,我之前做过,实现起来不难的
      

  7.   

    不是哦。
    是这个页面。http://flights.ctrip.com/booking/bjs-sha----adu-1/?dayoffset=7&ddate1=2013-01-12&dcityname1=%u5317%u4eac&acityname1=%u4e0a%u6d77
    我就是获取页面航班的信息。你看看
      

  8.   

    是呢。我是这样实现的
    但也不行Uri uri = new Uri(url);
                HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(uri);
                myReq.UserAgent = "User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705";
                myReq.Accept = "*/*";
                myReq.KeepAlive = true;
                myReq.Headers.Add("Accept-Language", "zh-cn,en-us;q=0.5");
                HttpWebResponse result = (HttpWebResponse)myReq.GetResponse();
                Stream receviceStream = result.GetResponseStream();
                StreamReader readerOfStream = new StreamReader(receviceStream, System.Text.Encoding.Default);
                string strHTML = readerOfStream.ReadToEnd();
                readerOfStream.Close();
                receviceStream.Close();
                result.Close();
                return strHTML; 
      

  9.   

    有内容。我打开这个页面的时候右键查看源文件有我想要的信息。但用代码就就没有,我右键看到很多div之类的。代码实现却没有。
      

  10.   

    这是我在博客园提的问题。那里比较详细。有时间的话。看下
    http://q.cnblogs.com/q/45531/
      

  11.   


     你把你要抓取的url地址贴处理,我用我的程序抓抓看?
      

  12.   

    嗯。好。谢谢你
    http://flights.ctrip.com/booking/bjs-sha----adu-1/?dayoffset=7&ddate1=2013-01-12&dcityname1=%u5317%u4eac&acityname1=%u4e0a%u6d77
      

  13.   

    不知道你做的是WinForm程序,还是WEB程序,
    如果是WEB程序我还真想不到什么好方法,
    虽然有思路,但技术过于复杂,不容易实现。
    其实你想想就明白为什么抓不到了,
    你使用HttpWebRequest对象去获取代码,这样只能抓到指定网址的HTML字符内容,
    对于javascript来说,是在客户端执行后生成的结果。
    使用HttpWebRequest只能得到HTML,因为js并未执行,所以就不可能得到js成生的HTML字符串了。
    那么,除非建立一个js执行的环境,然后获取执行后的结果,但这样难度太大。如果你作的是WinForm程序的话,
    可以考虑使用WebBrowser控件。
    在加载完成后,WebBrowser.Document就已经包含了js执行后的字符串。
      

  14.   


    你说的WebBrowser我也尝试了。也不想行。你看下代码 using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;namespace Test
    {
        class Program
        {        static void Main(string[] args)
            {
                System.Threading.Thread t = new System.Threading.Thread(ThreadStart);
                t.SetApartmentState(System.Threading.ApartmentState.STA);
                t.Start();            Console.Read();
            }        static string html = string.Empty;
            private static void ThreadStart()
            {
                string stUrl = "http://flights.ctrip.com/booking/bjs-sha----adu-1/?dayoffset=7&ddate1=2013-01-12&dcityname1=%u5317%u4eac&acityname1=%u4e0a%u6d77";
                WebBrowser browser = new WebBrowser(); browser.Dock = DockStyle.Fill;
                browser.Name = "webBrowser";
                browser.ScrollBarsEnabled = false;
                browser.TabIndex = 0;
               
                //browser.Url = new Uri("http://www.microsoft.com");
                browser.Url = new Uri(stUrl);
                browser.Navigated += browser_Navigated;            Form form = new Form();
                form.WindowState = FormWindowState.Minimized;
                form.Controls.Add(browser);
                form.Name = "Browser";            Application.Run(form);
            }        static void browser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
            {
                html = (sender as WebBrowser).DocumentText;
            }
        }
    }
    我是在控制台下执行的。读取信息。匹配。保存xml文件。你看这里的问题。
    http://q.cnblogs.com/q/45531/
      

  15.   

    dayoffset
    ddate1
    dcityname1
    acityname1
    这些都是网址中提交的查询参数,你可以考虑获取提交这些参数到查询接口,然后提交查询参数接收返回值看看。
      

  16.   

    你知道你为什么抓取不了吗?
    那是因为你没有post提交  就像你点击搜索页面一样 它是从另外一个页面带着参数过来的
    你怎么可能把地址输入上去就可以的, 缺了一个post提交过程
    分析页面的参数传值用httpwatch这样的工具就可以的
      

  17.   

    你看到的数据都是通过用AJAX根据查询参数后台获取后,前台用JS填充进去的,网站的JS是混淆过的。没法查看。
      

  18.   

     解决办法有了,你把你的代码改成post提交就可以了,编码用GB2312就可以了
      

  19.   

    解决办法有了,你把你的代码改成post提交就可以了,编码用GB2312就可以了 
    url地址还是那个地址,post提交一下就可以了,
      

  20.   

     你之前是get方式提交的,但是他们是接受post方式的参数,
     所以才抓不到的,你的方式错了,改为post方式就可以了,还有编码
     
     
      

  21.   

    你是说这个,HttpWebRequest 
    还是这个,WebBrowser 
    我试试先哦
      

  22.   

     
    用HttpWebRequest处理 就可以了
      

  23.   

    你试了行是吗。我改成post
    这句话报错哦
    HttpWebResponse result = (HttpWebResponse)myReq.GetResponse();
    错误:远程服务器返回错误: (411) 所需的长度。
    贴下你的代码我看看行吗?
      

  24.   

    刚才我使用WebBrowser试了一下,
    能够成功获取,
    但前提是内容加载完成,还有一点是很要命的问题,
    比如你想查看某一个“计划机型:333(大)”
    在鼠标未指向“333(大)”这些文字时,
    对就的Javascript代码就不会执行,直接导致的结果就是未生成对应的字符,
    所以你无法获取,获取你在WebBrowser获取上,让鼠标移动到“333(大)”后,在获取Document对象……
    在确保js执行后,以下代码可以正确获取内容。HtmlDocument objDoc = webBrowser1.Document;
    if (objDoc.All[i].TagName.ToLower().Equals("html"))
    {
      richTextBox1.Text = objDoc.All[i].InnerHtml;
      break;
    }
      

  25.   

    谢谢大家积极回答。因为没接触过。大脑都没这知识点。所有要想到思路很很难的,通过这样一讨论。于人于己都受益匪浅。
    博客园有个朋友帮解决了。在这里分享给大家,IT人以分享代码为快乐。谢谢大家积极讨论。特别谢谢"du1yi1dao 
    "博友。 using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Security.Cryptography;
    using System.IO;
    using System.Drawing.Drawing2D;
    using System.Data;
    using System.Text.RegularExpressions;
    using System.Reflection;
    using System.Xml.Serialization;
    using System.Xml;
    using System.Threading;
    using System.Net;
    using System.IO.Compression;
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var url = "http://flights.ctrip.com/booking/bjs-sha----adu-1/";
                var param = "dcityname1=北京&acityname1=上海";
                var str = GetHTML(url, param);
                Console.Read();
            }        /// <summary>
            /// 获取HTML
            /// </summary>
            /// <param name="url"></param>
            /// <returns></returns>
            static string GetHTML(string url, string param)
            {
                Uri uri = new Uri(url);
                HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(uri);            myReq.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");            byte[] byData = Encoding.Default.GetBytes(param);
                myReq.Method = "Post";
                myReq.ContentLength = byData.Length;
                Stream reqStrem = myReq.GetRequestStream();
                reqStrem.Write(byData, 0, byData.Length);
                reqStrem.Close();            HttpWebResponse result = (HttpWebResponse)myReq.GetResponse();
                Stream recStream = result.GetResponseStream();            //如果是Gzip方式则需要解压
                recStream = new GZipStream(recStream, CompressionMode.Decompress);            StreamReader redStream = new StreamReader(recStream, System.Text.Encoding.Default);
                string strHTML = redStream.ReadToEnd();
                redStream.Close();
                recStream.Close();
                result.Close();            return strHTML; 
            }
        }
    }
      

  26.   

        string whereUrl = "dayoffset=7&ddate1=2013-01-12&dcityname1=%u5317%u4eac&acityname1=%u4e0a%u6d77";
                html = HttpPost1("http://flights.ctrip.com/booking/bjs-sha----adu-1/",whereUrl);
                Response.Write(html);
            }
            public string HttpPost1(string url, string param)
            {
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.Accept = "*/*";
                request.Timeout = 50000;
                request.AllowAutoRedirect = false;            StreamWriter requestStream = null;
                WebResponse response = null;
                string responseStr = null;            try
                {
                    requestStream = new StreamWriter(request.GetRequestStream());
                    requestStream.Write(param);
                    requestStream.Close();                response = request.GetResponse();
                    if (response != null)
                    {
                        StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("GB2312"));
                        responseStr = reader.ReadToEnd();
                        reader.Close();
                    }
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    request = null;
                    requestStream = null;
                    response = null;
                }
                return responseStr;
            }
    解决了
      

  27.   

    这个问题其实也的确很让人郁闷,
    在js未执行前,对应的字符是不可能出现,
    但这个网站很多地方,在用户未触发前,js偏偏却又是不执行的……
    比较,未触发MouseOver或MouseMove前js是不会执行的。
      

  28.   


    LZ所说的这种方法得到应该还是js未执行前的字符串。
      

  29.   

    我说好像少了什么叫,刚才把for给扔了……HtmlDocument objDoc = webBrowser1.Document;
    for (int i = 0; i < objDoc.All.Count; i++){
        if (objDoc.All[i].TagName.ToLower().Equals("html"))
        {
          richTextBox1.Text = objDoc.All[i].InnerHtml;
          break;
        }
    }
      

  30.   


    是我没看清你的问题……
    如果仅仅是获取呈现在IE里的代码用HttpWebRequest足够了。
      

  31.   


    这段代码你变通一下就可以实现。
    遍历一下HTML元素,
    遇到需要执行js的地方,通过HtmlElement对象的InvokeMember模拟出单击或移动的事件,
    这样对应的js就会执行,然后才获取WebBrowser的内容。
      

  32.   

    HtmlAgilityPack   节点匹配就可以刻
      

  33.   

    是一个第三方工具是吗。我刚下载看了下。很多dll。有时间接触下。谢谢
      

  34.   

    用这个 WebRequest request = WebRequest.Create("http://www.baidu.com");
                WebResponse response = request.GetResponse();
                using (StreamReader sr = new StreamReader(response.GetResponseStream(), System.Text.Encoding.GetEncoding("utf-8")))
                {
                    Response.Clear();
                    Response.Write(sr.ReadToEnd());
                    Response.End();            }
      

  35.   

    http://download.csdn.net/detail/myljg/4970491
    我是我原来开发某个项目时,需下下载HTML字符。这是基于HttpWebRequest的。你可以看看。
    因为我开发的那个项目,网站需要登陆,所有需要使用了。
    你可自己去掉,
    包含DownloadProgressChanged事件和DownloadStringCompleted事件,
    一个是进度,一个是获取完成的事件。
    在完成事件中通过Result获取HTML字符
      

  36.   

    你所需的网站不需要登陆,
    自己把CookieContainer去掉测试就行了。
      

  37.   

    如果你下载过就算了,没下过的话需要代码的话给我Email就行了。
      

  38.   

    刚洗澡好呢。还没下载哦。你发我邮箱。谢谢了,[email protected]
      

  39.   

    我之前刚好做过一个这样的工具,静态加载的内容很好抓取,最难的应该就是那些通过js加载的数据对吧,其实思路很简单,就是通过火狐的网络分析它的请求,然后根据js请求的路径进行动态配置就行的,根据匹配的路径然后再去抓取就好了,上面有说到HtmlAgilityPack,这个很好用的,就是通过xpath进行匹配路径。明白原理就简单了,每个东西都是要通过http请求,然后http返回的数据的。不懂再问我
      

  40.   

    推荐使用WebBrowser  。 因为类似WebRequest  这样的。只能抓取源代码。如果是ajax过来的就没办法了。    //解析源代码
            private void DeconeHTMl(string URL)
            {
                WebBrowser webb = new WebBrowser();
                webb.ScriptErrorsSuppressed = true;
                webb.Navigate("about:blank");
                IEBrowser ie = new IEBrowser(webb);
                ie.Navigate(URL);  // 等待页面载入完毕.
                try
                {
                    ie.IEFlow.Wait(new UrlCondition("wait", URL, zoyobar.shared.panzer.StringCompareMode.StartWith), 5);
                }
                catch (Exception)
                {
                    MessageBox.Show("请求地址未响应");
                    return;
                }
                
                ie.InstallTrace();
                ie.InstallJQuery(JQuery.CodeMin);
                ie.ExecuteJQuery(JQuery.Create("'div[id=post_content_24405726649]'"), "_aHtml");
                int count = ie.ExecuteJQuery<int>(JQuery.Create("_aHtml").Length());
               // ie.ExecuteJQuery(JQuery.Create("_aHtml").Eq("0"), "_current"); //获取第一个元素
                MessageBox.Show(count + ie.ExecuteJQuery(JQuery.Create("_aHtml").Html()).ToString());
               
            }
      

  41.   

    上面写的一个利用jquery语法获取内容的例子。
      

  42.   

    其实不用那么复杂的,有一个第三方的组件HtmlAgilityPack,我用的就是这个,先获取html,然后加载解析,避免了不能识别的网页的问题。至于对HTML的操作,它完全支持Xpath方式的查找,操作起来很方便,你要解析某一种网页中某个元素,用chorme打开,然后F12,选择该节点,右键拷贝xpath,直接就可以获得xpath,然后在代码中查找,非常的方便,我用这个方式把我所需要的所需要的信息,从相关网站上拷贝完了。
      

  43.   


    HtmlAgilityPack能获取到js生成的页面吗.?求指教,js页面采集太头疼了..
      

  44.   


    大哥,怎么样才能抓取到由js生成的信息.
    就是采集的源代码和firebug看到的一样,而不是右键查看源代码看到的源代码.
    教教我吧..