當前位置:
首頁 > 知識 > linux c++爬蟲(一)

linux c++爬蟲(一)

1 int main(int argc, void *argv[])
2 {
3 struct epoll_event events[10];
4 int daemonized = 0;
5 char ch;
6
7
8 while ((ch = getopt(argc, (char* const*)argv, "vhd")) != -1) { 9 switch(ch) { 10 case "v": 11 version; 12 break; 13 case "d": 14 daemonized = 1; 15 break; 16 case "h": 17 case "?": 18 default: 19 usage; 20 } 21 } 22 23 24 g_conf = initconfig; 25 loadconfig(g_conf); 26 27 28 set_nofile(1024); 29 30 31 vector::iterator it = g_conf->modules.begin; 32 for(; it != g_conf->modules.end; it++) { 33 dso_load(g_conf->module_path, *it); 34 } 35 36 37 if (g_conf->seeds == NULL) { 38 SPIDER_LOG(SPIDER_LEVEL_ERROR, "We have no seeds!"); 39 } else { 40 int c = 0; 41 char ** splits = strsplit(g_conf->seeds, ",", &c, 0); 42 while (c--) { 43 Surl * surl = (Surl *)malloc(sizeof(Surl)); 44 surl->url = url_normalized(strdup(splits[c])); 45 surl->level = 0; 46 surl->type = TYPE_HTML; 47 if (surl->url != NULL) 48 push_surlqueue(surl); 49 } 50 } 51 52 53 if (daemonized) 54 daemonize; 55 56
57 chdir("download"); 58 59 60 int err = -1; 61 if ((err = create_thread(urlparser, NULL, NULL, NULL)) < 0) { 62 SPIDER_LOG(SPIDER_LEVEL_ERROR, "Create urlparser thread fail: %s", strerror(err)); 63 } 64 65 /* waiting seed ourl ready */ 66 int try_num = 1; 67 while(try_num < 8 && is_ourlqueue_empty) 68 usleep((10000 << try_num++)); 69 70 if (try_num >= 8) { 71 SPIDER_LOG(SPIDER_LEVEL_ERROR, "NO ourl! DNS parse error?"); 72 } 73 74 /* set ticker */ 75 if (g_conf->stat_interval > 0) { 76 signal(SIGALRM, stat); 77 set_ticker(g_conf->stat_interval); 78 } 79 80 /* begin create epoll to run */ 81 int ourl_num = 0; 82 g_epfd = epoll_create(g_conf->max_job_num); 83 84 while(ourl_num++ < g_conf->max_job_num) { 85 if (attach_epoll_task < 0) 86 break; 87 } 88 89 /* epoll wait */ 90 int n, i; 91 while(1) { 92 n = epoll_wait(g_epfd, events, 10, 2000); 93 printf("epoll:%d ",n); 94 if (n == -1) 95 printf("epoll errno:%s ",strerror(errno)); 96 fflush(stdout); 97 98 if (n <= 0) { 99 if (g_cur_thread_num <= 0 && is_ourlqueue_empty && is_surlqueue_empty) { 100 sleep(1); 101 if (g_cur_thread_num <= 0 && is_ourlqueue_empty && is_surlqueue_empty) 102 break; 103 } 104 } 105 106 for (i = 0; i < n; i++) { 107 evso_arg * arg = (evso_arg *)(events[i].data.ptr); 108 if ((events[i].events & EPOLLERR) || 109 (events[i].events & EPOLLHUP) || 110 (!(events[i].events & EPOLLIN))) { 111 SPIDER_LOG(SPIDER_LEVEL_WARN, "epoll fail, close socket %d",arg->fd); 112 close(arg->fd); 113 continue; 114 } 115 116 epoll_ctl(g_epfd, EPOLL_CTL_DEL, arg->fd, &events[i]); /* del event */ 117 118 printf("hello epoll:event=%d
",events[i].events); 119 fflush(stdout); 120 create_thread(recv_response, arg, NULL, NULL); 121 } 122 } 123 124 SPIDER_LOG(SPIDER_LEVEL_DEBUG, "Task done!"); 125 close(g_epfd); 126 return 0; 127 }

本項目主要進行網頁的抓取,上述為主控制模塊

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=1
seeds=http://www.imeiding.com
logfile=spiderq.log

# Set the level to log. The probable values list as follow:
# 0 DEBUG
# 1 INFO
# 2 WARN
# 3 ERROR
# 4 CRIT
log_level=0

max_depth=0

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接收報文進行持久化操作

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 科技優家 的精彩文章:

光速 React
Ubuntu14.04安裝samba
STM 8s 外部中斷寄存器無法寫入

TAG:科技優家 |

您可能感興趣

把玩Alpine linux(四):安裝zsh和docker
第三個版本的Ubuntu Linux抵達Windows Store
把玩Alpine linux(一):安裝
linux 安裝 jdk、tomcat + 配置 tomcat 啟動 + tomcat 命令
在 AppImage、Flathub 和 Snapcraft 平台上搜索 Linux 應用
Linux + Nginx + Uwsgi + Django 搭建單服務實現多域名訪問
Ubuntu Linux環境下shadowsocks-qt5的安裝與配置
把玩Alpine linux(五):init系統
xsos:一個在 Linux 上閱讀 SOSReport 的工具
Skype的Snap安裝包發布,Microsoft Loves Linux
Facebook開源Linux內核組件和工具:BPF、Btrfs、Netconsd、Cgroup2、PSI、Oomd
Windows Server 2016 與 Linux 的一些網路性能測試
簡單了解dd、ext3grep、extundelete與linux數據恢復
基於Debian Linux的Neptune 5.4發布啦
Windows Server 2019新特性:Linux、HCI……
SUSE Linux Enterprise High Performance Computing公測啟動
在tinycolinux上編譯pypy和hippyvm
Windows、Linux和Mac OS的區別
Linux vs Mac:Linux 比 Mac 好的 7 個原因
Linux下C函數庫:glibc與newlibc