int main(int argc, void *argv[])
{
struct epoll_event events[];
int daemonized = ;
char ch; while ((ch = getopt(argc, (char* const*)argv, "vhd")) != -) {
switch(ch) {
case 'v':
version();
break;
case 'd':
daemonized = ;
break;
case 'h':
case '?':
default:
usage();
}
} g_conf = initconfig();
loadconfig(g_conf); set_nofile(); vector<char *>::iterator it = g_conf->modules.begin();
for(; it != g_conf->modules.end(); it++) {
dso_load(g_conf->module_path, *it);
} if (g_conf->seeds == NULL) {
SPIDER_LOG(SPIDER_LEVEL_ERROR, "We have no seeds!");
} else {
int c = ;
char ** splits = strsplit(g_conf->seeds, ',', &c, );
while (c--) {
Surl * surl = (Surl *)malloc(sizeof(Surl));
surl->url = url_normalized(strdup(splits[c]));
surl->level = ;
surl->type = TYPE_HTML;
if (surl->url != NULL)
push_surlqueue(surl);
}
} if (daemonized)
daemonize(); chdir("download"); int err = -;
if ((err = create_thread(urlparser, NULL, NULL, NULL)) < ) {
SPIDER_LOG(SPIDER_LEVEL_ERROR, "Create urlparser thread fail: %s", strerror(err));
} /* waiting seed ourl ready */
int try_num = ;
while(try_num < && is_ourlqueue_empty())
usleep(( << try_num++)); if (try_num >= ) {
SPIDER_LOG(SPIDER_LEVEL_ERROR, "NO ourl! DNS parse error?");
} /* set ticker */
if (g_conf->stat_interval > ) {
signal(SIGALRM, stat);
set_ticker(g_conf->stat_interval);
} /* begin create epoll to run */
int ourl_num = ;
g_epfd = epoll_create(g_conf->max_job_num); while(ourl_num++ < g_conf->max_job_num) {
if (attach_epoll_task() < )
break;
} /* epoll wait */
int n, i;
while() {
n = epoll_wait(g_epfd, events, , );
printf("epoll:%d\n",n);
if (n == -)
printf("epoll errno:%s\n",strerror(errno));
fflush(stdout); if (n <= ) {
if (g_cur_thread_num <= && is_ourlqueue_empty() && is_surlqueue_empty()) {
sleep();
if (g_cur_thread_num <= && is_ourlqueue_empty() && is_surlqueue_empty())
break;
}
} for (i = ; i < n; i++) {
evso_arg * arg = (evso_arg *)(events[i].data.ptr);
if ((events[i].events & EPOLLERR) ||
(events[i].events & EPOLLHUP) ||
(!(events[i].events & EPOLLIN))) {
SPIDER_LOG(SPIDER_LEVEL_WARN, "epoll fail, close socket %d",arg->fd);
close(arg->fd);
continue;
} epoll_ctl(g_epfd, EPOLL_CTL_DEL, arg->fd, &events[i]); /* del event */ printf("hello epoll:event=%d\n",events[i].events);
fflush(stdout);
create_thread(recv_response, arg, NULL, NULL);
}
} SPIDER_LOG(SPIDER_LEVEL_DEBUG, "Task done!");
close(g_epfd);
return ;
}

本项目主要进行网页的抓取,上述为主控制模块

 while ((ch = getopt(argc, (char* const*)argv, "vhd")) != -1) {

主要作用为命令行参数的解析,根据命令行参数我们判断是一些额外输出信息和以什么方式进行(ps:守护进成)

 24     g_conf = initconfig();
25 loadconfig(g_conf); 进行初始化配置,对log配置进行加载,
log配置包含了一些抓取深度,种子,动态库路径等等之类的信息
下面主要是一些需要抓取前加载的配置文件
cur_thread_num.
max_job_num=
seeds=http://www.imeiding.com
logfile=spiderq.log # Set the level to log. The probable values list as follow:
# DEBUG
# INFO
# WARN
# ERROR
# CRIT
log_level= max_depth= module_path=/etc/spider/modules/ load_module=savehtml
load_module=saveimage
load_module=maxdepth
load_module=domainlimit
load_module=headerfilter # specify which type of resource we accept. Each one a line.
# text/html is accepted default
accept_types=image/jpeg
我们将动态库都存在vector里面,以便后续使用
但是在读取配置文件的时候我们不要忘记字符串的处理,比如,空行,注释行#,空格,=划分等等问题 接下来设置守护进程,以便使任务脱离终端控制, 创建线程,通过libevent进行dns解析,,开启epoll任务,向epoll中注册事件,模式为ET模式,不断的等待内核中epoll事件的触发并进行处理 通过开启线程进行http请求,手写http头部,进行发送给server端一个http请求报文

http协议请求页面时的流程:

1、 输入网址

2、 向DNS发送解析请求

3、 DNS返回给我们一个对应的IP地址

4、 通过IP地址向资源所在的主机发送请求

5、 如果资源存在,主机返回200状态,同时返回数据部分

6、 本地http客户端(一般来说是浏览器)接收数据

7、 得到资源

得到http接受报文的时候,对http接收报文进行解析,解析内部的url并放入队列中,并对http接收报文进行持久化操作

linux c++爬虫(一)的更多相关文章

  1. Linux shell爬虫实现树洞网自动回复Robot

    奇怪的赞数 人生在世,不如意事十之八九,可与言者无二三人.幸好我们生在互联网时代,现实中找不到可以倾诉的人还可以在网络上寻找发情绪宣泄口,树洞这类产品就是提供一个让人在网络上匿名倾诉的平台. 我是偶然 ...

  2. Linux 驱动开发

    linux驱动开发总结(一) 基础性总结 1, linux驱动一般分为3大类: * 字符设备 * 块设备 * 网络设备 2, 开发环境构建: * 交叉工具链构建 * NFS和tftp服务器安装 3, ...

  3. 微信小程序开发 [00] 写在前面的话,疯狂唠唠

    我总是喜欢在写东西之前唠唠嗑,按照惯例会在博文的开篇写这么一段"写在前面的话",这次却为了这个唠嗑单独开了一篇文,大概预想着要胡说八道的话有点多. 前段时间突然对小程序来了兴趣,说 ...

  4. Shell脚本日志关键字监控+告警

    最近小张的爬虫程序越来越多,可当爬虫程序报错,不能及时的发现,从而造成某些重要信息不能及时获取的问题,更有甚者,遭到领导的批评.于是就在想有没有一种方法,当爬取信息报错的时候,可以通过邮件或者短信的方 ...

  5. 在linux下python爬虫进程发生异常时自动重启直至正常结束的方法

    之前在做爬虫的时候遇到一种情况,当网络情况不太好的时候,爬虫爬到的链接在urlopen时会因为无法正常连接而报URLError或者timeout的错误导致陈序报错而终止:但是这些错误在重新运行陈序后能 ...

  6. Linux企业级项目实践之网络爬虫(19)——epoll接口

    由于要实现爬虫程序的快速抓取,显然如果采用阻塞型的I/O方式,那么系统可能很长时间都处在等待内核响应的状态中,这样爬虫程序将大大地降低效率.然而,如果采用非阻塞I/O,那么就要一直调用应用进程,反复对 ...

  7. Linux企业级项目实践之网络爬虫(6)——将程序设计成为守护进程

    在linux或者unix操作系统中在系统的引导的时候会开启很多服务,这些服务就叫做守护进程.为了增加灵活性,root可以选择系统开启的模式,这些模式叫做运行级别,每一种运行级别以一定的方式配置系统. ...

  8. Linux企业级项目实践之网络爬虫(1)——项目概述及准备工作

    我们在学习了Linux系统编程之后,需要一些实战项目来提高自己的水平,本系列我们通过编写一个爬虫程序,将我们学习的知识进行综合应用,同时在实现项目的过程中逐渐养成一些有用的思维方式,并具有初步的软件开 ...

  9. Linux 安装python爬虫框架 scrapy

    Linux 安装python爬虫框架 scrapy http://scrapy.org/ Scrapy是python最好用的一个爬虫框架.要求: python2.7.x. 1. Ubuntu14.04 ...

随机推荐

  1. Vue服务端渲染和Vue浏览器端渲染的性能对比

    Vue 2.0 开始支持服务端渲染的功能,所以本文章也是基于vue 2.0以上版本.网上对于服务端渲染的资料还是比较少,最经典的莫过于Vue作者尤雨溪大神的 vue-hacker-news.本人在公司 ...

  2. PRINCE2考试一共多少道题

    一.Foundation 基础级: 考试时长 1 个小时: 75 道单选题,其中 5 道随机测试题,无论对错都不计入考分:满分 70 分,获得 35 分才能通过考试,正确率 50%: 全程闭卷考试 二 ...

  3. FitVids,一个轻视频插件,操作简单

    最近在找一个视频插件,偶尔看见一个口碑啥的都不错的插件,FitsVids. fitvids.js 是个轻量级,易于使用的 jQuery 插件,用来在网页上播放指定宽度的嵌入视频.Fitvides.js ...

  4. Linux网络那点事

    跨平台系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#linux 之前的之前说过网络自连接的配置(CentOS服务器网络配置:http://ww ...

  5. 【Electron】Electron开发入门

    Electron简介: Electron提供了丰富的本地(操作系统)的API,使你能够使用纯JavaScript来创建桌面应用程序,并且跨平台(win,mac,linux等各种PC端平台).与其它各种 ...

  6. Swift: 使用cocoapods进行单元测试找不到bridge_header文件

    准备对项目进行单元测试,在 command + U 运行时出现了错误找不到桥接文件,如下图所示. 找了各种资料,终于解决了,如下图,可以发现search path中路径都为空,由于unit test是 ...

  7. ASP.NET Core MVC和Visual Studio入门

    本教程将教你使用Visual Studio 2017创建 ASP.NET Core MVC web应用程序的基础知识. 安装Visual Studio 2017 和.Net Core 安装Visual ...

  8. VS Code 的常用快捷键

    VS Code 的常用快捷键和插件 一.vs code 的常用快捷键 1.注释: a) 单行注释:[ctrl+k,ctrl+c] 或 ctrl+/ b) 取消单行注释:[ctrl+k,ctrl+u] ...

  9. Python javascript操作DOM

    文档对象模型(Document Object Model,DOM)是一种用于HTML和XML文档的编程接口.它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式.我们最为关心的是,DOM把 ...

  10. HibernateTemplate的使用

    HibernateTemplate 提供了非常多的常用方法来完成基本的操作,比如增加.删除.修改及查询等操作,Spring 2.0 更增加对命名 SQL 查询的支持,也增加对分页的支持.大部分情况下, ...