作者:gzshun. 原创作品,转载请标明出处!
来源:http://blog.youkuaiyun.com/gzshun
唐僧:你想要啊?悟空,你要是想要的话你就说话嘛,你不说我怎么知道你想要呢,虽然你很有诚意地看着我,可是你还是要跟我说你想要的。你真的想要吗?那你就拿去吧!你不是真的想要吧?难道你真的想要吗?……
悟空:我Kao!
唐僧:喂喂喂!大家不要生气,生气会犯了嗔戒的!悟空你也太调皮了,我跟你说过叫你不要乱扔东西,你怎么又…你看我还没说完你又把棍子给扔掉了!月光宝盒是宝物,你把他扔掉会污染花草草也是不对的!
三.下载个人博客的主页,并分析出必要的信息,比如下载:http://blog.youkuaiyun.com/gzshun主页,程序将该文件保存到了本地的"index.html"文件中,先贴出一点html文件的源码,这样就更加清晰的了解代码的字符串解析:
博客的总页数:
博客的排名,积分信息:
贴出源码,这几个字符串解析函数没必要看,自己看下html的规则就能解析出来了:
以上使用了rank_info_addr数组,是为了在while (fgets(line, sizeof(line), fp)) 循环里面方便赋值。
博客里面可能有很多页,必须我的博客就有2页,这时候网址是这样:
http://blog.youkuaiyun.com/gzshun/article/list/1
http://blog.youkuaiyun.com/gzshun/article/list/2
所以循环下载blog.youkuaiyun.com对应自己的博客列表就行,网页文件的名称如:/gzshun/article/list/1 把gzshun改为自己的csdn的id就是了。
来源:http://blog.youkuaiyun.com/gzshun
唐僧:你想要啊?悟空,你要是想要的话你就说话嘛,你不说我怎么知道你想要呢,虽然你很有诚意地看着我,可是你还是要跟我说你想要的。你真的想要吗?那你就拿去吧!你不是真的想要吧?难道你真的想要吗?……
悟空:我Kao!
在开篇,先happy下,有个好心情,才能天天向上,奋发图强,自强不息。
继《自己动手编写优快云博客备份工具-blogspider》与《自己动手编写优快云博客备份工具-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, "优快云 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,
- 优快云_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, "优快云 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,
- 优快云_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.youkuaiyun.com/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.youkuaiyun.com/gzshun/article/list/1
http://blog.youkuaiyun.com/gzshun/article/list/2
所以循环下载blog.youkuaiyun.com对应自己的博客列表就行,网页文件的名称如:/gzshun/article/list/1 把gzshun改为自己的csdn的id就是了。
先来杯咖啡,待下一篇文章,前几天奔波在火车上,辛苦啊,今天及时赶到,马上发表,持之以恒。。