因为课业要求,搭建一个简单的搜索引擎,找了一些相关资料并进行了部分优化(坑有点多)
一.数据
数据是网络上爬取的旅游相关的攻略页面
这个是travels表,在索引中主要用到id和url两个字段。
页面中文文章内容的爬取用了newspaper3k这个包(如果页面里面文章字数过多,需要设置一下超时时间,不然会报错)
def article(url): try: a=Article(url,language="zh") a.download() a.parse() return a.text except: pass return -1
如果报错不退出程序,返回-1
二.分词
文章爬取下来之后的分词有两种模式,全文分词,分词后提取关键词
全文分词
def cutworf(url): text=article(url) seg_list=jieba.cut_for_search(text) return seg_list
如果有很多的页面需要爬取,全文分词的速度会很慢,所以我用了关键词分词
jieba有提供两个关键词分词的方式 TF-IDF以及TextRank算法,在这里我不多详细的说明两个算法的区别。在经过分词结果的比较后,我选择了TF-IDF。
textrank = analyse.textrank tfidf = analyse.extract_tags def keyword(url): text =article(url) if text==-1: return -1 else: # 基于TF-IDF算法进行关键词抽取 keywords = tfidf(text) #print ("keywords by tfidf:") # 输出抽取出的关键词 #for keyword in keywords: #print (keyword + "/") return keywords
三.建立索引
建立索引的数据结构,我参考了https://blog.csdn.net/qq_27483535/article/details/53149021这位博主的文章
创建3个链表类型,3个节点类型(括号中表示)。
Linklist(Node):对每一个网页分词后,将词加入此链表。
Weblist(Web):把网页按照所拥有的词加入词链表,接在词的后面。
Resultlist(Result):搜索结果加入此链表。
设定停用词
ignorewords=set(['的','但是','然而','能','在','以及','可以','使','我','我们','大家','高兴','啊','哦'])
停用词可以根据文章进行添加
把分词加入链表
def index(url,count): #words=cutworf(url) keys=keyword(url) if keys==-1: return -1 dickey=list(keys) #dicn=list(words) # for i in range(len(dicn)): # word = dicn[i] # if word in ignorewords: continue # if ll.getlength() == 0: # wl = linklist.WebList() # wl.initlist(count) # ll.initlist(word, wl) # # if ll.getlength() > 0: # i = ll.index(word) # if i == -1: # wl = linklist.WebList() # wl.initlist(count) # ll.append(word, wl) # # print(word) # if i != -1: # j = ll.getwh(i).index(count) # if j == -1: # ll.getwh(i).append(count) for i in range(len(dickey)): word = dickey[i] if word in ignorewords: continue if kl.getlength() == 0: wl = linklist.WebList() wl.initlist(count) kl.initlist(word, wl) if kl.getlength() > 0: i = kl.index(word) if i == -1: wl = linklist.WebList() wl.initlist(count) kl.append(word, wl) # print(word) if i != -1: j = kl.getwh(i).index(count) if j == -1: kl.getwh(i).append(count) return 1
注释掉的部分是全文分词
最后就是遍历链表,加入索引库
对14000多条url进行处理大概花费25个小时
建议放到服务器上运行,用nohup命令,可以在关闭远程连接后让程序继续运行。会自动生成nohup.out文件,报错输出结果什么的可以在里面看到。
四.源代码
https://github.com/zucc31701019/SearchIndex
五.一些坑
这些运行时间很长的程序一定要加异常处理!!!不然运行一半报错了又要重头开始...
连接数据库不要在还没用到的时候连,在用之前再连接。我在分词之前连了数据库,然后运行 20多个小时以后,链表处理完了...数据库链接失效报错...因为连接之后太长时间没有进行操作,数据库会断开连接。