首页 新闻 赞助 找找看

如何获取网页源代码中无法显示的内容??

0
悬赏园豆:100 [已解决问题] 解决于 2015-11-26 11:43

  最近在做一个采集网页数据的功能,要获取博客园主页的二级分类,但是源代码里却没有,请问可以使用什么方式获取源代码里无法显示的内容????

lchcoder的主页 lchcoder | 初学一级 | 园豆:112
提问于:2015-11-24 15:52
< >
分享
最佳答案
1

可能是通过ajax异步加载的。可以把网站地址贴出来,帮你看看怎么解决。

收获园豆:100
凝冰 | 小虾三级 |园豆:685 | 2015-11-24 15:56

我是用HtmlAgilityPack采集文章的,我想要获取的就是博客园主页文章里面的标签

lchcoder | 园豆:112 (初学一级) | 2015-11-24 16:23

@lchcoder: 

我在网上下载了你说的那个插件来用了,没有什么问题的呀。

代码:

using HtmlAgilityPack;
using System;
namespace HtmlAnalyzeDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            HtmlWeb htmlWeb = new HtmlWeb();
            HtmlDocument htmlDoc = htmlWeb.Load("http://www.cnblogs.com");
            HtmlNodeCollection htmlNodeCollection = htmlDoc.DocumentNode.SelectNodes("//div[@class='post_item_body']");
            foreach (var item in htmlNodeCollection)
            {
                Console.WriteLine("标题:"+item.ChildNodes[1].FirstChild.InnerText);
                Console.WriteLine("链接:" + item.ChildNodes[1].FirstChild.Attributes["href"].Value);
                Console.WriteLine();
            }
      }
}

 

运行效果

凝冰 | 园豆:685 (小虾三级) | 2015-11-24 17:23

@凝冰: 这些我都能获取到,但是有些标签是隐藏的,只有鼠标移上去才会显示,比如说博客园主页的第二级的分类,在源码里面是查看不到的,所以也就获取不到第二级的分类,文章里的标签也是如此,我是想找个方法能获取到二级分类和文章标签,这些都是源码里面看不到的。

lchcoder | 园豆:112 (初学一级) | 2015-11-24 19:11

@lchcoder:这个需要分析的。

1、首先我们打开google浏览器的开发者工具。

我们在请求到的源代码中搜索ASP.NET关键字。是找不到的。我们推测是异步加载的。

2、我们在google浏览器中查看所有异步请求。

发现有一个aggsite/SubCategories(子菜单)的请求正是我们需要的。

3、查看js代码。

查看.net技术标签上有一个onmouseover方法。

4、在浏览器控制台中打印出函数

5、获取函数定义

6、根据规则编写程序。获取cateshow函数中参数,然后根据参数来获取cate_content_block_xxx。就获取到子菜单了、

凝冰 | 园豆:685 (小虾三级) | 2015-11-25 12:16

@凝冰: 不好意思,我是个菜鸟,我想请问然后怎么获取到子菜单,我的那个小程序是用WPF做的,直接用HtmlAgilityPack这个插件是找不到的。

lchcoder | 园豆:112 (初学一级) | 2015-11-25 14:51

@lchcoder: 用什么做不存在,主要是思路。我们控制台程序做测试。快些。看一下是不是要获取下面的效果。

 

代码

using HtmlAgilityPack;
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;

namespace HtmlAnalyzeDemo
{
    public class HttpWebRequestBeginGetRequest
    {
        private static ManualResetEvent allDone = new ManualResetEvent(false);

        static string postData = "{\"cateIds\":\"108698,2,108701,108703,108704,108705,108709,108712,108724,4\"}";
        private static string html = "";
        public static void Main(string[] args)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.cnblogs.com/aggsite/SubCategories");
            request.Accept = "text/plain, */*; q=0.01";
            request.Host = "www.cnblogs.com";
            request.ContentType = "text/plain;charset=UTF-8";
            request.ContentLength = postData.Length;
            request.Method = "POST";
            //异步请求子菜单
            request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
            allDone.WaitOne();
            //将获取到的源代码转为流
            byte[] array = Encoding.UTF8.GetBytes(html);
            MemoryStream stream = new MemoryStream(array);
            StreamReader reader = new StreamReader(stream);
            HtmlDocument htmlDocumentSub = new HtmlDocument();
            //加载html成xml
            htmlDocumentSub.Load(reader);
            //获取html首页的一级菜单
            HtmlDocument htmlDocument = new HtmlWeb().Load("http://www.cnblogs.com");
            HtmlNodeCollection htmlNodes = htmlDocument.DocumentNode.SelectNodes("//ul[@id='cate_item']/li");
            foreach (var node in htmlNodes)
            {
                string onmouseover = node.Attributes["onmouseover"].Value;
                string cateshowId=onmouseover.Split(new char[]{'(',')'})[1];
                HtmlNodeCollection htmlCateNodes = htmlDocumentSub.DocumentNode.SelectNodes("//div[@id='cate_content_block_" + cateshowId + "']/div/ul/li");
                Console.WriteLine("--" + node.InnerText);
                if (htmlCateNodes != null)
                {
                    foreach (var cateNode in htmlCateNodes)
                    {
                        Console.WriteLine("----"+cateNode.InnerText);
                    }
                }
            }
            //Console.WriteLine(htmlDocumentSub.DocumentNode.InnerHtml);
        }

        private static void GetRequestStreamCallback(IAsyncResult asynchronousResult)
        {
            HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
            Stream postStream = request.EndGetRequestStream(asynchronousResult);
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);

            postStream.Write(byteArray, 0, postData.Length);
            postStream.Close();
            //请求完成后异步读取数据
            request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
        }

        private static void GetResponseCallback(IAsyncResult asynchronousResult)
        {
            HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
            Stream streamResponse = response.GetResponseStream();
            StreamReader streamRead = new StreamReader(streamResponse);
            string responseString = streamRead.ReadToEnd();
            //请求完成的字符串保存到html中
            html = responseString;
            streamResponse.Close();
            streamRead.Close();
            response.Close();
            allDone.Set();
        }
    }
}
View Code
凝冰 | 园豆:685 (小虾三级) | 2015-11-26 09:22

@凝冰: 那这部分代码的作用是什么,有点看不懂

lchcoder | 园豆:112 (初学一级) | 2015-11-26 11:18

@lchcoder: 这个是http协议里面的东西。推荐你看一下园里里面大神些的http协议详解。

http://www.cnblogs.com/li0803/archive/2008/11/03/1324746.html

主要作用是使用http协议来模拟请求。所有的网站都是用到http协议来进行请求。返回数据的。

给你截一张http请求报文的图。

凝冰 | 园豆:685 (小虾三级) | 2015-11-26 11:20

@凝冰: 非常感谢,问题已经解决,可以加你QQ吗,有什么不会的可以请教你。

lchcoder | 园豆:112 (初学一级) | 2015-11-26 11:40

@凝冰: 这是群号吗?

lchcoder | 园豆:112 (初学一级) | 2015-11-26 11:42

@lchcoder: 个人qq号546341921,打错了。

凝冰 | 园豆:685 (小虾三级) | 2015-11-26 11:57
其他回答(2)
0

webbrowse+js可以搞定

星星点灯6 | 园豆:164 (初学一级) | 2015-11-24 17:04

可是我是用的WPF,那该如何获取呢??

支持(0) 反对(0) lchcoder | 园豆:112 (初学一级) | 2015-11-25 16:47
0
xgqfrms | 园豆:116 (初学一级) | 2015-11-25 13:06
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册