• 一键构造你的博客园目录


    最近看了一下吴军的数学之美。书很好,废话我就不多少了。看了第9章图论和网络爬虫,一直都觉得网络爬虫很牛B,搜索引擎不就是用爬虫爬网页的吗,于是想写一个简单的爬虫来爬网页试试,最先想到的就是给自己的博客建一个目录,够小够简单了吧,于是就有了这篇文章,简单的分享一下,先申明我的实现很简单没有技术含量,在看下文之前可以先看看 我的博客目录。              源码必共享

    简单介绍一下网络爬虫的原理:给你一个网页地址,先把这个网页下载下来,然后分析这个网页的内容,得到这个网页中的所有链接,然后下载这些网页,继续分析下载。这样就能下载互联网上的很多网页。原理就这么简单,实现起来就不那么容易了。由于深入不了只能说简单的。

    构造我的博客目录思路简单分析。获得你的所有文章的地址及标题,然后将这些文章分类。你的文章其实是已经分类好了的,只用得到你的文章的所有分类,然后根据分类得到所有分类下的文章,就可以得到你所有的文章及其分类,构造你的博客目录就容易了。

    被否定了的思路一:随便拿到我的一篇文章的地址,下载这篇文章,然后分析这个地址,得到这篇文章里面的所有链接,按照一定的规则得到我的文章地址,即排除无用的连接,然后以爬虫的思路得到我的所有文章,由于每篇文章都有它的分类,所以很快就能构造我的博客目录了。然而由于博客园的实现不是我想的那样,在下载一篇文章的时候,没有下面的内容,因为下面的内容就像一个双向链表一样将我的所有文章连接起来了,我只要知道一篇文章的地址,通过这个”双向链表“我就能得到我的所有文章了,可就是下载网页里偏偏没有下面的内容,于是这个最接近爬虫的方法被PASS掉了。 

    被否定了的思路二。每个人的文章都是分页显示的,我就可以下载这些内容,然后就可以得到我的所有文章,可还是有个问题,跟上面一样的原因,妹的,下载的网页中没有文章的分类,得到了所有的文章,却不知道文章的分类,叫我怎么构造目录啊。于是又被PASS掉了。

    要构造我的博客目录,这么简单的需求方法当然是很多的了,于是用了个不太想爬虫的方法。就是上面所说的,得到所有文章的分类,下载每个分类下的文章,构造博客目录。获得我的博客分类的方法很简单,如获取我的文章分类方法如下:

    请求这个地址:http://www.cnblogs.com/hlxs/mvc/blog/sidecolumn.aspx

    传入参数blogApp=hlxs;(hlxs是我在博客园的ID)

    这样就得到了我文章的所有分类,然后按照分类得到分类下的所有文章,在构造博客目录就简单了。在这个过程中只要知道某人在博客园的ID就能构造它的博客目录,我说一键构造你的博客目录不为过吧。

    如果你也想构造你的博客目录,可以先看看我的博客目录,构造你的博客目录很简单,运行程序,输入你的博客园ID,会自动生成一个”我的博客目录.txt”,将文件的内容以源码的方式发表就行。

    出处:https://www.cnblogs.com/hlxs/archive/2013/02/20/2918760.html

    =============================================================================================

    由于博客园改版了,上面的比如获取随笔分类还是使用的老的url,现在已经无法访问到这个页面了,我们通过查看源码,不难发现类似如下的代码:

    <div id="blog-sidecolumn"></div>
                        <script>loadBlogSideColumn();</script>
    </div>

    只需要在chrome中跟踪一把,看看他访问的是那个路径获取数据的,看来现在换成ajax获取的方式了,如下

     https://www.cnblogs.com/hlxs/ajax/sidecolumn.aspx

    试试上面的路径,看看能否获取到分类列表呢?

    还有就是现在的文章目录是放到用户的url下的p目录,例如

    https://www.cnblogs.com/hlxs/p/

    看看能否访问到随笔列表呢?

    还有代码里面的正则,我稍微修改了一下加了换行的匹配,如下:

    string regex = @"<a(?:(?!href=).)*href=(['""]?)(?<url>[^""s>]*)1[^>]*>(?<text>(?:(?!</?a).)*)</a>";
    regex = @"<a(?:(?!href=).)*href=(['""]?)(?<url>[^""s>]*)1[^>]*>([.
    ]?)(?<text>(?:(?!</?a).)*)([.
    ]?)</a>"; 
    Regex rx = new Regex(regex);
    return rx.Matches(content);

    完整代码:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;
    using System.Net;
    using System.Text.RegularExpressions;
    using System.Linq;
    using Utils;
    using System.Threading;
    
    namespace Reptile
    {
        class Program
        {
            static Dictionary<string, List<DataItem>> archiveList = new Dictionary<string, List<DataItem>>();//文章列表
            static List<DataItem> categoryList = new List<DataItem>();//分类列表
            static string userId = "hlxs";//用户ID,根据这个ID获取这个人的博客目录
            const string archive = "p";
            const string category = "category";
    
            private static Stream GetStream(int timeout, string url, string param)
            {
                try
                {
                    //if (!url.StartsWith("http://", StringComparison.OrdinalIgnoreCase))
                    //{
                    //    url = "http://" + url;
                    //}
                    HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
                    if (!string.IsNullOrEmpty(param))
                    {
                        req.Method = "POST";
                        req.ContentType = "application/x-www-form-urlencoded";
                        byte[] bs = Encoding.ASCII.GetBytes(param);
                        req.ContentLength = bs.Length;
                        using (Stream reqStream = req.GetRequestStream())
                        {
                            reqStream.Write(bs, 0, bs.Length);
                        }
                    }
    
                    HttpWebResponse HttpWResp = (HttpWebResponse)req.GetResponse();
                    return HttpWResp.GetResponseStream();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return null;
                }
            }
    
            //获取页面的内容
            private static string GetContent(string url, string param)
            {
                using (Stream myStream = GetStream(24000, url, param))
                {
                    if (myStream == null)
                    {
                        return string.Empty;
                    }
                    using (StreamReader sr = new StreamReader(myStream, Encoding.UTF8))
                    {
                        if (sr.Peek() > 0)
                        {
                            return sr.ReadToEnd();
                        }
                    }
                    return string.Empty;
                }
            }
    
            static MatchCollection Filter(string url, string param)
            {
                string content = GetContent(url, param);
                if (string.IsNullOrEmpty(content))
                {
                    return null;
                }
                string regex = @"<a(?:(?!href=).)*href=(['""]?)(?<url>[^""s>]*)1[^>]*>(?<text>(?:(?!</?a).)*)</a>";
                regex = @"<a(?:(?!href=).)*href=(['""]?)(?<url>[^""s>]*)1[^>]*>([.
    ]?)(?<text>(?:(?!</?a).)*)([.
    ]?)</a>"; 
    
                Regex rx = new Regex(regex);
                return rx.Matches(content);
            }
    
            //获取文章
            static void GetArchive(string url, string param)
            {
                MatchCollection matchs = Filter(url, param);
                if (matchs == null)
                {
                    return;
                }
                foreach (Match m in matchs)
                {
                    string curUrl = m.Groups["url"].Value;
                    if (curUrl.IndexOf(userId + "/" + archive) >= 0 && curUrl.IndexOf('#') < 0)
                    {
                        DataItem item = new DataItem { Text = m.Groups["text"].Value, Value = curUrl };
                        if (!archiveList.ContainsKey(url))
                        {
                            archiveList.Add(url, new List<DataItem> { item });
                        }
                        else
                        {
                            if (archiveList[url].FirstOrDefault(archiveItem => archiveItem.Value == curUrl) == null)
                            {
                                archiveList[url].Add(item);
                            }
                        }
                    }
                }
                DataItem curCategory = categoryList.FirstOrDefault(m => m.Value == url);
                if (curCategory != null)
                {
                    Console.WriteLine("    " + curCategory.Text);
                }
            }
    
            //获取文章分类
            static bool GetCategory(string url, string param)
            {
                MatchCollection matchs = Filter(url, param);
                if (matchs == null)
                {
                    return false;
                }
                Console.Clear();
                Console.WriteLine("已完成您的博客分类:");
                foreach (Match m in matchs)
                {
                    if (m.Groups["url"].Value.IndexOf(userId + "/" + category) >= 0)
                    {
                        categoryList.Add(new DataItem { Text = m.Groups["text"].Value.Trim(), Value = m.Groups["url"].Value });
                    }
                }
                return categoryList.Count == 0 ? false : true;
            }
    
            static void Main(string[] args)
            {
                Console.WriteLine("请输入你的博客园ID后回车:");
                userId = Console.ReadLine();
                string url = "http://www.cnblogs.com/" + userId + "/mvc/blog/sidecolumn.aspx";//获取博客分类地址
                url = "http://www.cnblogs.com/" + userId + "/ajax/sidecolumn.aspx";
                string param = "blogApp=" + userId;//获取你的博客分类需要你的ID
                Console.WriteLine("正在连接服务器,请稍候...");
                bool isOK = GetCategory(url, param);//获取博客分类
                if (!isOK)
                {
                    Console.Clear();
                    Console.WriteLine("你输入的博客园ID不正确,系统将在10秒后爆炸,请注意安全!");
                    Thread.Sleep(5000);
                    for (int i = 5; i >= 1; i--)
                    {
                        Thread.Sleep(1000);
                        Console.Clear();
                        Console.WriteLine(i);
                    }
                    Environment.Exit(0);
                }
                foreach (DataItem item in categoryList)
                {
                    GetArchive(item.Value, string.Empty);//获取分类中的博客
                }
                Console.Clear();
                CreateDir();
                Console.ReadKey();
    
            }
    
            //生成博客目录
            static void CreateDir()
            {
                IOHelper.DeleteFile(Environment.CurrentDirectory + "/我的博客目录.txt");
                string divFormat = "<div style='100%;float:left;margin-top:20px;background-color:#999999;font-size:20px;color:White;padding-left:5px'>{0}</div>";
                string aFormat = "<a href='{0}' target='_blank' title='{1}'>{1}</a>";
                string liFormat = "<li style='49%;float:left;line-height:30px;'>{0}</li>";
    
                string[] catelist = { "算法", "智力题", "C++", "读书", "分析", "C#", "Windows" };//这些排在前面
                for (int i = catelist.Length - 1; i >= 0; i--)
                {
                    DataItem item = categoryList.FirstOrDefault(m => m.Text.Contains(catelist[i]));
                    if (item != null)
                    {
                        categoryList.Remove(item);
                        categoryList.Insert(0, item);
                    }
                }
    
                foreach (DataItem categoryItem in categoryList)
                {
                    Console.WriteLine(categoryItem.Text);
                    WriteLine(string.Format(divFormat, categoryItem.Text));
                    List<DataItem> list;
                    if (archiveList.TryGetValue(categoryItem.Value, out list))
                    {
                        WriteLine("<ul style='padding-top:10px;clear:both;list-style:none;'>");
                        foreach (DataItem archiveItem in list)
                        {
                            Console.WriteLine("	" + archiveItem.Text);
                            WriteLine(string.Format(liFormat, string.Format(aFormat, archiveItem.Value, archiveItem.Text)));
                        }
                        WriteLine("</ul>");
                        Console.WriteLine();
                    }
                }
                WriteLine("<div style='clear:both;'>");
    
                Console.WriteLine("
    
    博客园生成Html代码已经完成,请查看 我的博客目录.txt
    ");
            }
    
            private static void WriteLine(string content)
            {
                IOHelper.WriteLine(Environment.CurrentDirectory + "/我的博客目录.txt", content);
            }
        }
    
        class DataItem
        {
            public string Text { get; set; }
            public string Value { get; set; }
        }
    }
    View Code
  • 相关阅读:
    软件加载前显示加载中画面
    datatable用法
    arcsde安装
    dev gridcontrol (一)绑定值
    dev常用
    lookupedit用法(combox功能)
    关于NetBox2.8端口问题
    asp.net中,登录互斥的相关代码(不包含中途退出的处理)
    我老婆其人其事(一)
    判断文件是否为UTF8编码(以前收集的)
  • 原文地址:https://www.cnblogs.com/mq0036/p/12656911.html
Copyright © 2020-2023  润新知