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

唐僧:你想要啊?悟空,你要是想要的话你就说话嘛,你不说我怎么知道你想要呢,虽然你很有诚意地看着我,可是你还是要跟我说你想要的。你真的想要吗?那你就拿去吧!你不是真的想要吧?难道你真的想要吗?…… 
悟空:我Kao!

在开篇,先happy下,有个好心情,才能天天向上,奋发图强,自强不息。

继《自己动手编写CSDN博客备份工具-blogspider》与《自己动手编写CSDN博客备份工具-blogspider之源码分析(1)》博文后,继续贴出处理的一些函数,原理很简单。

一.在博客的下载过程中,打印了一些信息到屏幕,也保存到了*.log文件

/*********************************************************
将爬虫链表的内容打印到log文件,格式为"csdn_id.log",比如
我的博客的地址为: "gzshun.log"
*********************************************************/
static void print_spider(blog_spider *spider_head)
{
char file[BUFSIZE] = {0};
char tmpbuf[BUFSIZE] = {0};
blog_spider *spider;
FILE *fp;
sprintf(file, "%s.log", csdn_id);
fp = fopen(file, "a+");
if (NULL == fp) {
#ifdef SPIDER_DEBUG
fprintf(stderr, "fopen: %s\n", strerror(errno));
#endif
return;
}
setvbuf(fp, NULL, _IONBF, 0);
fseek(fp, 0, SEEK_END);
spider = spider_head->next;
while (spider) {
fprintf(fp, "%d:\n"
"%-15s : %s\n"
"%-15s : %s\n"
"%-15s : %s\n"
"%-15s : %d\n"
"%-15s : %d\n"
"%-15s : %s\n\n",
spider->blog->b_seq_num,
"title", spider->blog->b_title,
"url", spider->blog->b_url,
"date", spider->blog->b_date,
"reads", spider->blog->b_reads,
"comments", spider->blog->b_comments,
"download",
(spider->blog->b_download == BLOG_DOWNLOAD) ? "Download" : "UnDownload");
spider = spider->next;
}
fclose(fp);
}
/*********************************************************
将博客的基本信息打印到标准输出
*********************************************************/
static void print_rank(blog_rank *rank)
{
char file[BUFSIZE] = {0};
FILE *fp;
sprintf(file, "%s.log", csdn_id);
fp = fopen(file, "w+");
if (NULL == fp) {
#ifdef SPIDER_DEBUG
fprintf(stderr, "fopen: %s\n", strerror(errno));
#endif
return;
}
setvbuf(stdout, NULL, _IONBF, 0);
fprintf(stdout, "CSDN ID : %s\n"
"TITLE   : %s\n"
"URL     : %s/%s\n"
"%s\n"
"%s\n"
"%s\n"
"%s\n"
"%s\n"
"%s\n"
"%s\n",
csdn_id,
rank->b_title,
CSDN_BLOG_URL,
csdn_id,
rank->b_page_view,
rank->b_integral,
rank->b_ranking,
rank->b_original,
rank->b_reship,
rank->b_translation,
rank->b_comments);
fprintf(fp, "CSDN ID : %s\n"
"TITLE   : %s\n"
"URL     : %s/%s\n"
"%s\n"
"%s\n"
"%s\n"
"%s\n"
"%s\n"
"%s\n"
"%s\n",
csdn_id,
rank->b_title,
CSDN_BLOG_URL,
csdn_id,
rank->b_page_view,
rank->b_integral,
rank->b_ranking,
rank->b_original,
rank->b_reship,
rank->b_translation,
rank->b_comments);
fclose(fp);
}

唐僧:喂喂喂!大家不要生气,生气会犯了嗔戒的!悟空你也太调皮了,我跟你说过叫你不要乱扔东西,你怎么又…你看我还没说完你又把棍子给扔掉了!月光宝盒是宝物,你把他扔掉会污染花草草也是不对的! 

二.申请了空间,在程序结束后必须释放,要不内存泄露了,污染到内存,污染到花花草草也是不对的.

/*********************************************************
释放爬虫链表的空间
*********************************************************/
static void free_spider(blog_spider * spider_head)
{
blog_spider *pspider;
blog_spider *tmp;
pspider = spider_head;
while (pspider) {
if (pspider->blog->b_url) {
free(pspider->blog->b_url);
}
if (pspider->blog->b_host) {
free(pspider->blog->b_host);
}
if (pspider->blog->b_page_file) {
free(pspider->blog->b_page_file);
}
if (pspider->blog->b_local_file) {
free(pspider->blog->b_local_file);
}
if (pspider->blog->b_title) {
free(pspider->blog->b_title);
}
if (pspider->blog->b_date) {
free(pspider->blog->b_date);
}
free(pspider->blog);
tmp = pspider->next; /*保存下一个节点地址*/
free(pspider);
pspider = tmp;
}
}
/*********************************************************
释放博客基本信息结构体空间
*********************************************************/
static void free_rank(blog_rank *rank)
{
if (rank->b_title) {
free(rank->b_title);
}
if (rank->b_page_view) {
free(rank->b_page_view);
}
if (rank->b_integral) {
free(rank->b_integral);
}
if (rank->b_ranking) {
free(rank->b_ranking);
}
if (rank->b_original) {
free(rank->b_original);
}
if (rank->b_reship) {
free(rank->b_reship);
}
if (rank->b_translation) {
free(rank->b_translation);
}
if (rank->b_comments) {
free(rank->b_comments);
}
free(rank);
}

三.下载个人博客的主页,并分析出必要的信息,比如下载:http://blog.csdn.net/gzshun主页,程序将该文件保存到了本地的"index.html"文件中,先贴出一点html文件的源码,这样就更加清晰的了解代码的字符串解析:

博客标题:

<div class="header">
<div id="blog_title">
<h1>
<a href="/gzshun">Open Linux C/C++专栏</a></h1>
<h2></h2>
<div class="clear">
</div>
</div>

博客的总页数:

<!--显示分页-->
<div id="papelist" class="pagelist">
<span> 35条数据  共2页</span><strong>1</strong> <a href="/gzshun/article/list/2">2</a> <a href="/gzshun/article/list/2">下一页</a> <a href="/gzshun/article/list/2">尾页</a>
只需要获取到"尾页"前面的数字即可.

博客的排名,积分信息:

  <span>gzshun</span>
</div>
<div id="blog_medal">
</div>
<ul id="blog_rank">
<li>访问:<span>54524次</span></li>
<li>积分:<span>1070分</span></li>
<li>排名:<span>第5615名</span></li>
</ul>
<ul id="blog_statistics">
<li>原创:<span>29篇</span></li>
<li>转载:<span>6篇</span></li>
<li>译文:<span>0篇</span></li>
<li>评论:<span>209条</span></li>
</ul>

贴出源码,这几个字符串解析函数没必要看,自己看下html的规则就能解析出来了:

/**********************************************************
获取博客的基本信息,包括以下几点(以下是按照页面的顺序,
若不按照该顺序,每次查找必须重设偏移量到开头rewind(fp)):
这里获取很多信息, 具体参考blog_spider与blog_rank结构体
**********************************************************/
static int get_blog_info(blog_spider * spider_head, blog_rank * rank)
{
FILE *fp;
int count;
char *posA, *posB, *posC, *posD, *posE;
char tmpbuf[BUFSIZE]   = {0};
char tmpbuf2[BUFSIZE]  = {0};
char line[BUFSIZE]     = {0};
char *rank_info_addr[7];
fp = fopen(spider_head->blog->b_local_file, "r");
if (NULL == fp) {
fprintf(stderr, "fopen: %s\n", strerror(errno));
return -1;
}
/*查找博客的标题*/
sprintf(tmpbuf, "<a href=\"/%s\">", csdn_id);
while (fgets(line, sizeof(line), fp)) {
posA = strstr(line, tmpbuf);
if (posA) {
posA += strlen(tmpbuf);
posB = strstr(posA, "</a>");
*posB = 0;
/*设置爬虫头结点的标题*/
spider_head->blog->b_title = strdup(posA);
rank->b_title = strdup(posA);
#ifdef SPIDER_DEBUG
printf("%s\n", spider_head->blog->b_title);
#endif
break;
}
}
/*查找博客文章的总页数*/
while (fgets(line, sizeof(line), fp)) {
posA = strstr(line, HTML_MULPAGE);
if (posA) {
fgets(line, sizeof(line), fp);
posB = strrstr(line, BLOG_HREF);
/* /gzshun/article/list/N, N就是总页数 */
memset(tmpbuf, 0, sizeof(tmpbuf));
sprintf(tmpbuf, "/%s/%s/", csdn_id, BLOG_NEXT_LIST);
posB += strlen(BLOG_HREF) + strlen(tmpbuf);
posC = strchr(posB, '"');
*posC = 0;
rank->b_page_total = atoi(posB);
spider_head->blog->b_seq_num = rank->b_page_total;
#ifdef SPIDER_DEBUG
printf("b_page_total = %d\n", rank->b_page_total);
#endif
break;
}
}
/*总共有7条信息: 访问 积分 排名 原创 转载 译文 评论*/
while (fgets(line, sizeof(line), fp)) {
posA = strstr(line, BLOG_RANK);
if (posA) {
count = 0;
while (fgets(line, sizeof(line), fp)) {
posB = strstr(line, BLOG_LI);
if (posB) {
if (7 == count) {
break;
}
posB += strlen(BLOG_LI);
posC = strstr(posB, BLOG_SPAN_HEAD);
posD = posC + strlen(BLOG_SPAN_HEAD);
posE = strstr(posD, BLOG_SPAN_END);
*posC = 0;
*posE = 0;
memset(tmpbuf, 0, sizeof(tmpbuf));
memset(tmpbuf2, 0, sizeof(tmpbuf2));
strcpy(tmpbuf, posB);
strcpy(tmpbuf2, posD);
strcat(tmpbuf, tmpbuf2);
rank_info_addr[count++] = strdup(tmpbuf);
}
}
rank->b_page_view     = rank_info_addr[0];
rank->b_integral      = rank_info_addr[1];
rank->b_ranking       = rank_info_addr[2];
rank->b_original      = rank_info_addr[3];
rank->b_reship        = rank_info_addr[4];
rank->b_translation   = rank_info_addr[5];
rank->b_comments      = rank_info_addr[6];
break;
}
}
fclose(fp);
return 0;
}

以上使用了rank_info_addr数组,是为了在while (fgets(line, sizeof(line), fp)) 循环里面方便赋值。
博客里面可能有很多页,必须我的博客就有2页,这时候网址是这样:
http://blog.csdn.net/gzshun/article/list/1
http://blog.csdn.net/gzshun/article/list/2

所以循环下载blog.csdn.net对应自己的博客列表就行,网页文件的名称如:/gzshun/article/list/1 把gzshun改为自己的csdn的id就是了。

先来杯咖啡,待下一篇文章,前几天奔波在火车上,辛苦啊,今天及时赶到,马上发表,持之以恒。。

自己动手编写CSDN博客备份工具-blogspider之源码分析(2)相关推荐

  1. 自己动手编写CSDN博客备份工具-blogspider之源码分析(3)

    作者:gzshun. 原创作品,转载请标明出处! 来源:http://blog.csdn.net/gzshun 周星驰:剪头发不应该看别人怎么剪就发神经跟流行,要配合啊!你看你的发型,完全不配合你的脸 ...

  2. python+shell 备份 CSDN 博客文章,CSDN博客备份工具

    python+shell 备份 CSDN 博客文章,CSDN博客备份工具 在 csdn 写了几年的博客了.多少也积累了两三百篇博文,近日,想把自己的这些文章全部备份下来,于是开始寻找解决方案. 我找到 ...

  3. CSDN 博客备份工具

    前言 核心 登录模块 备份模块 博文扫描模块 演示 如何使用 效果 总结 前言 近段时间以来,听群友博友都在谈论着一件事:"CSDN博客怎么没有备份功能啊?".这其实也在一定程度上 ...

  4. switchyomega规则列表备份_求人不如求己,自己动手写一个CSDN博客备份小工具?...

    前提概要 背景 因为笔者在上个月的时候,突然想扩展一下技术栈,不能仅仅局限于Java,还是得掌握一门工具语言,不然显得太low.所以也就对Python和Golang类的语言有了一些兴趣.也就在上个月简 ...

  5. 【小工具】CSDN博客导出工具-Java集成Maven开发

    CSDN博客导出工具 之前一直想把CSDN的博客导入到自己的网站中,可是由于博客比较多,后面受朋友老郭启发,就找了个时间用Java开发了这款小工具. 转载请注明出处:http://chenhaoxia ...

  6. 博客备份工具——小收集

    打算长期写原创博客了,当然也就要考虑备份问题了.虽然服务器很稳定,但是一旦出什么差错,技术类的东西丢了真的很难恢复,特别痛苦. 所以收集一下可用的工具吧,针对CSDN,因为我们现在有代码片了,不知道各 ...

  7. 博客备份工具BlogDown 软件使用感想

    最近在找博客备份相关的工具,看到了一个不错的博客备份工具BlogDown.使用博客备份BlogDown工具是可以制作博客电子书的.他支持导出多种文件格式,包括常用的电子书格式chm,还有word格式d ...

  8. Blog_Backup:绿色博客备份工具

    Blog_Backup 是一款功能完善的博客备份软件,支持国内所有大型BSP,可导出内容为多种格式.支持的导出的格式包括:RSS 1.0,RSS 2.0,Atom 0.3,单个网页(正序.反序),多个 ...

  9. CSDN博客导出工具

    我把 CSDN 博客当作笔记本来用,记录我遇到的坎儿 突然有一天夜里,我写的博客提交之后都没了,也不知道是哪里出了问题,一般白天博客审查很快,夜里都下班了得等到第二天审查,可是第二天发现博客空了,草稿 ...

  10. 开源-一步步实现cnblogs博客采集工具-对项目需求的分析

    欢迎继续关注CnblogsFan开源项目, 在昨天的项目时间中, 我们已经完成了项目开始前的一些准备工作, 今天, 我们就一起来分析下项目的一些需求. 在对需求进行分析之前我们先来再次熟悉下一个完整项 ...

最新文章

  1. 接上一篇配置多仓库相关命令
  2. Leetcode 223. 矩形面积 解题思路及C++实现
  3. springmvc教程--注解开发基础详解
  4. 前端图片有时候能显示有时候不显示_如何自动搞定全站图片的alt属性?
  5. 爬虫基本原理及Request和Response分析
  6. 此地址使用了一个通常用于网络浏览以外的端口。出于安全原因,Firefox 取消了该请求...
  7. sam格式的结构和意义_各种格式的练字本,对写字真有帮助吗
  8. 苹果将iOS应用带入macOS
  9. opencv 的norm_OpenCV学习笔记(一)之图像金字塔-上采样与降采样与DOG
  10. Oracle RAC的五大优势及其劣势
  11. sql-labs超详细教程
  12. linux软盘镜像下载,Linux系统各发行版镜像下载(持续更新)
  13. 尚硅谷Java入门视频教程(一)编程入门
  14. 关于 “总机服务” 新增功能来电弹屏的功能说明
  15. LaTex创建四级目录
  16. 使用扩展卡尔曼滤波(EKF)进行AHRS九轴姿态融合
  17. 12 道腾讯前端面试真题及答案整理
  18. 计算机右键无法新建excel2007,右键无法新建Excel
  19. [wine5.0] 解决wine所有软件乱码(中文不显示)问题
  20. DDOS攻击相关问题

热门文章

  1. linux网卡加vlan标签,如何在 CentOS/RHEL 系统中使用带 VLAN 标记的以太网卡
  2. Mac搭建本地局域网SVN服务(Cornerstone)
  3. 全球及中国水电行业开发规划及十四五投资战略报告2021年版
  4. Docker学习笔记——Docker基础
  5. oracle_用户与概要文件
  6. python 大小写字母怎么用数字表示_python判断字符串是字母 数字 大小写(转载)...
  7. 【IoT】 产品设计:硬件产品经理核心能力培养
  8. 安卓投屏助手(B1425)
  9. SCZ的3篇有关sam的文章
  10. eNSP综合实验——简易园区网的搭建