垂直爬虫爬取资源步骤:
首先选定需要抓取的目标网站,输入数据库的站源表sitelist,然后url crawler会读取出来存入map,并提出对应站点的正则解析规则。
然后根据事先制定的url列表页正则表达式,url crawler到列表页爬取列表并提取出来存入资源url表urllist,当中涉及一些列表页分页功能,具体视每个网站分页url规则而定。
从数据库的资源url表读出urls及其资源页的爬取规则,存入一个同步的队列中(一般做法会将url做md5处理,用于去重,以免重复爬取相同url,浪费资源),多线程下的每个爬虫程序将从此队列读取urls(若队列为空线程将进入等待),然后爬取每个资源页并保持页面。
最后根据爬取到的页面,进行进一步的处理。
int extract_url(regex_t *re, char *str, Url *ourl)
{
const size_t nmatch = 2;
regmatch_t matchptr[nmatch];
int len;
char *p = str;
while (regexec(re, p, nmatch, matchptr, 0) != REG_NOMATCH) {
len = (matchptr[1].rm_eo - matchptr[1].rm_so);
p = p + matchptr[1].rm_so;
char *tmp = (char *)calloc(len+1, 1);
strncpy(tmp, p, len);
tmp[len] = '\0';
p = p + len + (matchptr[0].rm_eo - matchptr[1].rm_eo);
/* exclude binary file */
if (is_bin_url(tmp)) {
free(tmp);
continue;
}
char *url = attach_domain(tmp, ourl->domain);
if (url != NULL) {
SPIDER_LOG(SPIDER_LEVEL_DEBUG, "I find a url: %s", url);
Surl * surl = (Surl *)malloc(sizeof(Surl));
surl->level = ourl->level + 1;
surl->type = TYPE_HTML;
/* normalize url */
if ((surl->url = url_normalized(url)) == NULL) {
SPIDER_LOG(SPIDER_LEVEL_WARN, "Normalize url fail");
free(surl);
continue;
}
if (iscrawled(surl->url)) { /* if is crawled */
SPIDER_LOG(SPIDER_LEVEL_DEBUG, "I seen this url: %s", surl->url);
free(surl->url);
free(surl);
continue;
} else {
push_surlqueue(surl);
}
}
}
return (p-str);
}