美文网首页我爱编程
一个简易版的智能搜索系统(下)

一个简易版的智能搜索系统(下)

作者: dc343001cf91 | 来源:发表于2018-07-26 14:14 被阅读35次

    3 用python实现在线搜索功能

            继上篇一个简易版的智能搜索系统(上)
    这份代码是基于php调用python写的用户输入的参数传给php然后再传给python。
    主要是通过爬虫抓取阿里云服务器上的分词模型的分词结果,然后再去抓取对应分词的近义词和同义词来实现智能搜索。

    # 导入相关包
    # -*- coding: utf-8 -*-                 # 设定utf-8编码
    import os                               # 修改工作路径
    import warnings                         # 屏蔽警告
    import requests                         # request库爬虫
    import re                               # 正则表达式库
    import pandas as pd                     # dataframe处理
    from urllib import parse                # url编码
    from urllib.parse import quote
    from urllib.parse import unquote
    import numpy as np                      # 数据处理
    import string                           # 编码转换
    from bs4 import BeautifulSoup           # 网页解析
    import sys                              # 输入转义
    warnings.filterwarnings("ignore")       # 无视警告
    os.chdir("D:/WWW/ElasticSearch")        # 修改工作路径
    

    3.1 定义分词程序

    这里由于没空搭建分词环境就直接调用了某在线分词系统

    def gethtmltext(word):
        # 抓取分词结果
        try: # 尝试调取 120.26.6.172的分词结果,如果失败了换个ip调取
            url = 'http://120.26.6.172/get.php?source=' + word + '&param1=0.25&param2=0'
            r = requests.get(url, headers={"user-agent": "Mozilla/5.0"})
        except IOError:
            url = 'http://114.67.84.223/get.php?source=' + word + '&param1=0.25&param2=0'
            r = requests.get(url, headers={"user-agent": "Mozilla/5.0"})
        # html文本处理
        keyword = re.split("\r\n", r.text)
        # 删除无效词语,这些都是系统关键词 不能使用
        jingyonglist = ["con", " ", "prn", "aux", "nul", "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8",
                        "com9", "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9"]
        for jingyong in jingyonglist:
            while keyword.count(jingyong) > 0:
                keyword.remove(jingyong)
        # 删除多余的空白文字
        while '' in keyword:
            keyword.remove('')
        return np.array(keyword)
    

    3.2 定义同义词获取程序

    def getsynonym(word):
        file = r'./search/' + word + ".txt"
        # 第一步尝试从本地读取
        try:
            openfile = open(file, encoding='utf-8')
            getdata = np.loadtxt(openfile, dtype= np.str)
            openfile.close()
        # 如果本地不存在的话会报错就去网页上抓取近义词
        except IOError:
            url = 'http://www.cibo.cn/search.php?dictkeyword=' + word
            newurl = quote(url, safe=string.printable)
            r = requests.get(newurl)
            r.encoding = 'gbk'
            soup = BeautifulSoup(r.text, "html.parser")
            adm = [str(word)]
            for i in soup.find_all("span"):
                for j in i.select('a'):
                    # 词语都存在网页链接上了
                    hrefword = unquote(j.get("href"), encoding="GBK")[42:].lower()
                    hrefword = re.sub(r'pl\.|vi\.|n\.|v\.|vb\.|sb\.|\'s|pron\.|adj\.|vt\.|adv\.|的复数|ad\.|a\.|phr\.|-|\(|\)|\\ ', "",hrefword)
                    hrefword = re.sub(r'&|/|\.',"+", hrefword).split('+')
                    adm.extend(hrefword)
            # 删除空白字符
            while '' in adm:
                adm.remove('')
            # 在不修改顺序的情况下去重
            adm_fuzhu = adm
            adm_fuzhu = list(set(adm_fuzhu))
            adm_fuzhu.sort(key=adm.index)
            # 这个词语可能没有被收录,所以这里需要个判断语句,不然会报错
            if len(adm_fuzhu) > 0:
                pd.DataFrame(adm_fuzhu[:5]).to_csv(file, sep=',', header=True, index=False)
            getdata = np.array(adm_fuzhu[:5])
        return getdata
    

    3.3 主模型

    wordinput = parse.unquote(sys.argv[1]).encode("utf-8").decode("utf-8")  # 用户输入请求
    newword = gethtmltext(wordinput)                                        # 抓取分词结果
    data = pd.DataFrame(columns=['id', 'TF_IDF', 'name'])                   # 设定结果dataframe
    try:
        for x in newword:                                                   
            synonym = getsynonym(x)[1:]                                     # 抓取该词语的近义词
            k = 0
            for keyword in synonym:
                k = k + 1
                file = r'./wordscore/' + str(keyword) + ".txt"
                try:
                    f = open(file, encoding='utf-8')
                    df = pd.read_table(f, sep='\t')
                    df['TF_IDF'] = np.exp(df['TF_IDF']) / (k * k * k)       # 读取该词语的所有近义词的数据并加权值
                    df['name'] = keyword
                    data = data.append(df)
                    f.close()
                except IOError:
                    data = data
        data = data.dropna()                                                # 删除缺失数据
        data = data.pivot_table(                                            # 做列联表
            index=["id"],  # 行索引(可以使多个类别变量)
            columns=["name"],  # 列索引(可以使多个类别变量)
            values=["TF_IDF"]  # 值(一般是度量指标)
        )
        data = data + 1                                                     # 防止结果太小就整体加1
        data[np.isnan(data)] = 0.5                                          # 如果不存在这个词给0.5分,负向得分
        newdata = np.prod(data, axis=1)                                     # 所有词语得分的总乘积
        data = pd.DataFrame(columns=['ID', "TF_IDF"])                       
        data['ID'] = newdata.index                                          # 读取index 就是文章id
        data['TF_IDF'] = newdata.values                                     # 读取具体得分
        maxnum = max(data['TF_IDF']) * 0.0001                               # 筛选得分较高的文章
        data = data[data['TF_IDF'] > maxnum]                              
        # 将前1000条结果打印出来传输给浏览器
        score = data['TF_IDF'].groupby(data['ID']).sum().reset_index().sort_values(by='TF_IDF', ascending=False)[:1000]
    except:
        score = pd.DataFrame(columns=['ID', "TF_IDF"])
    print(score.to_json(orient='values')) # 输出传给网页
    

    源代码请移步Github
    https://github.com/wujialin123/hzzlw_Standardsearch

    相关文章

      网友评论

        本文标题:一个简易版的智能搜索系统(下)

        本文链接:https://www.haomeiwen.com/subject/qylbmftx.html