날짜: 1996-04-27 | 글쓴이: 도아 | 6897 번 | 프린트 | 메일로보내기

제 27강 - 검색엔진


여기서 설명하는 검색엔진은 AltaVista와 같은 형식의 키워드 검색엔진이다. 다만 AltaVista와 같은 검색엔진과의 가장 주된 차이점은 다른 사이트를 검색하는 것이 아니라 자신의 사이트를 검색한다는 것과 dB를 이용해서 검색하는 것이 아니라 등록된 디렉토리의 모든 파일을 검색한다는 것이다. 동작원리

동작원리는 다음과 같이 아주 간단하다.

검색엔진 구성 CGI 파일

search.cgi*			사이트 검색 CGI
				chmod 755 search.cgi
mycgilib.pl			검색엔진용 Library
				chmod 644 mycgilib.pl
				
설정파일

search.cfg			검색엔진의 설정파일
				chmod 644 search.cfg
				대부분의 설정의 자신의 환경에 맞게 변경
폼문서 파일

sindex.html			프레임을 만드는 HTML 파일
				chmod 644 sindex.html
stop.html			검색 폼을 포함하는 HTML 문서
				chmod 644 stop.html
				FORM의 action을 자신에 맞게 변경
sbelow.html			검색엔진에 대한 도움말 파일
				chmod 644 sbelow.html
style.css			Cascading Style Sheet 파일
				chmod 644 style.css
search.js			입력폼을 검사하는 자바스크립트
				chmod 644 search.js
검색엔진 설정

# User = 사용자 이름. search로 두면됨
# Refer = 방명록을 기동할 서버의 IP와 DNS
User = search
Refer = 210.206.89.230, comp.mailx2.com, 127.0.0.1, localhost

# SearchForm = 검색폼의 URL
# Style = 서식파일의 URL
SearchForm = /~artech/search/sindex.htm
Style = /~artech/style.css

# TitleLen = Title을 사용하지 않은 경우 Title로 사용할 단어의 수
# SummaryLen = 요약을 추출할 때 추출할 줄의 수
TitleLen = 5
SummaryLen = 5
# SearchDir = 검색할 기본 디렉토리. 이 디렉토의 하위디렉토리가 검색됨.
# SearchUrl = 검색할 디렉토리의 URL
# SearchExt = 검색할 파일의 확장.
# SearchStyle = 결과 화면에 사용할 서식 크래스. search로 두면됨.
SearchDir = /home/artech/public_html
SearchUrl =  /~artech
SearchExt = *.htm*, *.txt
SearchStyle = search

# NoSearch = 검색에서 제외할 디렉토리
NoSearch = /~artech/html40, /~artech/report
검색엔진 소스 search.cgi

  1 : #!/usr/local/bin/perl
  2 : require './mycgilib.pl';
  3 : 
  4 : $conf_path = './search.cfg';
  5 : %FORM = &read_parse;
  6 : %CONF = &read_conf($conf_path, 'search');
  7 : 
  8 : @refer = split(/, */, $CONF{'Refer'});
  9 : @nosearch = split(/, */, $CONF{'NoSearch'});
 10 : 
 11 : $search_form = $CONF{'SearchForm'};
 12 : $style = $CONF{'Style'};
 13 : $search_dir = $CONF{'SearchDir'};
 14 : $search_url = $CONF{'SearchUrl'};
 15 : @EXT = split(/, */, $CONF{'SearchExt'});
 16 : $style_class = $CONF{'SearchStyle'};
 17 : $title_length = $CONF{'TitleLen'};
 18 : $summary_length = $CONF{'SummaryLen'};
 19 : 
 20 : MAIN:
 21 : {
 22 : 	$keyword = $FORM{'keyword'};
 23 : 	$method = $FORM{'method'};
 24 : 	$case = $FORM{'case'};
 25 : 	$sortmeth = $FORM{'sortmeth'};
 26 : 	
 27 : 	&redirect($search_form) 
		if(&no_refer || $keyword eq '' || $method eq '');
 28 : 
 29 : 	%result = &search;
 30 : 
 31 : 	@key = sort(keys %result);
 32 : 	@key = reverse @key if($sortmeth eq 'desc');
 33 : 	@keylist = split(/  */, $keyword);
 34 : 
 35 : 	for(0..$#keylist) {
 36 : 		if($method eq 'and' || $method eq 'or') {
 37 : 			$key .= "$keylist[$_]";
 38 : 			$key .= '|' if($_ != $#keylist);
 39 : 		}else{
 40 : 			$key = $keyword;
 41 : 		}		
 42 : 	}
 43 : 
 44 : 	$num = $#key + 1;
 45 : 
 46 : 	print &print_header;
 47 : 	print &html_top("검색결과","$style", "$style_class");
 48 : 	print &print_title("Search Result", "검 색 결 과");
 49 : 	print "<p class=info>총 $num개가 검색되었습니다.</p>\n";
 50 : 	print "<hr noshade>\n";
 51 : 
 52 : 	if ($num == 0) {
 53 : 		print &no_result;
 54 : 	}else {
 55 : 		print "<DL>\n";
 56 : 		$count=1;
 57 : 
 58 : 		foreach $key_index (@key) {
 59 :		($url, $title, $summary, $file_date, $file_size)
			=split(/\c\V/, $result{$key_index});
 60 : 
 61 : 			if($case eq '') {
 62 : 			$summary =~ s/($key)/<span><\/span>/gi;
 63 : 			}else{
 64 : 			$summary =~ s/($key)/<span><\/span>/g;
 65 : 			}
 66 : 
 67 : 			print &table_site;
 68 : 			$count++;
 69 : 		}
 70 : 
 71 : 		print "</DL>\n";
 72 : 	}
 73 : 	print &html_bot;
 74 : 	exit;
 75 : }
 76 : 
 77 : sub no_result {
 78 : my($no) =<<No;
 79 : 
 80 : <p class=info>
 81 : 찾는 파일이 없습니다. 검색어를 줄이던가 논리합으로 검색하기 바랍니다.
 82 : No
 83 : 	return $no;
 84 : }
 85 : 
 86 : sub table_site {
 87 : 
 88 : my($table);
 89 : 	$table =<<Table_Row;
 90 : <DT> <STRONG>$count</STRONG>. <a href="$url">$title</a> <DT>
 91 : <DD> $summary <BR>
 92 : <B>갱신일자</B>: $file_date - <B>파일크기</B>: $file_size
 93 : </DD>
 94 : <P>
 95 : Table_Row
 96 : 	return $table;
 97 : }
 98 : 
 99 : sub search_path {
100 : my($path, $list, $key);
101 : 
102 : 	$search_dir =~ s/\/\//g;
103 : 
104 : 	for(0..$#EXT) {
105 : 		if($^O =~ /mswin32/i) {
106 : 			$path = "$search_dir/$EXT[$_]";
107 : 			$list .= `dir /b/S "$path"`;
108 : 			$list .= `dir /b/S/a:h "$path"`;
109 : 		}else {
110 : 			$list .= `find $search_dir -name '$EXT[$_]*' -print`;
111 : 		}
112 : 	}
113 : 
114 : 	$list =~ s/\/\//g;
115 : 
116 : 	my (@LIST) = split(/\s+/, $list);
117 : 
118 : 	if ($#nosearch >= 0) {
119 : 			$key = join('|', @nosearch);
120 : 			@LIST = grep(!/$key/i, @LIST);
121 : 	}
122 : 
123 : 	return @LIST;
124 : }
125 : 
126 : sub search {
127 : my($id, $file);
128 : my (@LIST) = &search_path;
129 : my ($search_count) = '00000';
130 : 
131 : 	foreach $file (@LIST) {
132 : 		my($title,$summary,$file_date,$file_size,$result) 
			= &extract_info($file);
133 : 
134 : 		$file =~ s/^$search_dir//ig;
135 : 		$file = "$search_url/$file";
136 : 		$file =~ s!//!/!g;
137 : 
138 : 		if($result >= 1) {
139 : 			my($search_result) 
			= "$file\cV$title\cV$summary\cV$file_date\cV$file_size";
140 : 
141 : 			if($FORM{'sort'} eq 'file') {
142 : 				$id = "$file$search_count";
143 : 				$result{$id} = $search_result;
144 : 			}elsif($FORM{'sort'} eq 'title'){
145 : 				$id = "$title$search_count";
146 : 				$result{$id} = $search_result;
147 : 			}elsif($FORM{'sort'} eq 'fsize'){
148 : 				my($file_size_temp) = $file_size;
149 : 				$file_size_temp =~ s/([1-9][0-9]*)k//ig;
150 : 				if(length($file_size_temp) <= 5) {
151 : 				$file_size_temp=('0' x
				 (5-length($file_size_temp)) . $file_size_temp);
152 : 				}
153 : 				$id = "$file_size_temp$search_count";
154 : 				$result{$id} = $search_result;
155 : 			}elsif($FORM{'sort'} eq 'fdate'){
156 : 				$id = "$file_date$search_count";
157 : 				$result{$id} = $search_result;
158 : 			}else{
159 : 				$result{$search_count} = $search_result;
160 : 			}
161 : 			$search_count++;
162 : 		}
163 : 	}
164 : 	return %result;
165 : }
166 : 
167 : sub extract_info {
168 : my($path) = @_;
169 : my($file_date,$file_size,$headline,$i,
		$join_file,$key,$len,$line,$num,$result,$summary,$title);
170 : my(@file, @keylist, @word);
171 : 
172 : 	$headline = '';
173 : 	$title = '';
174 : 
175 : 	open(FILE, $path) || die "$!";
176 : 	@file = <FILE>;
177 : 	close(FILE);
178 : 
179 : 	$path =~ tr/[A-Z]/[a-z]/;
180 : 
181 : 	($file_size, $file_date) = (stat($path))[7,9];
182 : 	$file_date = &get_date($file_date);
183 : 	$file_size = ( $file_size > 1023 ? int($file_size/1024) . "k" 
		: $file_size . "b" );
184 : 	
185 : 	if($path =~ /htm.?$/){
186 : 
187 : 		for(0..$#file) {
188 : 			$line = $file[$_];
189 : 			$headline .= $line;
190 : 			if (( $line =~/<\/head>/i ) 
				|| ( $line =~ /<\/title>/i )) {
191 : 				last;
192 : 	    		}
193 :         	}
194 : 
195 : 		$headline =~ s/\n/ /g;
196 : 		if($headline =~ m!<title>(.*)</title>!i) {
197 : 			$title = ;
198 : 		}
199 : 	}
200 : 	
201 : 	$join_file = "@file";
202 : 	$join_file =~ s/<([^>]|\n)*>//g;
203 : 	$join_file =~ s/\n\n*/\n\cV/g;
204 : 	@file = split(/\cV/, $join_file);
205 : 
206 : 	@file = &search_array(@file);
207 : 
208 : 	$result = (@file > $summary_length ? $summary_length : @file);
209 : 	for($i=0; $i < $result; $i++) {
210 : 		$len = length($file[$i]);
211 : 
212 : 		if( $len >= 70 && $#file > $result) {
213 : 			$file[$i] =~ s/(.{69}[^ |.]*)  *.*/\n/g;
214 : 		}
215 : 
216 : 		if($title eq '') {
217 : 			@word = split(/\s+/,$file[$i]);
218 : 			$num = (@word > $title_length ? $title_length : @word);
219 : 			$title = "@word[0..$num-1]";
220 : 		}
221 : 		$summary .= $file[$i];
222 : 		$summary =~ s/\n\n*/ /g;
223 : 	}
224 : 	return ($title, $summary, $file_date, $file_size, $result);
225 : }
226 : 
227 : sub search_array {
228 : my(@file) = @_;
229 : my(@keylist);
230 : 
231 : 	if($FORM{'method'} eq 'and') {
232 : 		@keylist = split(/  */, $FORM{keyword});
233 : 
234 : 		if($FORM{'case'} eq '') {
235 : 			foreach $key (@keylist) {
236 : 				@file = grep(/$key/i, @file);
237 : 			}
238 : 		}else{
239 : 			foreach $key (@keylist) {
240 : 				@file = grep(/$key/, @file);
241 : 			}
242 : 		}
243 : 	}
244 : 
245 : 	if($FORM{'method'} eq 'or') {
246 : 		@keylist = split(/  */, $FORM{keyword});
247 : 		for(0..$#keylist) {
248 : 			$key .= "$keylist[$_]";
249 : 			$key .= '|' if($_ != $#keylist);
250 : 		}
251 : 		if($FORM{'case'} eq '') {
252 : 			@file = grep(/$key/i, @file);
253 : 		}else{
254 : 			@file = grep(/$key/, @file);
255 : 		}
256 : 	}
257 : 
258 : 	if($FORM{'method'} eq 'phrase') {
259 : 		$key = $FORM{keyword};
260 : 		if($FORM{'case'} eq '') {
261 : 			@file = grep(/$key/i, @file);
262 : 		}else{
263 : 			@file = grep(/$key/, @file);
264 : 		}
265 : 	}
266 : 	return @file;
267 : }
mycgilib.pl

방명록의 mycgilib.pl을 참조 실행결과

검색엔진



다음글: 제 28강 - 웹 메일(Mail Gateway) - 작성중 (4624)1996-04-28
이전글: 제 26강 - 방명록(Guestbook) - 소스 변경중 (4591)1996-04-26

세상사는 이야기

  • 찾아라! 아이폰 순정용 >
  • 만원대 피젯 스피너를 >
  • 망하는 길을 택한 쿠팡 >
  • 물놀이에 적당한 가성 >
  • 컴퓨터를 IPTV로 2, po >
  • 컴퓨터를 IPTV로 만들 >
  • Warning.or.kr도 우회 >
  • 한국의 100대 부자, 어 >
  • 세상을 바꾼 크롬: 크 >
  • 장난(?)으로 시작한 여 >


  • RSS 구독 (익명 | 회원 | 강좌 | 포럼)
    (C) 1996 ~ 2017 QAOS.com All rights reserved.