自己动手编写CSDN博客备份工具-blogspider

作者:gzshun. 原创作品,转载请标明出处!
来源:http://blog.csdn.net/gzshun



网络爬虫(又被称为网页蜘蛛,网络机器人),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁,自动索引,模拟程序或者蠕虫。

网络爬虫最重要的任务,就是从互联网搜索出需要的信息,将网页抓取下来并分析,很多搜索引擎,比如百度,谷歌,后台都有一只很强悍的网络爬虫,用来访问互联网上的网页,图片,视频等内容,并建立索引数据库,使用户能在百度搜索引擎中搜索到您网站的网页、图片、视频等内容。

我们常见的几个大型搜索引擎公司的爬虫名称:
1.谷歌(Google) -> Googlebot
2.百度(Baidu)爬虫名称:Baiduspider
3.雅虎(Yahoo) -> Yahoo! Slurp
4.有道(Yodao) -> YodaoBot
5.搜狗(sogou) -> Sogou spider
6.MSN -> msmbot
7.腾讯搜搜 -> Sosospider

最近我突然想自己动手写一只小型的博客爬虫,将自己在CSDN博客网站写的文章给抓取下来,想做个博客备份工具。当了解到网络爬虫的用途后,就来动手实现一个应用,用来备份自己在CSDN的博客,这样即使没有网络,或者文章丢失了,我手头都有一个备份。记得上次在微博看过CSDN创始人蒋涛先生说的一句话,他想做一个CSDN博客生成PDF文档的工具,其实那也相当于对自己博客的备份,这样就能很方便的浏览自己的写的文章。

我写的这个"blogspider"程序,将会把自己博客信息提取出来,并将所有的文章下载到本地。这里只是简单的下载网页而已,里面的图片我没有下载,那得涉及到太多的东西。如果电脑有网络,将会很容易的看到博客里面的图片,如果没有网络,图片将无法显示。

blogspider程序由C语言编写的,基于Linux平台,我编写该程序的环境如下:
[plain]  view plain copy
  1. gzshun@ubuntu:~$ uname -a  
  2. Linux ubuntu 2.6.32-24-generic-pae #39-Ubuntu SMP Wed Jul 28 07:39:26 UTC 2010 i686 GNU/Linux  
  3. gzshun@ubuntu:~$ gcc -v  
  4. Using built-in specs.  
  5. Target: i486-linux-gnu  
  6. Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu  
  7. Thread model: posix  
  8. gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)  

本人在putty终端测试程序,可以正确的显示中文,要设置为UTF-8,或者GB2312,如果显示乱码,切换一下字符集试试。


一.blogspider的功能简介:

1.获取博客的基本信息:
  博客标题
  博客访问量
  博客积分
  博客排名
  博客原创文章数量
  博客转载文章数量
  博客译文文章数量
  博客评论数量

2.下载博客到本地:
  博客主题
  博客发表日期
  博客阅读次数
  博客评论次数

二.blogspider涉及到的知识点:
1.文件I/O
2.网络编程socket
3.数据结构-链表
4.内存分配


三.blogspider程序执行流程:
以我的博客为例:
1.将"http://blog.csdn.net/gzshun"主页下载到本地
2.分析该主页,获取到博客的URL
3.将博客的URL添加到爬虫链表
4.遍历爬虫链表,将博客下载到本地
5.将下载日志保存在gzshun.log


四.blogspider程序的重要部分:

1.爬虫链表的结构体

[cpp]  view plain copy
  1. typedef struct tag_blog_info {  
  2.     char *b_url;           /*网址*/  
  3.     char *b_host;          /*网站服务器主机名*/  
  4.     char *b_page_file;     /*页面文件名称*/  
  5.     char *b_local_file;    /*本地保存的文件名称*/  
  6.     char *b_title;         /*博客主题*/  
  7.     char *b_date;          /*博客发表日期*/  
  8.     int   b_port;          /*网址端口号*/  
  9.     int   b_sockfd;        /*网络套接字*/  
  10.     int   b_reads;         /*阅读次数*/  
  11.     int   b_comments;      /*评论次数*/  
  12.     int   b_download;      /*下载状态*/  
  13.     int   b_lock;          /*处理锁*/  
  14.     int   b_seq_num;       /*序号*/  
  15. }blog_info;  
  16.   
  17. typedef struct tag_blog_spider {  
  18.     blog_info *blog;  
  19.     struct tag_blog_spider *next;  
  20. }blog_spider;  

2.博客基本信息结构体

[cpp]  view plain copy
  1. typedef struct tag_blog_rank {  
  2.     int   b_page_total;    /*博客总页数*/  
  3.     char *b_title;         /*博客标题*/  
  4.     char *b_page_view;     /*博客访问量*/  
  5.     char *b_integral;      /*博客积分*/  
  6.     char *b_ranking;       /*博客排名*/  
  7.     char *b_original;      /*博客原创文章数量*/  
  8.     char *b_reship;        /*博客转载文章数量*/  
  9.     char *b_translation;   /*博客译文文章数量*/  
  10.     char *b_comments;      /*博客评论数量*/  
  11. }blog_rank;  

3.定义的函数

[cpp]  view plain copy
  1. static char *strrstr(const char *s1, const char *s2);  
  2. static char *strfchr(char *s);  
  3. static int  init_spider(blog_spider **spider);  
  4. static int  init_rank(blog_rank **rank);  
  5. static void insert_spider(blog_spider *spider_head, blog_spider *spider);  
  6. static int  spider_size(blog_spider *spider_head);  
  7. static void print_spider(blog_spider *spider_head);  
  8. static void print_rank(blog_rank *rank);  
  9. static void free_spider(blog_spider *spider_head);  
  10. static void free_rank(blog_rank *rank);  
  11. static int get_blog_info(blog_spider *spider_head, blog_rank *rank);  
  12. static int analyse_index(blog_spider *spider_head);  
  13. static int download_index(blog_spider *spider_head);  
  14. static int download_blog(blog_spider *spider);  
  15. static int get_web_host(const char *hostname);  
  16. static int connect_web(const blog_spider *spider);  
  17. static int send_request(const blog_spider * spider);  
  18. static int recv_response(const blog_spider * spider);  

4.strrstr是自己实现的,C库没有提供

1.strrstr函数:从一个字符串中查找指定字符串,返回最后一次出现的地址
程序如下:

[cpp]  view plain copy
  1. /************************************************************** 
  2. strrstr  : 查找指定字符串, 返回最后一次出现的地址, 自己实现 
  3. ***************************************************************/  
  4. static char *strrstr(const char *s1, const char *s2)  
  5. {  
  6.     int len2;  
  7.     char *ps1;  
  8.   
  9.     if (!(len2 = strlen(s2))) {  
  10.         return (char *)s1;  
  11.     }  
  12.       
  13.     ps1 = (char *)s1 + strlen(s1) - 1;  
  14.     ps1 = ps1 - len2 + 1;  
  15.   
  16.     while (ps1 >= s1) {  
  17.         if ((*ps1 == *s2) && (strncmp(ps1, s2, len2) == 0)) {  
  18.             return (char *)ps1;  
  19.         }  
  20.         ps1--;  
  21.     }  
  22.   
  23.     return NULL;  
  24. }  

5.初始化爬虫链表

[cpp]  view plain copy
  1. /********************************************************* 
  2. 初始化博客爬虫的链表节点, 申请空间并赋空值 
  3. *********************************************************/  
  4. static int init_spider(blog_spider * * spider)  
  5. {  
  6.     *spider = (blog_spider *)malloc(sizeof(blog_spider));  
  7.     if (NULL == *spider) {  
  8.         #ifdef SPIDER_DEBUG  
  9.         fprintf(stderr, "malloc: %s\n", strerror(errno));  
  10.         #endif  
  11.         return -1;  
  12.     }  
  13.   
  14.     (*spider)->blog = (blog_info *)malloc(sizeof(blog_info));  
  15.     if (NULL == (*spider)->blog) {  
  16.         #ifdef SPIDER_DEBUG  
  17.         fprintf(stderr, "malloc: %s\n", strerror(errno));  
  18.         #endif  
  19.         free(*spider);  
  20.         return -1;  
  21.     }  
  22.   
  23.     (*spider)->blog->b_url           = NULL;  
  24.     (*spider)->blog->b_host          = strdup(CSDN_BLOG_HOST);  
  25.     (*spider)->blog->b_page_file     = NULL;  
  26.     (*spider)->blog->b_local_file    = NULL;  
  27.     (*spider)->blog->b_title         = NULL;  
  28.     (*spider)->blog->b_date          = NULL;  
  29.     (*spider)->blog->b_port          = CSDN_BLOG_PORT;  
  30.     (*spider)->blog->b_sockfd        = 0;  
  31.     (*spider)->blog->b_reads         = 0;  
  32.     (*spider)->blog->b_comments      = 0;  
  33.     (*spider)->blog->b_download      = BLOG_UNDOWNLOAD;  
  34.     (*spider)->blog->b_lock          = BLOG_UNLOCK;  
  35.     (*spider)->blog->b_seq_num       = 0;  
  36.           
  37.     (*spider)->next = NULL;  
  38.   
  39.     return 0;  
  40. }  

6.初始化博客基本信息结构体

[cpp]  view plain copy
  1. /********************************************************* 
  2. 初始化博客基本信息结构体,包含以下几个变量: 
  3. 1.博客页面总页数 
  4. 2.博客标题 
  5. 3.博客访问量 
  6. 4.博客积分 
  7. 5.博客排名 
  8. 6.博客原创文章数量 
  9. 7.博客转载文章数量 
  10. 8.博客译文文章数量 
  11. 9.博客评论数量 
  12. *********************************************************/  
  13. static int init_rank(blog_rank **rank)  
  14. {  
  15.     *rank = (blog_rank *)malloc(sizeof(blog_rank));  
  16.     if (NULL == *rank) {  
  17.         #ifdef SPIDER_DEBUG  
  18.         fprintf(stderr, "malloc: %s\n", strerror(errno));  
  19.         #endif  
  20.         return -1;  
  21.     }  
  22.   
  23.     (*rank)->b_page_total      = 0;  
  24.     (*rank)->b_title           = NULL;  
  25.     (*rank)->b_page_view       = NULL;  
  26.     (*rank)->b_integral        = NULL;  
  27.     (*rank)->b_ranking         = NULL;  
  28.     (*rank)->b_original        = NULL;  
  29.     (*rank)->b_reship          = NULL;  
  30.     (*rank)->b_translation     = NULL;  
  31.     (*rank)->b_comments        = NULL;  
  32.   
  33.     return 0;  
  34. }  

五.blogspider遇到的问题:
1.博客标题如果有'/','?',或者其他不规则的符号,文件将会创建失败。
  解决方案:将不规则的符号赋空,并在后面连接"xxx"字符串,表示省略;
2.在接受网站服务器响应的时候,要将select函数的时间设置长点,有时候因为网络差的问题,将会超时导致退出程序。在blogspider里面,将timeout设置30s。
3.本程序在考虑加入多线程遍历爬虫链表,经过尝试,连接网站服务器会出现竞争问题,将导致连接延时,影响程序效率,暂时不考虑。

六.blogspider运行截图:




使用blogspider:

这里以下载我的博客为例,我CSDN的ID是:gzshun, 网址是:http://blog.csdn.net/gzshun





title              : 博客标题

url                : 博客网址

date            : 博客发表日期

reads          : 博客阅读次数

comments  : 博客评论次数

download   : 博客下载状态


以下这张图片是在windows查看的,通过samba连接到ubuntu服务器。我博客上面的所有文章已经成功地下载到本地。

打开下载在本地的html文件,此时有网络。

打开下载在本地的html文件,此时无网络。



若需要blogspider的源程序,请留下您的E-mail(注意要写成我后面的那种形式,否则会被非法网络爬虫抓取),或者直接联系我的E-mail:gzshuns#163.com (#->@).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
博客备份工具BlogDown是强大的博客和微博备份工具博客电子书制作工具,书籍下载工具。支持多种博客、微博、读书网站以及任意博客RSS方式备份,支持多种电子书导出格式和样式(txt,html,chm,word,mht,rss,wordpress),备份后的文件中包含博客图片,多线程多网站多用户同时下载。 软件主要功能和特点介绍: (+)多线程多用户多网站同时备份 真正多线程博客下载备份,可以同时下载多个不同网站不同用户的博客,在软件里面可以实时查看每个博客内容,浏览每篇博客文章,包括文本和网页形式。 (+)强大的博客备份功能 可以解析备份博客的文章标题,文章类别,发表时间,文章正文,原文地址共五项内容。 (+)支持离线博客编辑功能 可以在软件里写博客,然后把写好的博客导出成电子书,或者直接上传到相应博客网站。 (+)备份博客图片 可以备份博客文章中的图片,可以单独备份,也可以跟文章一起备份。导出的图片保存在备份文章之中,方便保存和阅读,直接浏览,无需连网,例如电子书chm,博客书word,web档案mht格式,都可以包含图片,无需连网。 (+)支持众多的博客网站 支持国内各个大型的博客网站,例如新浪博客,网易博客,百度空间,QQ空间,搜狐博客等等,本软件支持的详细博客列表见附录,会不断添加新的博客。 (+)支持多种微博 支持多种微博,包括新浪微博,搜狐微博,腾讯微博,网易微博等等。 (+)支持多种读书网站 支持多种读书网站,包括:新浪读书,腾讯读书,网易读书,搜狐读书,中华网读书,凤凰网读书。 (+)支持任意博客RSS备份 可以备份任意博客,只需要输入博客的RSS地址即可。【【严重注意】】此方法只能备份最新的几篇博客文章,无法备份全部博客文章。 (+)丰富的导出格式 【** 重点介绍**】 BlogDown可以把下载的博客文章导出为流行的文档格式和样式,具体如下: 【1】电子书chm格式(纯文本)(chm):电子书格式, 使用纯文本样式 。 【2】电子书chm格式(含图片)(chm):电子书格式,保持博客原样,文件中含图片,无需连网,所有博客一个文件,方便阅读和珍藏。 【3】电子书chm格式(含图片,按文章类别分组)【强烈推荐】(chm):文件中含图片,无需连网,保持博客样式,按照文章类别进行分类,更加清晰,方便浏览。 【4】分页电子书(chm):可以设置分页,更适合微博电子书,更适合手机阅读,包含图片,保持博客样式。 【5】多个word格式(纯文本)(doc):自动排版,纯文本,每篇博文一个word文件。 【6】单个word格式(纯文本)【《博客书》】(doc):博客书格式,纯文本,自动排版,可直接打印成书。 【7】多个word格式(含图片)(doc):自动排版,文件中含有图片,无需连网,每篇博文一个word文件。 【8】单个word格式(含图片)【《博客书》】【强烈推荐】(doc):博客书格式,自动排版,文件中含有图片,无需连网,可直接打印成书。可以设置文件中图片大小,可以设置每篇文章是否分页显示。对于微博备份,可以不用分页。 【9】多个word格式(保持博客样式)(doc):保持博客的原样,使用网页内容,每篇博客一个word文件。 【10】单个word格式(保持博客样式)(doc):保持博客的原样,使用网页内容,所有博客一个word文件。 【11】多个网页格式(html): 保持博客原样,一篇博文一个文件。 【12】单个网页格式(html): 保持博客原样,所有博客都在一个网页文件中。 【13】多文本格式(txt):一篇博文一个文件。 【14】单文本格式(txt):所有博客都在一个文件中。 【15】Web档案格式【含图片】(mth):保持博客样式,含有图片,无需连网,每篇博客一个mht文件,比网页html格式好。 【16】RSS格式(xml):标准RSS2.0格式,方便文章上传和导入到其他系统。 【17】WordPress格式【绝对图片地址,不搬家图片】(.xml)【WXR文件,使用绝对图片地址,不用下载图片】 【18】WordPress格式【相对图片地址,可以搬家图片】(.xml)【WXR文件,使用相对图片地址,需要下载图片,导入wordpress时同时把下载的博客图片文件夹拷贝到wordpress网站根目录,这样图片也可以搬家。】 【19】ePub电子书【含图片】(.epub):epub是手机中非常流行的一种电子书格式。ePub电子书【含图片】会先下载博客文章中的图片。 【20】epub电子书【纯文本】(.epub):epub是手机中非常流行的一种电子书格式。ePub电子书【纯文本】会自动对博客文章进行格式化处理,留下整齐的文本内容。 【21】umd电子书【纯文本】(.umd):umd是手机中非常普遍的一种电子书格式。 umd电子书【纯文本】会自动对博客文章进行格式化处理,留下整齐的文本内容。 (+)具备博客管理功能 可以管理下载的博客文章,包括查找博客文章,可以根据标题、正文、发表时间、文章分类的关键词来搜索博客。这样便于用户从大量的博客文章中搜索自己感兴趣的文章。可以删除博客文章,可以修改博客文章。可以添加博客文章。 (+)支持多种导出选项 可以按照要求,有选择的导出文章标题,文章类别,发表时间,文章正文,原文地址等内容。可以按照发表的时间逆序或者正序导出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值