Linux企业级项目实践之网络爬虫(28)——爬虫socket处理
Socket是进程之间交换数据的机制。这些进程即可以是同一台机器上的,也可以是通过网络连接起来的不同机器。一旦一个Socket连接建立,那么数据就能够双向传输,直到其中一端关闭连接。
通常,请求数据的应用程序叫做客户端Client,而为请求服务叫做服务器Server。基本上说,首先,服务器监听一个端口,并且等待来自客户端的连接。之后客户端创建一个,并且尝试连接服务器。接着,服务器接受了来自客户端的连接,并且开始交换数据。一旦所有的数据都已经通过socket连接传输完毕,那么任意一方都可以关闭连接了。
我们的爬虫程序只需要client端就够了。
int build_connect(int *fd, char *ip, intport)
{
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(struct sockaddr_in)); server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
if (!inet_aton(ip, &(server_addr.sin_addr))) {
return -1;
} if ((*fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
return -1;
} if (connect(*fd, (struct sockaddr *)&server_addr, sizeof(structsockaddr_in)) < 0) {
close(*fd);
return -1;
} return 0;
}
void * recv_response(void * arg)
{
begin_thread(); int i, n, trunc_head = 0, len = 0;
char * body_ptr = NULL;
evso_arg * narg = (evso_arg *)arg;
Response *resp = (Response *)malloc(sizeof(Response));
resp->header = NULL;
resp->body = (char *)malloc(HTML_MAXLEN);
resp->body_len = 0;
resp->url = narg->url; regex_t re;
if (regcomp(&re, HREF_PATTERN, 0) != 0) {/* compile error */
SPIDER_LOG(SPIDER_LEVEL_ERROR, "compile regex error");
} SPIDER_LOG(SPIDER_LEVEL_INFO, "Crawling url: %s/%s",narg->url->domain, narg->url->path); while(1) {
/* what if content-length exceeds HTML_MAXLEN? */
n = read(narg->fd, resp->body + len, 1024);
if (n < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
/**
* TODO: Why always recvEAGAIN?
* should we deal EINTR
*/
//SPIDER_LOG(SPIDER_LEVEL_WARN,"thread %lu meet EAGAIN or EWOULDBLOCK, sleep", pthread_self());
usleep(100000);
continue;
}
SPIDER_LOG(SPIDER_LEVEL_WARN, "Read socket fail: %s",strerror(errno));
break; } else if (n == 0) {
/* finish reading */
resp->body_len = len;
if (resp->body_len > 0) {
extract_url(&re,resp->body, narg->url);
}
/* deal resp->body */
for (i = 0; i < (int)modules_post_html.size(); i++) {
modules_post_html[i]->handle(resp);
} break; } else {
//SPIDER_LOG(SPIDER_LEVEL_WARN, "read socket ok! len=%d", n);
len += n;
resp->body[len] = '\0'; if (!trunc_head) {
if ((body_ptr =strstr(resp->body, "\r\n\r\n")) != NULL) {
*(body_ptr+2) = '\0';
resp->header =parse_header(resp->body);
if(!header_postcheck(resp->header)) {
goto leave; /* moduluesfilter fail */
}
trunc_head = 1; /* cover header */
body_ptr += 4;
for (i = 0; *body_ptr; i++){
resp->body[i] =*body_ptr;
body_ptr++;
}
resp->body[i] = '\0';
len = i;
}
continue;
}
}
} leave:
close(narg->fd); /* close socket */
free_url(narg->url); /* free Url object */
regfree(&re);/* free regex object */
/* free resp */
free(resp->header->content_type);
free(resp->header);
free(resp->body);
free(resp); end_thread();
return NULL;
}
Linux企业级项目实践之网络爬虫(28)——爬虫socket处理的更多相关文章
- Linux企业级项目实践之网络爬虫(1)——项目概述及准备工作
我们在学习了Linux系统编程之后,需要一些实战项目来提高自己的水平,本系列我们通过编写一个爬虫程序,将我们学习的知识进行综合应用,同时在实现项目的过程中逐渐养成一些有用的思维方式,并具有初步的软件开 ...
- Linux企业级项目实践之网络爬虫(23)——系统测试:找出系统中的bug
为了验证爬虫的业务流程.性能和健壮性需要进行测试. 软件测试是描述一种用来促进鉴定软件的正确性.完整性.安全性和质量的过程.软件测试的经典定义是:在规定的条件下对程序进行操作,以发现程序错误,衡量软件 ...
- Linux企业级项目实践之网络爬虫(30)——通过查阅RFC文档扩充更加复杂的功能
HTTP是一种很简单的请求.响应式协议,客户端发送一个请求.服务器返回一个响应.HTTP 1.1 版本规范由 RFC2616 定义.了解了 HTTP请求.响应消息在TCP数据流中的格式,很容易使用纯 ...
- Linux企业级项目实践之网络爬虫(29)——遵守robots.txt
Robots协议(也称为爬虫协议.机器人协议等)的全称是"网络爬虫排除标准"(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以 ...
- Linux企业级项目实践之网络爬虫(21)——扩展为多任务爬虫
高效的网络爬虫是搜索引擎的重要基础.采用多任务并发执行,实现类似于CPU的流水线(pipeline)运行方式,可极大地提高网络和计算资源的利用率等性能. #include "threads. ...
- Linux企业级项目实践之网络爬虫(19)——epoll接口
由于要实现爬虫程序的快速抓取,显然如果采用阻塞型的I/O方式,那么系统可能很长时间都处在等待内核响应的状态中,这样爬虫程序将大大地降低效率.然而,如果采用非阻塞I/O,那么就要一直调用应用进程,反复对 ...
- Linux企业级项目实践之网络爬虫(6)——将程序设计成为守护进程
在linux或者unix操作系统中在系统的引导的时候会开启很多服务,这些服务就叫做守护进程.为了增加灵活性,root可以选择系统开启的模式,这些模式叫做运行级别,每一种运行级别以一定的方式配置系统. ...
- Linux企业级项目实践之网络爬虫(3)——设计自己的网络爬虫
网络抓取系统分为核心和扩展组件两部分.核心部分是一个精简的.模块化的爬虫实现,而扩展部分则包括一些便利的.实用性的功能.目标是尽量的模块化,并体现爬虫的功能特点.这部分提供简单.灵活的API,在基本不 ...
- Linux企业级项目实践之网络爬虫(2)——网络爬虫的结构与工作流程
网络爬虫是捜索引擎抓取系统的重要组成部分.爬虫的主要目的是将互联网上的网页下载到本地形成一个或联网内容的镜像备份. 一个通用的网络爬虫的框架如图所示:
随机推荐
- 针对Yii框架的nginx配置
我曾经针对yii制作了 个nginx配置,其中包括了以下几项内容: rewrite规则(try_file),需要nginx0.8.6版本以上支持. 针对于icon, robots.txt文件的日志优化 ...
- [Angular 2] Using ngrx/store and Reducers for Angular 2 Application State
ngrx/store is a library that simplifies common RxJS patterns for managing state and gives you an eas ...
- [转] gdb的基本工作原理
转自: http://www.spongeliu.com/linux/howgdbwork/ 还是面某M的时候,面试官问我:“用过gdb么?” 答:“用过,调了两年bug了”.“那好,给我解释下gdb ...
- EF 已有打开的与此 Command 相关联的 DataReader,必须首先将它关闭
在以下代码中,当第二次foreach时会抛出该异常,原因是:由于Entity在读取数据的时候使用的是DbDataReader进行读取,当作为IEnumuerable<T>对象MoveNex ...
- repeater 分页显示数据
表名:ChinaStates 控件:Repeater 查询代码DA: public class ChinaStatesDA { private DataClassesDataContext Conte ...
- .Net程序员 Solr-5.3之旅 (二)Solr 安装
阅读目录 引言 Solr5.3环境搭建 Solr5.3创建第一个Core 结尾 引言 一个糟糕的设计有好的表现形式,它会被判死缓,一个好的设计有糟糕的表现形式,它会被判死刑立即执行. 以上摘自一个设计 ...
- effective C#之 - 使用属性代替成员变量
使用属性代替公共成员变量,一个很明显的好处是,很容易在一个地方对成员变量进行控制,例如: class Customer { private string name; public string Nam ...
- Java反射 - 3(动态代理)
动态代理是对包装模式的升级,可以动态的传入需要代理的对象实现代理 准备如下 1. 被代理类的接口 2.被代理类 3.处理器:InvocationHandler 4.代理调用:Proxy.newInst ...
- CentOS5.5下安装Ant
从yum源直接下ant: [root@master local]$ yum install ant 运行ant,发现报错: java.lang.NoClassDefFoundError: org/ap ...
- mongodb安装服务
一.准备工作 1:下载: http://www.mongodb.org/downloads 2:解压到ZIP到 D:\Mongodb ,在此目录下再建立2个目录 D:\Mongodb\db和D ...