分类目录归档:搜索引擎

Sphinx 1.10 实时索引实现——sphinx新特性体验[转]

在2010.7.19,sphinx 1.10-beta 正式发布。本人当时做了一些很简单的测试,体验了一下其实时索引及字符串属性,今天因工作需求,再次使用
sphinx,详细的测试了一下这两个功能。并做一些记录,以供日后查询!

warning:这里只是简单的体验记录及发现的一些问题,并非指南。如需操作,请根据自己的环境调试!

1、软件:sphinx-1.10-beta-win32.zip

下载地址:http://www.sphinxsearch.com/downloads/sphinx-1.10-beta-win32.zip
系统:windows xp
2、安装配置

sphinx window下不需要安装,直接配置即可
解压 sphinx-1.10-beta-win32.zip 至 E:\sphinxserver\sphinx-1.10
复制 E:\sphinxserver\sphinx-1.10\sphinx-min.conf.in E:\sphinxserver\sphinx-1.10\sphinx.conf
编辑sphinx.conf 配置参数
[shell]
#
# Minimal Sphinx configuration sample (clean, simple, functional)
#

index testrt
{
type = rt
rt_mem_limit = 128M

path = E:/sphinxserver/sphinx-1.10/data/testrt

//utf-8 编码设置,此处只采用一元切分
charset_type = utf-8
charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F
ngram_chars = U+3000..U+2FA1F

//实时索引的字段、属性
rt_field = title
rt_field = content
rt_attr_uint = gid

//字符串属性
rt_attr_string = content
rt_attr_string = title

}

indexer
{
mem_limit = 128M
}

searchd
{
listen = 9312 #searchd 端口

# 实时索引监听端口,这些采用mysql 41协议,从0.9.9-rc2开始,sphinx searchd守护进程支持mysql二进制网络协议
# 并可通过标准的mysql api存取数据

listen = 9306:mysql41

log = E:/sphinxserver/sphinx-1.10/data/log/searchd.log #自己在对应目录下建立 data和log目录
query_log = E:/sphinxserver/sphinx-1.10/data/log/query.log
read_timeout = 5
max_children = 30
pid_file = E:/sphinxserver/sphinx-1.10/data/log/searchd.pid
max_matches = 1000
seamless_rotate = 1
preopen_indexes = 0
unlink_old = 1
workers = threads # for RT to work
}
[/shell]
3、测试

开启服务端:sphinx 守护进程 searchd

E:\sphinxserver\sphinx-1.10\bin>searchd -c ../sphinx.conf

若无错误,运行并等待接收查询

客户端 :

a、在cli上测试:

C:\>mysql -P9306 -hlocalhost##注意,我的机器直接把mysql的路径注册在系统路径,所以直接使用mysql客户端,和以往的索引进程一样,这里不设置权限,若在生产中,请注意使用防火墙进行权限过滤

C:\>mysql -P9306 -hlocalhost

Welcome to the MySQL monitor.Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 1.10-beta (r2420)

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the buffer.
mysql>
#插入一条数据
mysql> insert into testrt(id,gid,title,content) values(1,1,’hello sphinx’,'this is sphinx test record’);

#查询刚才的结果

mysql> select * from testrt where match(‘sphinx’);
+——+——–+——+—————————-+————–+
| id | weight | gid| content| title|
+——+——–+——+—————————-+————–+
|1 | 2812 |1 | this is sphinx test record | hello sphinx |
+——+——–+——+—————————-+————–+
1 row in set (0.00 sec) #正确命中

mysql> select * from testrt where match(‘mysql’);
Empty set (0.00 sec)#没有查询到
Query OK, 1 row affected (0.00 sec)
###测试证明刚才的实时索引设置正确

b、在程序端(php)上测试:
[php]
<?php
header(‘Content-type:text/html;charset=utf-8′);
//这里我使用专门用来测试sphinx的中文数据
$link = mysql_connect(‘localhost’,'root’,'password’);
mysql_query(‘set names utf8′);
mysql_select_db(‘sphinx’,$link);
$sphinxLink = mysql_connect(‘localhost:9306′);

//测试数据
//获取real-time当前最大id
$maxRs = mysql_query(‘select * from testrt order by id desc limit 1 ‘);
$maxVal = mysql_result($maxRs,0,’id’);

$sets = mysql_query(‘select co_id,co_name,co_do from sph_comp limit 1,10000′,$link);
$i = $maxVal; ##此处必须使用最大值,否则会出现数据插入失败

##注意原先可以使用 insert into values (value),(value)的逗号分隔的值方式,但这里防止内存不足,每次都直接插入索引

while ($row=mysql_fetch_assoc($sets)) {
$sphinxSql = "insert into testrt(id,gid,title,content) values ($i,{$row['co_id']},’{$row['co_name']}’,'{$row['co_do']}’)";
$res = mysql_query($sphinxSql,$sphinxLink);
$i++;
}

//搜索测试,针对中文
$key = ‘商品信息’;
$sql = "select * from testrt where match(‘{$key}’)";
$rs = mysql_query($sql,$sphinx);
while ($row = mysql_fetch_assoc($rs)) {
print_r($row);
}
die;
?>
[/php]
运行后显示结果:

Array
(
[id] => 347
[weight] => 8588
[gid] => 208
[content] => 商品信息咨询服务。
[title] => 广州市越秀区姿营商品信息咨询服务部
)

至此整个操作完成(转自:http://www.sphinxsearch.org/archives/260)

本文链接:Sphinx 1.10 实时索引实现——sphinx新特性体验
详细出处:http://www.tcreator.info/webSchool/search-engine/sphinx-1.10.html

快速安装最新 CentOS + Nginx + PHP-FPM + MySQL[转]

PHP 5.3.1
MySQL 5.0.89
Nginx 0.8.33 或 0.7.65 (可选)

现在,我们可以快速全自动搞定 CentOS + Nginx + PHP-FPM + MySQL 的安装了

这个可比网上流传的什么一键安装包要好得多,强烈推荐此法安装,适合所有菜鸟和高手
我服务器上全用的源代码编译安装,也好不到哪去,还很费劲

我这个装完已经包含 php 的一些常用扩展, PDO,eaccelerator,memcache,tidy等等

本文为 21andy.com 原创,转载请以超级链接方式注明出处 http://www.21andy.com

先新建一个 repo

# vi /etc/yum.repos.d/centos.21andy.com.repo

放入如下内容

[21Andy.com]
name=21Andy.com Packages for Enterprise Linux 5 – $basearch
baseurl=http://www.21andy.com/centos/5/$basearch/
enabled=1
gpgcheck=0
protect=1

启用 EPEL repo
i386

rpm -ihv http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm

x86_64

rpm -ihv http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm

接着导入key

rpm –import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL

好了,一键安装

# yum install nginx php-fpm mysql-server

爽吧!

如果 nginx 你要用 0.7.65 最新稳定版,把
yum -y install nginx
换成
yum -y install nginx-stable
就可以了

本文为 21andy.com 原创,转载请以超级链接方式注明出处 http://www.21andy.com

更完整的安装

yum -y update
yum -y install mysql-server
service mysqld start
mysqladmin -u root password root
service mysqld stop
yum -y install nginx php-fpm php-cli php-pdo php-mysql php-mcrypt php-mbstring php-gd php-tidy php-xml php-xmlrpc php-pear php-pecl-memcache php-eaccelerator
# APC 和 eAccelerator 有冲突,2选1
yum -y install php-pecl-apc

看下我的完整安装,只要一句

yum -y install nginx mysql-server php-fpm php-cli php-pdo php-mysql php-mcrypt php-mbstring php-gd php-tidy php-xml php-xmlrpc php-pear php-pecl-memcache php-eaccelerator

安装结果,全自动

Dependencies Resolved

==========================================================
Package Arch Version Repository Size
==========================================================
Installing:
mysql x86_64 5.0.89-1.el5 21Andy.com 3.5 M
mysql-server x86_64 5.0.89-1.el5 21Andy.com 10 M
nginx x86_64 0.8.33-3.el5 21Andy.com 422 k
php-cli x86_64 5.3.1-2.el5 21Andy.com 2.4 M
php-eaccelerator x86_64 2:0.9.6-1.el5 21Andy.com 118 k
php-fpm x86_64 5.3.1-2.el5 21Andy.com 1.2 M
php-gd x86_64 5.3.1-2.el5 21Andy.com 110 k
php-mbstring x86_64 5.3.1-2.el5 21Andy.com 1.1 M
php-mcrypt x86_64 5.3.1-2.el5 21Andy.com 27 k
php-mysql x86_64 5.3.1-2.el5 21Andy.com 84 k
php-pdo x86_64 5.3.1-2.el5 21Andy.com 91 k
php-pear noarch 1:1.9.0-1.el5 21Andy.com 420 k
php-pecl-memcache x86_64 2.2.5-3.el5 21Andy.com 44 k
php-tidy x86_64 5.3.1-2.el5 21Andy.com 31 k
php-xml x86_64 5.3.1-2.el5 21Andy.com 115 k
php-xmlrpc x86_64 5.3.1-2.el5 21Andy.com 48 k
Installing for dependencies:
gmp x86_64 4.1.4-10.el5 base 201 k
libXaw x86_64 1.0.2-8.1 base 329 k
libXmu x86_64 1.0.2-5 base 63 k
libXpm x86_64 3.5.5-3 base 44 k
libedit x86_64 2.11-2.20080712cvs.el5 epel 80 k
libmcrypt x86_64 2.5.8-4.el5.centos extras 105 k
libtidy x86_64 0.99.0-14.20070615.el5 epel 140 k
php-common x86_64 5.3.1-2.el5 21Andy.com 554 k
sqlite2 x86_64 2.8.17-5.el5 21Andy.com 165 k
t1lib x86_64 5.1.1-7.el5 epel 208 k
Updating for dependencies:
libevent x86_64 1.4.12-1.el5 21Andy.com 129 k

Transaction Summary
==========================================================
Install 26 Package(s)
Update 1 Package(s)
Remove 0 Package(s)

最后只要 yum -y update 一下,全是最新的
别忘了开机启动

chkconfig –level 345 mysqld on
chkconfig –level 345 php-fpm on
chkconfig –level 345 nginx on

来看看我用虚拟机测试的强大结果
http://www.21andy.com/blog/20100219/1703.html

补充:所有的配置文件都在 /etc 目录下,包括 nginx, php-fpm, mysql 的配置文件,请自行查找设置,以下为我的 nginx 的配置范例

先新建一个 /www 目录,网站和日志也全放在这里
别忘了建日志存放目录,你在配置文件中 access_log 用到的 /www/logs

注意:fastcgi_params 要加入这一行
# vim /etc/nginx/fastcgi_params

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

# vi /etc/nginx/nginx.conf

user nobody nobody;

worker_processes 8; #这里根据你的CPU和内存配置, 设置2到10都OK

error_log  /www/logs/nginx_error.log  crit;

pid        /usr/local/nginx/logs/nginx.pid;

#Specifies the value for maximum file descriptors that can be opened by this process.
worker_rlimit_nofile 51200;

events {
use epoll;
worker_connections 51200;
}

http {
include       mime.types;
default_type  application/octet-stream;

#charset  gb2312; # 默认编码,可以不设置

server_names_hash_bucket_size 128;
client_header_buffer_size 16k;
large_client_header_buffers 4 16k;
client_max_body_size 8m;

sendfile on;
tcp_nopush     on;

keepalive_timeout 60;

tcp_nodelay on;

fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;

gzip on;
gzip_min_length  1k;
gzip_buffers     4 16k;
gzip_http_version 1.0;
gzip_comp_level 5;
gzip_types       text/plain text/javascript application/x-javascript text/css application/xml;
gzip_vary on;

#limit_zone  crawler  $binary_remote_addr  10m;
server {
listen 80;
server_name localhost;
root  /www;
location /status {
stub_status on;
access_log  off;
}
location / {
# 这里是把所有不存在的文件和目录,全都转到 index.php 处理
try_files $uri $uri/ /index.php?q=$uri&$args;
}

# 这里分开放到 server.conf 是为了再开 server 的时候方便,统一调用,放到/etc/nginx/ 目录下
include server.conf;

log_format  access  ‘$remote_addr – $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” $http_x_forwarded_for’;
access_log  /www/logs/access.log  access;
}

server {
listen 80;
server_name www.21andy.com 21andy.com *.21andy.com;
root  /www/21andy.com;
if ($host !~* 21andy\.com$) {
return 444;
}
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
include server.conf; # 这里复用了,这段就省了
access_log  /www/logs/21andy.com_access.log  access;
}
}

# vi /etc/nginx/server.conf

index index.html index.htm index.php;

#limit_conn   crawler  20;

location ~ /\.ht {
deny all;
}

location ~ .*\.(sqlite|sq3)$ {
deny all;
}

location ~ .*\.php$ {
fastcgi_pass  unix:/tmp/php-cgi.sock;
#fastcgi_pass  127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ico)$ {
expires      30d;
access_log   off;
}

location ~ .*\.(js|css)?$ {
expires      30d;
access_log   off;
}

本行以下内容可以略过
php-fpm 也可以用以下设置,但建议用上面的,比较稳定

location ~ \.php$ {
root           /www;
fastcgi_pass   127.0.0.1:9000;
fastcgi_index  index.php;
#下面这一行要加在 /etc/nginx/fastcgi_params 里
#fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
include        fastcgi_params;
}

不管是使用 php-cgi.sock 或 9000 端口方法,nginx 和 php-fpm 都要同时设置成一样的
nginx 的设置上面已经提过,记得同时修改 php-fpm.conf 相应的地方
# vi /etc/php-fpm.conf

<value name=”listen_address”>127.0.0.1:9000</value>

<value name=”listen_address”>unix:/tmp/php-cgi.sock</value>

Nutch爬虫工作流程及文件格式详细分析(收藏)

Crawler和Searcher两部分尽量分开的目的主要是为了使两部分可以分布式配置在硬件平台上,例如将Crawler和Searcher分别放在两个主机上,这样可以提升性能。

爬虫,Crawler:

Crawler的重点在两个方面,Crawler的工作流程和涉及的数据文件的格式和含义。数据文件主要包括三类,分别是 web database,一系列的segment加上index,三者的物理文件分别存储在爬行结果目录下的db目录下webdb子文件夹内, segments文件夹和index文件夹。那么三者分别存储的信息是什么呢?

Web database,也叫WebDB,其中存储的是爬虫所抓取网页之间的链接结构信息,它只在爬虫Crawler工作中使用而和 Searcher的工作没有任何关系。WebDB内存储了两种实体的信息:page和link。Page实体通过描述网络上一个网页的特征信息来表征一个 实际的网页,因为网页有很多个需要描述,WebDB中通过网页的URL和网页内容的MD5两种索引方法对这些网页实体进行了索引。Page实体描述的网页 特征主要包括网页内的link数目,抓取此网页的时间等相关抓取信息,对此网页的重要度评分等。同样的,Link实体描述的是两个page实体之间的链接 关系。WebDB构成了一个所抓取网页的链接结构图,这个图中Page实体是图的结点,而Link实体则代表图的边。

一次爬行会产生很多个segment,每个segment内存储的是爬虫Crawler在单独一次抓取循环中抓到的网页以及这些网页的索引。 Crawler爬行时会根据WebDB中的link关系按照一定的爬行策略生成每次抓取循环所需的fetchlist,然后Fetcher通过 fetchlist中的URLs抓取这些网页并索引,然后将其存入segment。Segment是有时限的,当这些网页被Crawler重新抓取后,先 前抓取产生的segment就作废了。在存储中。Segment文件夹是以产生时间命名的,方便我们删除作废的segments以节省存储空间。

Index是Crawler抓取的所有网页的索引,它是通过对所有单个segment中的索引进行合并处理所得的。Nutch利用Lucene 技术进行索引,所以Lucene中对索引进行操作的接口对Nutch中的index同样有效。但是需要注意的是,Lucene中的segment和 Nutch中的不同,Lucene中的segment是索引index的一部分,但是Nutch中的segment只是WebDB中各个部分网页的内容和 索引,最后通过其生成的index跟这些segment已经毫无关系了。

Crawler工作流程:

在分析了Crawler工作中设计的文件之后,接下来我们研究一下Crawler的抓取流程以及这些文件在抓取中扮演的角色。Crawler的 工作原理主要是:首先Crawler根据WebDB生成一个待抓取网页的URL集合叫做Fetchlist,接着下载线程Fetcher开始根据 Fetchlist将网页抓取回来,如果下载线程有很多个,那么就生成很多个Fetchlist,也就是一个Fetcher对应一个Fetchlist。 然后Crawler根据抓取回来的网页WebDB进行更新,根据更新后的WebDB生成新的Fetchlist,里面是未抓取的或者新发现的URLs,然 后下一轮抓取循环重新开始。这个循环过程可以叫做“产生/抓取/更新”循环。

指向同一个主机上Web资源的URLs通常被分配到同一个Fetchlist中,这样的话防止过多的Fetchers对一个主机同时进行抓取造 成主机负担过重。另外Nutch遵守Robots Exclusion Protocol,网站可以通过自定义Robots.txt控制Crawler的 抓取。

在Nutch中,Crawler操作的实现是通过一系列子操作的实现来完成的。这些子操作Nutch都提供了子命令行可以单独进行调用。下面就是这些子操作的功能描述以及命令行,命令行在括号中。

1.       创建一个新的WebDb (admin db -create).

2.       将抓取起始URLs写入WebDB中 (inject).

3.       根据WebDB生成fetchlist并写入相应的segment(generate).

4.       根据fetchlist中的URL抓取网页 (fetch).

5.       根据抓取网页更新WebDb (updatedb).

6.       循环进行3-5步直至预先设定的抓取深度。

7.       根据WebDB得到的网页评分和links更新segments (updatesegs).

8.       对所抓取的网页进行索引(index).

9.       在索引中丢弃有重复内容的网页和重复的URLs (dedup).

10.   将segments中的索引进行合并生成用于检索的最终index(merge).

Crawler详细工作流程是:在创建一个WebDB之后(步骤1), “产生/抓取/更新”循环(步骤3-6)根据一些种子URLs开始启 动。当这个循环彻底结束,Crawler根据抓取中生成的segments创建索引(步骤7-10)。在进行重复URLs清除(步骤9)之前,每个 segment的索引都是独立的(步骤8)。最终,各个独立的segment索引被合并为一个最终的索引index(步骤10)。

其中有一个细节问题,Dedup操作主要用于清除segment索引中的重复URLs,但是我们知道,在WebDB中是不允许重复的URL存在 的,那么为什么这里还要进行清除呢?原因在于抓取的更新。比方说一个月之前你抓取过这些网页,一个月后为了更新进行了重新抓取,那么旧的segment在 没有删除之前仍然起作用,这个时候就需要在新旧segment之间进行除重。

另外这些子操作在第一次进行Crawler运行时可能并不用到,它们主要用于接下来的索引更新,增量搜索等操作的实现。这些在以后的文章中我再详细讲。

个性化设置:

Nutch中的所有配置文件都放置在总目录下的conf子文件夹中,最基本的配置文件是conf/nutch-default.xml。这个文 件中定义了Nutch的所有必要设置以及一些默认值,它是不可以被修改的。如果你想进行个性化设置,你需要在conf/nutch-site.xml进行 设置,它会对默认设置进行屏蔽。

Nutch考虑了其可扩展性,你可以自定义插件plugins来定制自己的服务,一些plugins存放于plugins子文件夹。Nutch 的网页解析与索引功能是通过插件形式进行实现的,例如,对HTML文件的解析与索引是通过HTML document parsing plugin,  parse-html实现的。所以你完全可以自定义各种解析插件然后对配置文件进行修改,然后你就可以抓取并索引各种类型的文件了。

Robots.txt使用指南

    当搜索引擎访问一个网站时,它首先会检查该网站的根域下是否有一个叫做robots.txt的纯文本文件。Robots.txt文件用于限定搜索引擎对其网站的访问范围,即告诉搜索引擎网站中哪些文件是允许它进行检索(下载)的。这就是大家在网络上常看到的“拒绝Robots访问标准”(Robots Exclusion Standard)。下面我们简称RES。 Robots.txt文件的格式:Robots.txt文件的格式比较特殊,它由记录组成。这些记录通过空行分开。其中每条记录均由两个域组成:
   1) 一个User-Agent(用户代理)字符串行;
   2) 若干Disallow字符串行。
   记录格式为:<Field> “:” <value>
   下面我们分别对这两个域做进一步说明。
User-agent(用户代理):
   User-agent行(用户代理行) 用于指定搜索引擎robot的名字,以Google的检索程序Googlebot为例,有:User-agent: Googlebot
   一个robots.txt中至少要有一条User-agent记录。如果有多条User-agent记录,则说明有多个robot会受到RES标准的限制。当然了,如果要指定所有的robot,只需用一个通配符”*”就搞定了,即:User-agent: *
Disallow(拒绝访问声明):
 
 在Robots.txt文件中,每条记录的第二个域是Disallow:指令行。这些Disallow行声明了该网站中不希望被访问的文件和(或)目
录。例如”Disallow:
email.htm”对文件的访问进行了声明,禁止Spiders下载网站上的email.htm文件。而”Disallow:
/cgi-bin/”则对cgi-bin目录的访问进行了声明,拒绝Spiders进入该目录及其子目录。Disallow声明行还具有通配符功能。例如
上例中”Disallow:
/cgi-bin/”声明了拒绝搜索引擎对cgi-bin目录及其子目录的访问,而”Disallow:/bob”则拒绝搜索引擎对/bob.html和
/bob/indes.html的访问(即无论是名为bob的文件还是名为bob的目录下的文件都不允许搜索引擎访问)。Disallow记录如果留空,
则说明该网站的所有部分都向搜索引擎开放。
空格 & 注释
   在robots.txt文件中,凡以”#”开头的行,均被视为注解内容,这和UNIX中的惯例是一样的。但大家需要注意两个问题:
 
  1)
RES标准允许将注解内容放在指示行的末尾,但这种格式并不是所有的Spiders都能够支持。譬如,并不是所有的Spiders都能够正确理解
“Disallow: bob
#comment”这样一条指令。有的Spiders就会误解为Disallow的是”bob#comment”。最好的办法是使注解自成一行。
   2) RES标准允许在一个指令行的开头存在空格,象”Disallow: bob #comment”,但我们也并不建议大家这么做。
Robots.txt文件的创建:
 
 需要注意的是,应当在UNIX命令行终端模式下创建Robots.txt纯文本文件。好的文本编辑器一般都能够提供UNIX模式功能,或者你的FTP客
户端软件也“应该”能够替你转换过来。如果你试图用一个没有提供文本编辑模式的HTML编辑器来生成你的robots.txt纯文本文件,那你可就是瞎子
打蚊子——白费力气了。
对RES标准的扩展:
   尽管已经提出了一些扩展标准,如Allow行或Robot版本控制(例如应该忽略大小写和版本号),但尚未得到RES工作组的正式批准认可。
附录I. Robots.txt用法举例:
   使用通配符”*”,可设置对所有robot的访问权限。
   User-agent: *
   Disallow:
   表明:允许所有搜索引擎访问网站下的所有内容。
   User-agent: *
   Disallow: /
   表明:禁止所有搜索引擎对网站下所有网页的访问。
   User-agent: *
   Disallow: /cgi-bin/Disallow: /images/
   表明:禁止所有搜索引擎进入网站的cgi-bin和images目录及其下所有子目录。需要注意的是对每一个目录必须分开声明。
   User-agent: Roverdog
   Disallow: /
   表明:禁止Roverdog访问网站上的任何文件。
   User-agent: Googlebot
Disallow: cheese.htm
   表明:禁止Google的Googlebot访问其网站下的cheese.htm文件。
   上面介绍了一些简单的设置,对于比较复杂的设置,可参看一些大型站点如CNN或Looksmart的robots.txt文件(www.cnn.com/robots.txt, www.looksmart.com/robots.txt )
附录II. 相关robots.txt文章参考:
   1. Robots.txt常见问题解析
   2. Robots Meta Tag的使用
   3. Robots.txt检测程序

网页搜索引擎竞争分析

搜索引擎公司经常说核心竞争是技术,实际上这个技术是宽泛的概念,应该包括了对用户的理解、对产品的理解、技术水平。
Google:“完美的搜索引擎需要做到确解用户之意,切返用户之需”。
搜索做得好不好不仅仅是算法的事情,更重要的是对用户意图的理解,所以搜索引擎的竞争有两个点:1.破解用户之意 2.切返用户之需。
破解用户之需是产品部门的工作。从产品经理的角度来看,对一个产品有三个工作1.需求分析 2.产品决策 3.产品的跟踪、强化。(前两个工作做好了,才能把后面的工作做好)
需求分析:就是针对用户的意图,需求做分析,确解用户之意。
产品决策:根据需求分析,结合技术可行性对产品做设计以最恰当的方式满足用户的需求。
技术实现:根据产品需求文档,完成产品的研发。

产品管理竞争:

在搜索产品理念上做得最好的公司就是google(本文均指美国google)和百度。Google要比百度更理解搜索,百度做为追随者只需要去理解google,在此基础上再建立本地化和社区化的差异化壁垒。

百度:
百度的产品部门对百度的成功起到了非常大的作用。
策略方面:根据市场情况和用户需求03年前是跟随策略,大量的获取新增互联网用户和新增的搜索用户。04年后社区化策略粘住获得用户,强化产品获取早期的搜索引擎用户。
执行方面:百度的主要产品设计都非常到位,抓住了用户最大的需求、产品的核心竞争力、同竞争对手产品的差异化、建立良好机制来运作产品,建立内部的产品管理流程(发现问题解决问题的流程)。
内部沟通:百度产品部门不仅仅把对搜索的理解灌输到每个产品经理,还将产品意识、理念影响到了高层、项目经理、工程师、市场人员身上,在产品的设计、研发、运营整个流程上时时刻刻都具有对用户需求的理解和搜索的理念。
中搜:最失败的案例。好像没有专门产品部门,很多产品都是是领导拍脑袋做产品决策。关于中搜只能用“可惜”两个字了。
雅虎中国:基本上没有产品决策权,申请做一antispam都要几个月,中国雅虎只是维护yapache,程序离开yapache就都不能用了。Yisou在王航的带领下把mp3做得的确不错,可惜内部的机制决定了雅虎中国不可能有任何前景。据说雅虎在等待百度不能跨越100亿数据量索引瓶颈,实在是……
谷歌:具体不清楚。但是从这一年多的表现来看和雅虎中国没有太大区别。
搜狗:在叫嚷100亿数据量,唉…;对搜索的理解还停留在03年。
奇虎:以前不行,近期明显感觉到产品管理能力在增强。


度在产品管理领域已经远远领先于竞争对手,百度拥有最强大的百度知道,可以在“发现问题”方面有各种专业用户基础、有庞大的用户群时时刻刻在监测他们的产
品的每一个细节可以最快速有效的在细节方面“发现问题”、有强大的产品部门集中了几乎中国对搜索理解最深的人才、流畅的链式管理机制可以用最快的方式解决
问题强化产品……
只要百度持续把这些优势发挥,那么在这个方面无以伦比,不存在一个级别的竞争对手。

技术之争:

网页搜索技术上现在进入了一个技术的相对瓶颈期,很难在理论上和技术上有大的突破(当然也有可能在任何一天有某个人提出一种新的理论颠覆了“超链接、PR”)。所以在网页搜索的技术上最关键的是如何能够针对发现的问题去解决问题。
在“网页搜索引擎的发展方向http://www.fullsearcher.com/n2006227185235735.asp”一文中有些个人的看法。其中最重要的一个方面是在自然语言处理方面,这是很多工作的基础。


页搜索引擎产品的一个方向就是垂直化针对不同的词汇,体现不同的维度,返回不同的结果。如在百度搜索“北京
天气”会体现一个提示性的链接、搜索软件你会发现百度做了专门的优化。在google搜索股票代码、手机号码等会有不同的提示性链接,有些词汇是有新闻链
接的有些是没有的。随着宽带的普及,这些垂直信息拼接会被网页搜引擎公司应用到网页搜索产品中,很明显这主要又是产品部门和技术部门协同才能很好完成的工
作。网页搜索会发展到越来越细节。

网页搜索引擎的存在有他存在的土壤,土壤环境是怎么样的呢?
1.海量的数据,互联网上有海量的数据,并且这些数据在快速增长、不断更新
2.分散的数据,这些数据存在于成千上万个网站中
3.多样化的数据
4.用户多样化的数据搜索需求
5.用户对搜索数据的实时性要求不是非常强
6.用户对这些数据有整合使用的需求,并且这种需求量很大
7.能够很好的对整合来的数据进行处理,能够完整的满足用户的这种需求,提供完整的信息检索体验

垂直搜索引擎存在的土壤:
1.网页搜索引擎无法对某类数据进行深度加工,提供更多的细化的服务
2.网页的数据实在是太多样化了(数据种类、数据类型等),不利于满足用户细分的服务
3.用户有对互联网数据进行深度采集,数据的深度加工提供更细化的服务的需求,这种需求量非常巨大
4.用户对某类信息的实时性的要求比较高
5.针对某类信息提供更简洁、更快速,更可依赖性更强的服务
6.行业性优化

垂直搜索存在的必备条件:
1.海量的数据,所选择的垂直搜索的数据必须是海量的数据,数据量和增长速度、增长量都比较大。符合搜索引擎的基本条件
2.分散的数据,这种数据必须要分散在很多个不同网站。不能是仅存在于几个网站。如果仅存在于几个网站不如做元搜索了(如果信息集中在几个网站,用户可以直接去使用)
3.用户对这些数据的实时性有一定要求,但是又不能是对实时性要求极高
(显然,春运期间的二手火车票信息就不适合做垂直搜索,因为等采集处理完毕,那票说不定已经卖掉了。拍卖的价格信息不适合做垂直搜索,有可能还没有采集处理完毕,价格已经变化了。)
4.用户对这类数据的需求量是很大的,而且需要长期使用。(搜索是需要学习、长期使用才能很好的驾驭的一种应用)
5.技术上能够很好的完成信息的整合、深度加工,并且加工后能够完整的满足用户对这类数据的搜索需求,提供完整的应用体验。
6.这种信息的深度采集、深度加工是网页搜索引擎完全不可以替代的。

垂直搜索选型的步骤:
1.选定适合您的,您熟悉的,有一定的资源背景的几个垂直搜索的被选方案。
2.查看google或百度(其它搜索引擎不行)检索关键词数据。
最好能搞到连续一段时间的全部词汇(按照检索频率排序),当然这几乎不可能,进行详细的分析、统计、挖掘。搞不到只要看风云榜和百度指数了,这估计就有很大偏差了。
对这些用户需求数据库进行深度分析找出用户到底要什么、互联网上缺什么。
(第1步和第2步交替进行)
3.分析相关行业的网站,评估用户需求、数据情况、横向竞争、纵向竞争、潜在竞争情况和可能遇到的其它问题。
4.如何满足用户的需求?如何保持产品和门户网站、搜索门户等的差异化和挖掘出用户潜在的最大的需求?
5.评估技术上的可行性,能否实现完整用户体验
6.如何保证产品的领先性(资源、效果、市场、技术、销售……)
7.产品的市场推广方式(这点非常非常重要,如何在竞争对手反应过来之前低成本的快速抵达有效用户群是成败的关键)
8.盈利模式;收入模型、成本模型
第一步完成到什么程度,达到什么目标。需要多少成本
第二步完成到什么程度,是否可以收支平衡或者获得投资
…………
9.产品的不足和先天的缺陷如何克服弥补。产品的生命周期的每一步可能出现的紧急问题如何应对。
10.不要认为自己很聪明,这世界上聪明人太多了,你能想到的肯定有n个人已经想到了。
关键在于您能不能充分利用自己的资源,做好前期的调查后专注的执行。
11.务必要找百度和google这类搜索引擎不愿意花大功夫去做(市场暂时不够大)、或者不可能能做的应用(受制约、有更重要的事情要做),不要把你的模式和意图暴露得太早,这个市场的竞争实在是太激烈了,中国人也都太聪明了。
务必要找和门户网站、网页搜索引擎有很大差异化,并且用户有持续的很大的需求的。理由很简单:搜索是需要持续使用才能熟练的一种产品、从门户和网页搜索引擎到您的垂直引擎的门槛很高(比多点击10次的门槛还高很多)。

垂直搜索引擎的选型

网页搜索引擎的存在有他存在的土壤,土壤环境是怎么样的呢?
1.海量的数据,互联网上有海量的数据,并且这些数据在快速增长、不断更新
2.分散的数据,这些数据存在于成千上万个网站中
3.多样化的数据
4.用户多样化的数据搜索需求
5.用户对搜索数据的实时性要求不是非常强
6.用户对这些数据有整合使用的需求,并且这种需求量很大
7.能够很好的对整合来的数据进行处理,能够完整的满足用户的这种需求,提供完整的信息检索体验

垂直搜索引擎存在的土壤:
1.网页搜索引擎无法对某类数据进行深度加工,提供更多的细化的服务
2.网页的数据实在是太多样化了(数据种类、数据类型等),不利于满足用户细分的服务
3.用户有对互联网数据进行深度采集,数据的深度加工提供更细化的服务的需求,这种需求量非常巨大
4.用户对某类信息的实时性的要求比较高
5.针对某类信息提供更简洁、更快速,更可依赖性更强的服务
6.行业性优化

垂直搜索存在的必备条件:
1.海量的数据,所选择的垂直搜索的数据必须是海量的数据,数据量和增长速度、增长量都比较大。符合搜索引擎的基本条件
2.分散的数据,这种数据必须要分散在很多个不同网站。不能是仅存在于几个网站。如果仅存在于几个网站不如做元搜索了(如果信息集中在几个网站,用户可以直接去使用)
3.用户对这些数据的实时性有一定要求,但是又不能是对实时性要求极高
(显然,春运期间的二手火车票信息就不适合做垂直搜索,因为等采集处理完毕,那票说不定已经卖掉了。拍卖的价格信息不适合做垂直搜索,有可能还没有采集处理完毕,价格已经变化了。)
4.用户对这类数据的需求量是很大的,而且需要长期使用。(搜索是需要学习、长期使用才能很好的驾驭的一种应用)
5.技术上能够很好的完成信息的整合、深度加工,并且加工后能够完整的满足用户对这类数据的搜索需求,提供完整的应用体验。
6.这种信息的深度采集、深度加工是网页搜索引擎完全不可以替代的。

垂直搜索选型的步骤:
1.选定适合您的,您熟悉的,有一定的资源背景的几个垂直搜索的被选方案。
2.查看google或百度(其它搜索引擎不行)检索关键词数据。
最好能搞到连续一段时间的全部词汇(按照检索频率排序),当然这几乎不可能,进行详细的分析、统计、挖掘。搞不到只要看风云榜和百度指数了,这估计就有很大偏差了。
对这些用户需求数据库进行深度分析找出用户到底要什么、互联网上缺什么。
(第1步和第2步交替进行)
3.分析相关行业的网站,评估用户需求、数据情况、横向竞争、纵向竞争、潜在竞争情况和可能遇到的其它问题。
4.如何满足用户的需求?如何保持产品和门户网站、搜索门户等的差异化和挖掘出用户潜在的最大的需求?
5.评估技术上的可行性,能否实现完整用户体验
6.如何保证产品的领先性(资源、效果、市场、技术、销售……)
7.产品的市场推广方式(这点非常非常重要,如何在竞争对手反应过来之前低成本的快速抵达有效用户群是成败的关键)
8.盈利模式;收入模型、成本模型
第一步完成到什么程度,达到什么目标。需要多少成本
第二步完成到什么程度,是否可以收支平衡或者获得投资
…………
9.产品的不足和先天的缺陷如何克服弥补。产品的生命周期的每一步可能出现的紧急问题如何应对。
10.不要认为自己很聪明,这世界上聪明人太多了,你能想到的肯定有n个人已经想到了。
关键在于您能不能充分利用自己的资源,做好前期的调查后专注的执行。
11.务必要找百度和google这类搜索引擎不愿意花大功夫去做(市场暂时不够大)、或者不可能能做的应用(受制约、有更重要的事情要做),不要把你的模式和意图暴露得太早,这个市场的竞争实在是太激烈了,中国人也都太聪明了。
务必要找和门户网站、网页搜索引擎有很大差异化,并且用户有持续的很大的需求的。理由很简单:搜索是需要持续使用才能熟练的一种产品、从门户和网页搜索引擎到您的垂直引擎的门槛很高(比多点击10次的门槛还高很多)。

谈谈网络爬虫设计中的问题

网络蜘蛛现在开源的已经有好几个了,LarbinNutchHeritrix都各有用户之地,要做一个自己的爬虫要解决好多个问题,比如调度算法、更新策略、分布式存储等,我们来一一看一下。

一个爬虫要做的事主要有以下这些

  1. 从一个网页入口,分析链接,一层一层的遍历,或者从一组网页入口,或者从一个rss源列表开始爬rss;
  2. 获取每个页面的源码保存在磁盘或者数据库里;
  3. 遍历抓下来的网页进行处理,比如提取正文,消重等;
  4. 根据用途把处理后的文本进行索引、分类、聚类等操作。

以上是个人理解哦,呵呵。这些过程中,大约有如下问题

如何获取网页源或者RSS源?

果是一般的爬虫的话,就是给几个入口页面,然后顺着超链接以遍历图的算法一个页面一个页面的爬,这种情况网页源很少,可以选择从hao123等网址大全的
网站为入口开始爬。如果做垂直搜索的话就人工去收集一些这个行业的网站,形成一个列表,从这个列表开始爬。如果是爬RSS的话,需要先收集RSS源,现在
大的门户的新闻频道和主流的博客系统都有rss的功能,可以先爬一遍网站,找出rss的链接,要获取每个链接的内容,分析是否是rss格式,如果是就把这
个链接保存到rss源数据库里,以后就专门爬这个rss源的rss。还有一种就是人工来整理,一般blog的rss都是有规律的,主域名跟一个用户名后面
再跟上一个rss的固定页面,比如http://www.abc.com/user1/rss.xml,这样就弄一个用户字典,拼接rss地址,然后用程
序去探测是否有这个页面来整理出每个网站的rss源。整理出rss源后再人工设置rss源的权重及刷新时间间隔等。

如果源页面很多,如何用多线程去有效的调度处理,而不会互相等待或者重复处理?

果现在有500万个页面要去爬,肯定要用多线程或者分布式多进程去处理了。可以把页面进行水平分割,每个线程处理一段儿,这样每个线程之间不需要同步,各
自处理各自的就行了。比如给这500W个页面分配一个自增ID,2个线程的话就让第一个线程去爬1,3,5的网页,第二个线程去爬2,4,6的网页,这样
做多个线程间基本上能均衡,而且不会相互等待,而且不会重复处理,也不会拉掉网页。每个线程一次取出1w个页面,并记录最高的源页面ID号,处理完这一批
后再从数据库里提取大于这个源页面ID号的下1W个页面,直到抓取完本线程要处理的所有页面。1w这个值根据机器的内存可做适当的调整。为了防止抓了半截
儿死机,所以要支持断点续抓,要为每个线程的处理进度保存状态,每取一批网页都要记录本线程最大的网页ID,记录到数据库里,进程重启后可以读取这个
ID,接着抓后面的页面。

如何尽量的利用CPU,尽量的不让线程处于等待、休眠、阻塞等空闲状态?而且要尽量用少的线程以减少上下文切换。

虫有两个地方需要IO操作,抓网页的时候需要通过网卡访问网络,抓到网页后要把内容写到磁盘或者数据库里。所以这两个部分要用异步IO操作,这样可以不用
线程阻塞在那里等待网页抓过来或者写完磁盘文件,网卡和硬盘都支持内存直接读取,大量的IO操作会在硬件驱动的队列里排队,而不消耗任何CPU。.net
的异步操作使用了线程池,不用自己频繁的创建和销毁线程,减少了开销,所以线程模型不用考虑,IO模型也不用考虑,.net的异步IO操作直接使用了完成
端口,很高效了,内存模型也不需要考虑,整个抓取过程各线程不需要访问共享资源,除了数据库里的源页面,各管各的,而且也是每个线程分段处理,可以实现无
锁编程。

如何不采集重复的网页?
去重可以使用king总监的布隆过滤器
每个线程使用一个bitarray,里面保存本批源页面上次抓取的页面的哈希值情况,抓取下来的源页面分析链接后,去这个bitarray里判断以前有没
有抓过这个页面,没有的话就抓下来,抓过的话就不管了。假设一个源页面有30个链接把,一批10W个源页面,300w个链接的bitarray应该也不会
占太大内存。所以有个五六个线程同时处理也是没问题的。

抓下来的页面更快的保存?保存到分布式文件系统还是保存在数据库里?

果保存到磁盘,可以每个域名创建一个文件夹,凡是这个网站的页面都放到这个文件夹下,只要文件名不一样,就不会出现冲突。如果把页面保存到磁盘,数据库有
自己的一套锁管理机制,直接用bulk
copy放数据库就行了。一般频繁的写磁盘可能会引起CPU过高,而频繁的写数据库CPU还好一些。而且sqlserver2008支持filestream类型的字段,在保存大文本字段的时候有很好的性能,并且还能使用数据库的API来访问。所以我觉得如果没有GFS那样高效成熟的分布式文件系统的话还不如存sqlserver里面呢。

如何有效的根据网页的更新频率来调整爬虫的采集时间间隔?
做爬虫要了解一些HTTP协议,如果要抓的网页支持Last-Modified或者ETag头,我们可以先发个head请求来试探这个页面有没有变化来决定是否要重新抓取,但是好多网站根本就不支持这个东西,所以让爬虫也很费劲,让自己的网站也会损失更多的性能。这样我们就要自己去标注每个源页面的更新时间间隔及权重,再根据这两个值去用一定的算法制定蜘蛛的更新策略。

采集下来的数据做什么用?
可以抓取一个行业的网站,在本地进行分词和索引,做成垂直搜索引擎。可以用一定的训练算法对抓取下来的页面进行自动分类,做成新闻门户。也可以用死小风行的文本相似度算法处理后进行文本聚类处理。

如何不影响对方网站的性能?
现在好多网站都被爬虫爬怕了,因为有些蜘蛛弄住一个网站可劲儿的爬,爬的人家网站的正常用户都无法访问了。所以好多站长想了好多办法来对付爬虫,所以我们写爬虫也要遵循机器人协议,控制单位时间内对一个网站的访问量。

尝试RSS Feed Spider

碰到的问题列表:

  1. 内容的编码问题是一个问题,需要很多功夫进行调整
  2. HTTP访问协议的问题,譬如路径重定向,以及各种错误
  3. robots协议支持的问题
  4. 垃圾信息处理的问题(譬如feedburner出来的RSS可能包含广告内容)
  5. 运行效率问题(用Java+JDBC在并发不多的情况下已经出现OutOfMemoryError了)
  6. 一些知名blog的历史文章尚未反向收集
  7. 在日期时间格式标准方面,有很多非标准的格式需要处理
  8. 未能很好地记录不同blog之间的引用关系
  9. 如何有效地控制RSS feed源头是一个问题
  10. 更新频率是写死的一天,没有频率计算调度
  11. 尚未提供添加新的RSS feed的界面接口
  12. 尚未实现全文检索,也没有对tag支持