Skip to content

如何优雅地使用c语言编写爬虫

Spico edited this page Apr 17, 2019 · 15 revisions

前言

大家在平时或多或少地都会有编写网络爬虫的需求。一般来说,编写爬虫的首选自然非python莫属,除此之外,java等语言也是不错的选择。选择上述语言的原因不仅仅在于它们均有非常不错的网络请求库和字符串处理库,还在于基于上述语言的爬虫框架非常之多和完善。良好的爬虫框架可以确保爬虫程序的稳定性,以及编写程序的便捷性。所以,这个cspider爬虫库的使命在于,我们能够使用c语言,依然能够优雅地编写爬虫程序。

爬虫的特性

  1. 配置方便。使用一句设置函数,即可定义user agent,cookie,timeout,proxy以及抓取线程和解析线程的最大数量。
  2. 程序逻辑独立。用户可以分别定义爬虫的解析函数,和数据持久化函数。并且对于解析到的新url,用户可以使用cspider提供的addUrl函数,将其加入到任务队列中。
  3. 便捷的字符串处理。cspider中提供了基于pcre的简单的正则表达式函数,基于libxml2的xpath解析函数,以及用于解析json的cJSON库。
  4. 高效的抓取。cspider基于libuv调度抓取线程和解析线程,使用curl作为其网络请求库。

使用cspider的步骤

  1. 获取cspider_t。
  2. 自定义user agent,cookie,timeout,proxy以及抓取线程和解析线程的最大数量。
  3. 添加初始要抓取的url到任务队列。
  4. 编写解析函数和数据持久化函数。
  5. 启动爬虫。

例子

先来看下简单的爬虫例子,会在后面详细讲解例子。

#include<cspider/spider.h>

void p(cspider_t *cspider, char *d, char *url, void *user_data) {

  char *get[100];
  int size = xpath(d, "//div[@id='listofficial']/div[@class='yk-row yk-v-80']/div[@class='yk-col3']/div[@class='p p-small']/div[@class='p-meta pa']/div[@class='p-meta-title']/a/@title", get, 100);

  int i;
  saveStrings(cspider, (void**)get, size, LOCK);
  freeStrings(get, size);

}

void s(void *str, void *user_data) {
  char *get = (char *)str;
  FILE *file = (FILE*)user_data;
  fprintf(file, "%s\n", get);
  return;
}

int main() {
  cspider_t *spider = init_cspider(); 
  char *agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:42.0) Gecko/20100101 Firefox/42.0";

  cs_setopt_url(spider, "http://www.youku.com/v_olist/c_96_s_0_d_0_g_0_a_0_r_0_u_0_pt_0_av_0_ag_0_sg_0_mt_0_lg_0_q_0_pr_0_h_0_p_1.html");

  cs_setopt_useragent(spider, agent);
  //指向自定义的解析函数,和数据持久化函数
  cs_setopt_process(spider, p, NULL);
  cs_setopt_save(spider, s, stdout);
  //设置抓取线程数量,和数据持久化的线程数量
  cs_setopt_threadnum(spider, DOWNLOAD, 2);
  cs_setopt_threadnum(spider, SAVE, 2);

  return cs_run(spider);
}

例子讲解

cspider_t *spider = init_cspider();获取初始的cspider。cs_setopt_xxx这类函数可以用来进行初始化设置。其中要注意的是: cs_setopt_process(spider,p,url,NULL);cs_setopt_save(spider,s,stdout);,它们分别设置了解析函数p和数据持久化函数s,这两个函数需要用户自己实现,还有用户自定义的指向上下文信息user_data的指针。在解析函数中,用户要定义解析的规则,并对解析得到的字符串数组可以调用saveStrings进行持久化,或者是调用addUrl将url加入到任务队列中。在saveStrings中传入的字符串会在用户自定义的数据持久函数中得到处理。此时,用户可以选择输出到文件或数据库等。
最后调用cs_run(spider)即可启动爬虫。
具体的API参数可在这里查看

总结

赶快使用cspider爬虫框架来编写爬虫吧!如果在使用过程中发现bug,欢迎反馈。