开源搜索引擎abelkhan
发起一个开源项目http://www.abelkhan.com/
目前而言,已经用python编写了一个网络爬虫抓取页面,和一个简单的前端
网络爬虫,已经有很多高手写过,我基本上奉行了拿来主义,
得益于python完善的lib,这个网络爬虫实现起来非常的简单:
使用urllib2从对应的url地址抓取html
def get_page(url):
try:
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebkit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240',
'Connection':'Keep-Alive',
'Accept':'text/html, application/xhtml+xml, image/jxr, */*',
'Accept-Language':'zh-Hans-CN,zh-Hans;q=0.8,en-US;q=0.5,en;q=0.3',
} cookie_jar = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie_jar))
req = urllib2.Request(url = url, headers = headers)
response = opener.open(req, timeout = 5)
the_page = response.read()
headers = response.info() return the_page, headers
except:
import traceback
traceback.print_exc()
一个需要注意的地方是,有部分网站会限制爬虫访问,所以我加入了headers用于模拟浏览器访问。
这个方法差强人意,但是我也没有找到一个更完善的办法。
抓取到页面后,基于HTMLParser做了html的解析:
class htmlprocess(HTMLParser.HTMLParser):
def __init__(self, urlinfo):
HTMLParser.HTMLParser.__init__(self) self.urllist = {}
self.sub_url = "" self.urlinfo = urlinfo
self.current_url = urlinfo['url'] keywords = doclex.simplesplit(self.current_url)
for key in keywords:
if key != "com" and key != "www" and key != "cn":
self.urlinfo['keys'][''].append(key) self.current_tag = ""
self.style = "" def handle_starttag(self, tag, attrs):
self.current_tag = tag
self.style = 'None'
self.sub_url = "" if tag == 'meta':
for name,value in attrs:
if name == 'name':
if value == 'keywords' or value == 'metaKeywords':
self.style = 'keywords'
elif value == 'description' or value == 'metaDescription':
self.style = 'profile' for name,value in attrs:
if name == 'content':
if self.style == 'keywords':
keywords = doclex.simplesplit(value)
if isinstance(keywords, list):
for key in keywords:
self.urlinfo['keys'][''].append(key)
elif self.style == 'profile':
self.urlinfo['profile'][''] = value encodingdate = chardet.detect(value)
if encodingdate['encoding']:
udata = unicode(value, encodingdate['encoding'])
tlen = 16
if len(udata) < 16:
tlen = len(udata)
self.urlinfo['titlegen'].append(udata[0:tlen].encode('utf-8'))
else:
self.urlinfo['titlegen'].append(value) if tag == 'a' or tag == 'A' or tag == 'link':
self.sub_url = ""
for name,value in attrs:
if name == 'href':
if len(value) == 0:
return if not judged_url(value):
if self.current_url[len(self.current_url) - 1] != '/' and value[0] != '/':
value = self.current_url + '/' + value
else:
value = self.current_url + value if value.find('javascript') != -1:
return if value.find('javaScript') != -1:
return if self.current_url.find("apple") != -1:
if value.find("http://www.apple.com/cn/mac#ac-gn-menustate") !=-1:
return if self.current_url.find("cnblogs") != -1:
if value.find("http://msg.cnblogs.com/send?recipient=itwriter") != -1:
return
elif value.find("http://i.cnblogs.com/EditPosts.aspx?opt=1") != -1:
return
elif value.find("http://i.cnblogs.com/EditPosts.aspx?postid=1935371") != -1:
return
elif value.find("http://msg.cnblogs.com/send?recipient=itwriter/") != -1:
return
elif value.find("http://msg.cnblogs.com/send?recipient=itwriter/GetUsername.aspx") != -1:
return
elif value.find("/EnterMyBlog.aspx?NewArticle=1") != -1:
return
elif value.find("GetUsername") != -1:
return
elif value.find("GetMyPassword") != -1:
return
elif value.find("http://i.cnblogs.com/EditPosts.aspx?postid=") != -1:
return
elif value[len(value) - 1] == '#':
value = value[0:-1] if self.current_url.find(value) != -1:
return if value[len(value) - 1] == '#':
value = value[0:-1] if value != self.current_url and len(value) < 64 and not ingoreurl(value):
self.urllist[value] = {'url':value, 'keys':{'':[], '':[], '':[]}, 'title':'', 'titlegen':[], 'profile':{'':'', '':'', '':[]}}
self.sub_url = value
print value def handle_data(self, data):
if self.current_tag == 'title':
try:
data = doclex.delspace(data)
keys = doclex.lex(data)
if isinstance(keys, list) and len(keys) > 0:
for key in keys:
self.urlinfo['keys'][''].append(key)
if len(data) > 0:
self.urlinfo['title'] = data
except:
import traceback
traceback.print_exc() elif self.current_tag == 'a':
try:
if self.sub_url != "":
keys = doclex.simplesplit(data)
if isinstance(keys, list) and len(keys) > 0:
for key in keys:
if key in self.urllist[self.sub_url]['keys']['']:
self.urllist[self.sub_url]['keys'][''].remove(key)
if key not in self.urllist[self.sub_url]['keys'][''] and key not in self.urllist[self.sub_url]['keys']['']:
self.urllist[self.sub_url]['keys'][''].append(key) encodingdate = chardet.detect(data)
if encodingdate['encoding']:
udata = unicode(data, encodingdate['encoding'])
tlen = 16
if len(udata) < 16:
tlen = len(udata)
self.urllist[self.sub_url]['titlegen'].append(udata[0:tlen].encode('utf-8'))
if len(udata) > 16:
self.urllist[self.sub_url]['profile'][''] = udata[0:32].encode('utf-8') except:
import traceback
traceback.print_exc()
else:
try:
if not doclex.invialddata(data):
data = doclex.delspace(data) encodingdate = chardet.detect(data)
udata = unicode(data, encodingdate['encoding'])
tlen = 16
if len(udata) < 16:
tlen = len(udata)
self.urlinfo['titlegen'].append(udata[0:tlen].encode('utf-8')) if len(udata) > 32:
self.urlinfo['profile'][''].append((udata[0:32] + u"...").encode('utf-8')) keys1 = doclex.lex(data)
for key in keys1:
self.urlinfo['keys'][''].append(key) except:
import traceback
traceback.print_exc()
基本上,要说的就是HTMLParser使用方法见文档,HTMLParser预先了定义了一组虚接口handle_starttag,handle_data和handle_endtag,使用者通过重载这三个接口,来实现对html中的tag进行处理,进而完整的解析抓取到的html。
然后从搜索结果来看,搜索的质量还很不尽如人意,欢迎大家的参与和提出意见
向我们提出意见:http://www.abelkhan.com/guestbook/
对项目进行捐助:http://www.abelkhan.com/collection/
代码托管地址如下:https://github.com/qianqians/websearch欢迎大家参与
开源搜索引擎abelkhan的更多相关文章
- 开源搜索引擎Iveely 0.8.0发布,终见天日
这是一篇博客,不是,这是一篇开源人的心酸和喜悦,没有人可以理解我们的心情,一路的辛酸一路的艰辛,不过还好,在大家的支持下,总算是终见天日,谢谢那些给予我们无私帮助的朋友.您的支持,依然是我们无限的动力 ...
- 开源搜索引擎Iveely 0.7.0发布,不一样,那就让他不一样!
2012年08月05日,Iveely Search Engine 0.1.0发布,今天,怀着对于未来的追求,终于,0.7.0如期和大家见面了,7个版本,历时2年4个月,感谢大家的支持,感谢我不离不弃的 ...
- 开源搜索引擎评估:lucene sphinx elasticsearch
开源搜索引擎评估:lucene sphinx elasticsearch 开源搜索引擎程序有3大类 lucene系,java开发,包括solr和elasticsearch sphinx,c++开发,简 ...
- 开源搜索引擎Iveely 0.8.0
开源搜索引擎Iveely 0.8.0 这是一篇博客,不是,这是一篇开源人的心酸和喜悦,没有人可以理解我们的心情,一路的辛酸一路的艰辛,不过还好,在大家的支持下,总算是终见天日,谢谢那些给予我们无私帮助 ...
- Solr vs. Elasticsearch谁是开源搜索引擎王者
当前是云计算和数据快速增长的时代,今天的应用程序正以PB级和ZB级的速度生产数据,但人们依然在不停的追求更高更快的性能需求.随着数据的堆积,如何快速有效的搜索这些数据,成为对后端服务的挑战.本文,我们 ...
- 开源搜索引擎评估:lucene sphinx elasticsearch (zhuan)
http://lutaf.com/158.htm ************************ 开源搜索引擎程序有3大类 lucene系,java开发,包括solr和elasticsearch s ...
- 一些开源搜索引擎实现——倒排使用原始文件,列存储Hbase,KV store如levelDB、mongoDB、redis,以及SQL的,如sqlite或者xxSQL
本文说明:除开ES,Solr,sphinx系列的其他开源搜索引擎汇总于此. A search engine based on Node.js and LevelDB A persistent, n ...
- 转 Solr vs. Elasticsearch谁是开源搜索引擎王者
转 https://www.cnblogs.com/xiaoqi/p/6545314.html Solr vs. Elasticsearch谁是开源搜索引擎王者 当前是云计算和数据快速增长的时代,今天 ...
- 开源搜索引擎排名第一,Elasticsearch是如何做到的?
一.引言 随着移动互联网.物联网.云计算等信息技术蓬勃发展,数据量呈爆炸式增长.如今我们可以轻易得从海量数据里找到想要的信息,离不开搜索引擎技术的帮助. 作为开源搜索引擎领域排名第一的 Elast ...
随机推荐
- AFNetworking源码阅读
get方法: - (NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(id)parameters progress:(void ...
- Memcached for windows x64 x32 安装
Memcached for windows 一.安装Memcached 1.下载 Memcached32位:http://s3.amazonaws.com/downloads.northscale.c ...
- 门面(Facade)模式
门面模式是对象的结构模式,外部与一个子系统的通信必须通过一个统一的门面对象进行.门面模式提供一个高层次的接口,使得子系统更易于使用. 医院的例子 现代的软件系统都是比较复杂的,设计师处理复杂系统的一个 ...
- HDFS 架构简述
HDFS 架构简述 Hadoop分布式文件系统(HDFS)是一个分布式的文件系统,运行在廉价的硬件上.它与现有的分布式文件系统有很多相似之处.然而与其他的分布式文件系统的差异也是显着的.HDFS是高容 ...
- 高性能网站架构设计之缓存篇(1)- Redis C#客户端
一.什么 RedisREmote DIctionary Server,简称 Redis,是一个类似于Memcached的Key-Value存储系统.相比Memcached,它支持更丰富的数据结构,包括 ...
- 用cv::Scalar来设置opencv中图片的颜色
1 怎样使用cv::Scalar来设置opencv中的颜色 cv::Scalar的构造函数是cv::Scalar(v1, v2, v3, v4),前面的三个参数是依次设置BGR的,和RGB相反,第四个 ...
- 根据wsdl文件用soapUi快速创建webService服务(有图有真相)
最近公司业务上使用webservice 频繁.由于之前都是自己搭建webservice 自己定义提供给别人服务,现在则相反需求都是根据人家提供的wsdl 文件来生成 我们平台需要提供的接口.刚开始不知 ...
- 026 hibernate操作树形结构
树形结构:也就是目录结构,有父目录.子目录.文件等信息,而在程序中树形结构只是称为节点. 一棵树有一个根节点,而根节点也有一个或多个子节点,而一个子节点有且仅有一个父节点(当前除根节点外),而且也存在 ...
- rownum基本用法
对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数,且rownum不能以任何表的名称作为前缀. ...
- 地理位置 API
js获取地理位置的接口navigator.geolocation geolocation对象有三个方法 1.getCurrentPosition 2.watchPosition 3.clearWatc ...