开源搜索引擎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‘][‘1‘].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‘][‘1‘].append(key)
                    elif self.style == ‘profile‘:
                        self.urlinfo[‘profile‘][‘0‘] = 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‘:{‘1‘:[], ‘2‘:[], ‘3‘:[]}, ‘title‘:‘‘, ‘titlegen‘:[], ‘profile‘:{‘0‘:‘‘, ‘1‘:‘‘, ‘2‘:[]}}
                        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‘][‘2‘].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‘][‘3‘]:
                                self.urllist[self.sub_url][‘keys‘][‘3‘].remove(key)
                            if key not in self.urllist[self.sub_url][‘keys‘][‘1‘] and key not in self.urllist[self.sub_url][‘keys‘][‘2‘]:
                                self.urllist[self.sub_url][‘keys‘][‘2‘].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‘][‘1‘] = 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‘][‘2‘].append((udata[0:32] + u"...").encode(‘utf-8‘))

                    keys1 = doclex.lex(data)
                    for key in keys1:
                        self.urlinfo[‘keys‘][‘3‘].append(key)

            except:
                import traceback
                traceback.print_exc()

基本上,要说的就是HTMLParser使用方法见文档,HTMLParser预先了定义了一组虚接口handle_starttag,handle_data和handle_endtag,使用者通过重载这三个接口,来实现对html中的tag进行处理,进而完整的解析抓取到的html。

然后从搜索结果来看,搜索的质量还很不尽如人意,欢迎大家的参与和提出意见

项目地址:http://www.abelkhan.com/

向我们提出意见:http://www.abelkhan.com/guestbook/

对项目进行捐助:http://www.abelkhan.com/collection/

代码托管地址如下:https://github.com/qianqians/websearch欢迎大家参与

时间: 2024-10-27 16:49:40

开源搜索引擎abelkhan的相关文章

Solr vs. Elasticsearch谁是开源搜索引擎王者

当前是云计算和数据快速增长的时代,今天的应用程序正以PB级和ZB级的速度生产数据,但人们依然在不停的追求更高更快的性能需求.随着数据的堆积,如何快速有效的搜索这些数据,成为对后端服务的挑战.本文,我们将比较业界两个最流行的开源搜索引擎,Solr和ElasticSearch.两者都建立在Apache Lucene开源平台之上,它们的主要功能非常相似,但是在部署的易用性,可扩展性和其他功能方面也存在巨大差异. 关于Apache Solr Apache Solr基于业界大名鼎鼎的java开源搜索引擎L

开源搜索引擎的比较

为解决全站搜索问题.对开源搜索引擎的一个比较.在我的项目中,是ssh+jsp结构.选择solr是最佳的. 1. Lucene及其变种 Luncene Lucene的开发语言是Java,也是Java家族中最为出名的一个开源搜索引擎,在Java世界中已经是标准的全文检索程序,它提供了完整的查询引擎和索引引擎,没有中文分词引擎,需要自己去实现,因此用Lucene去做一个搜素引擎需要自己去架构.另外它不支持实时搜索,但linkedin和twitter有分别对Lucene改进的实时搜素. 其中Lucene

大数据处理方面的 7 个开源搜索引擎

大数据处理方面的 7 个开源搜索引擎 大数据是一个包括一切的术语,指的是数据集很大很复杂,他们需要特别设计的硬件和软件工具.数据集通常是 T 或者更大级别.这些数据集从各种各样的来源创建,包括传感器,收集气象信息,公开可用的信息,如杂志.报纸.文章.还包括购买交易记录.网络日志.医疗记 录.军事侦察.视频和图像档案和大规模的电子商务等等. 要分析这些数据需要专门的软硬件,本文介绍 7 个开源的搜索引擎适合用于大数据处理: 1. Apache Lucene Lucene 是apache软件基金会一

开源搜索引擎评估:lucene sphinx elasticsearch

目录(?)[+] 开源搜索引擎评估:lucene sphinx elasticsearch 开源搜索引擎程序有3大类 lucene系,java开发,包括solr和elasticsearch sphinx,c++开发,简单高性能 Xapian,c++开发 搜索引擎程序这个名称不妥当,严格说来应该叫做索引程序(indexing program),早期主要用来做中文全文搜索,但是随着互联网的深入普及,各家网站规模越来越大,索引程序在 优化网站架构上发挥了更大的作用:替代mysql数据库内置的索引 让m

[转载] 开源搜索引擎的比较(五)

开源搜索引擎的比较(五) 5.3整体评估 基于以上结果,本文在不同的文档集合上进行了实验, 搜索引擎建索引的时间开销较小的是ht://Dig, Indri, IXE, Lucene, MG4J, Swish-E, Swish++, Terrier, XMLSearch, 和 Zettair.而建索引后的存储大小的分析,可以分为三种类型,Lucene, MG4J, Swish-E, Swish++, XMLSearch 和 Zettair 的索引的大小是数据集大 小的25%-35%. 而Terri

开源搜索引擎

开源搜索引擎 当前是云计算和数据快速增长的时代,今天的应用程序正以PB级和ZB级的速度生产数据,但人们依然在不停的追求更高更快的性能需求.随着数据的堆积,如何快速有效的搜索这些数据,成为对后端服务的挑战.本文,我们将比较业界两个最流行的开源搜索引擎,Solr和ElasticSearch.两者都建立在Apache Lucene开源平台之上,它们的主要功能非常相似,但是在部署的易用性,可扩展性和其他功能方面也存在巨大差异. 关于Apache Solr Apache Solr基于业界大名鼎鼎的java

开源搜索引擎Iveely 0.7.0发布,不一样,那就让他不一样!

2012年08月05日,Iveely Search Engine 0.1.0发布,今天,怀着对于未来的追求,终于,0.7.0如期和大家见面了,7个版本,历时2年4个月,感谢大家的支持,感谢我不离不弃的战友魏琪,奋斗到深夜,放弃了周末的社交,就为0.7.0如期而至:感谢Bogdan P Sliwowski先生,您的支持,让我们的激情和梦想靠得越来越近.下载安装编译部署,请参考Github,Web访问的时候,请确定您的浏览器支持WebSocket. 概  要 此次的版本,最大的技术改变是将纯C#迁移

转 Solr vs. Elasticsearch谁是开源搜索引擎王者

转 https://www.cnblogs.com/xiaoqi/p/6545314.html 当前是云计算和数据快速增长的时代,今天的应用程序正以PB级和ZB级的速度生产数据,但人们依然在不停的追求更高更快的性能需求.随着数据的堆积,如何快速有效的搜索这些数据,成为对后端服务的挑战.本文,我们将比较业界两个最流行的开源搜索引擎,Solr和ElasticSearch.两者都建立在Apache Lucene开源平台之上,它们的主要功能非常相似,但是在部署的易用性,可扩展性和其他功能方面也存在巨大差

Nutch 是一个开源Java 实现的搜索引擎

Nutch 是一个开源Java 实现的搜索引擎.它提供了我们运行自己的搜索引擎所需的全部工具.包括全文搜索和Web爬虫. Nutch的创始人是Doug Cutting,他同时也是Lucene.Hadoop和Avro开源项目的创始人. Nutch 诞生于2002年8月,是Apache旗下的一个用Java实现的开源搜索引擎项目,自Nutch1.2版本之后,Nutch已经从搜索引擎演化为网络爬 虫,接着Nutch进一步演化为两大分支版本:1.X和2.X,这两大分支最大的区别在于2.X对底层的数据存储进