zoukankan      html  css  js  c++  java
  • 『开源』50行代码 扒取 博客园文章

    今天在 博客园 看到一篇文章: 《网络爬虫+HtmlAgilityPack+windows服务从博客园爬取20万博文》

     

    于是 心血来潮,立即动手 用 50 行代码,完成 博客园 文章扒取。

    并非哗众取宠,有图有真相 —— 直接上图。

    并非恶意攻击 博客园 —— 所以只扒取 10页数据,望 博客园管理员 见谅。

     

     

    数据准备 (浏览器F12拦截监视):

      文章列表链接 :     http://www.cnblogs.com/mvc/AggSite/PostList.aspx?CategoryId=808&CategoryType=SiteHome&ItemListActionName=PostList&PageIndex=3&ParentCategoryId=0

      文章列表HTML :  <a class="titlelnk" href="http://www.cnblogs.com/2010wuhao/p/4707154.html" target="_blank">Android中的Intent详解</a>  —— 其中 class="titlelnk" 为重点

      文章正文HTML :  <div id="cnblogs_post_body"> ...... </div><div id="MySignature"> —— 其中 id="cnblogs_post_body" 和 id="MySignature" 为重点

     

     

    匹配引擎:

      配置 文章列表 的 扒取规则:

      

      得到格式化之后的 HTML:

      

      添加 正式 字段的 匹配规则:

      

      所见即所得,实时查看 匹配结果:

      

      配置 文章正文 的 扒取规则:

      

      调试 文章正文 的 扒取结果:

      

      新建控制台项目:

      

      引入 核心框架 Laura.MatchCore:

      

      完成 50行代码,调试运行,扒取开始:

      

    程序源码(50行):

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Text;
    using Laura.MatchCore.Entity;
    
    namespace Temp_20150806_1838
    {
        class Program
        {
            static void Main(string[] args)
            {
                const string 文章列表URL_模板 = "http://www.cnblogs.com/mvc/AggSite/PostList.aspx?CategoryId=808&CategoryType=SiteHome&ItemListActionName=PostList&PageIndex={PageIndex}&ParentCategoryId=0";
    
                MatchSchema matchSchema_List = (MatchSchema) ReadStream(@"Data扒取博客园_文章列表.data");
                MatchSchema matchSchema_Content = (MatchSchema) ReadStream(@"Data扒取博客园_文章内容.data");
    
                for (int i = 1; i <= 10; i++) //只 扒取 10 页
                {
                    Console.WriteLine("正在 扒取 第 {0} 页", i);
                    Console.WriteLine("----------------------------------------");
    
    
                    string urlList = 文章列表URL_模板.Replace("{PageIndex}", i.ToString());
                    string htmlList = ReadHtml(urlList, Encoding.UTF8);
    
                    MatchObject matchObject_List = matchSchema_List.CalculateFieldValues(htmlList);
                    List<string> listTitle = matchObject_List.GetValues("文章标题");
                    List<string> listUrl = matchObject_List.GetValues("文章URL");
    
                    for (int j = 0; j < listUrl.Count; j++)
                    {
                        string urlContent = listUrl[j];
                        string htmlContent = ReadHtml(urlContent, Encoding.UTF8);
    
                        MatchObject matchObject_Content = matchSchema_Content.CalculateFieldValues(htmlContent);
                        string content = matchObject_Content.GetValue("文章正文");
    
                        Console.WriteLine("标题: {0} 
    正文: {1}", listTitle[j], (content.Length >= 100 ? content.Substring(0, 100) : content)); //控制台输出 正文截取 100位
                        Console.WriteLine("----------------------------------------");
                    }
                }
    
    
                Console.WriteLine("扒取 博客园 10页 完成");
            }
    
    
    
    
            //两个 工具类, 不算入 正式代码
            public static object ReadStream(string file)
            {
                if (!File.Exists(file)) return null;
    
                try
                {
                    BinaryFormatter myBf = new BinaryFormatter();
                    using (FileStream myFs = new FileStream(file, FileMode.Open))
                    {
                        object record = myBf.Deserialize(myFs);
                        return record;
                    }
                }
                catch { return null; }
            }
            public static string ReadHtml(string url, Encoding encoding)
            {
                string result = string.Empty;
                try
                {
                    using (WebClient webClient = new WebClient { Headers = { { "user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)" } } })
                    {
                        using (Stream stream = webClient.OpenRead(url))
                        {
                            if (stream != null)
                            {
                                using (StreamReader streamReader = new StreamReader(stream, encoding))
                                {
                                    result = streamReader.ReadToEnd();
                                    stream.Close();
                                    streamReader.Close();
                                }
                            }
                        }
                    }
                }
                catch (Exception exp)
                {
                    string logMsg = string.Format("BaseUtil.WebTools.ReadHtml(url) 通过 Url: |{0}| 获取网页Html 时发生错误:{1}", url, exp);
                    Console.WriteLine(logMsg);
                }
                return result;
            }
        }
    }

    源码点击下载(包括 核心框架源码) —— 如果您觉得 本文不错,麻烦点击一下 右下角的推荐。

     

  • 相关阅读:
    DataGridView 实现,折叠的Tree效果
    DEV 总结
    EWS:邮箱的一个开放的接口服务
    socket,模拟服务器、客户端通信
    在ASP.NET Core中构建路由的5种方法
    扩展方法、泛型、委托,的小案例
    操作Work、Excel、PDF
    d3实现家族树
    大数据时代的图表可视化利器——highcharts,D3和百度的echarts
    函数防抖与节流
  • 原文地址:https://www.cnblogs.com/shuxiaolong/p/20150807_001.html
Copyright © 2011-2022 走看看