zoukankan      html  css  js  c++  java
  • python 爬虫应用——校园网搜索引擎(crawler application——Campus web search engine part-two)(下)

    来自 《Python项目案例开发从入门到实战》(清华大学出版社  郑秋生 夏敏捷主编)中爬虫应用——校园网搜索引擎

    这一部分的下半节代码内容主要讲的是 网页排名和搜索模块

    网页排名采用TF(Term Frequency)/IDF(Inverse Document Frequency)统计。
    其中TF意思是词频,表示词条t在文档d中出现的频率。IDF意思是逆文本频率指数,计算公式是 idf = log(N/df),其中N是文档总数,df是包含词条t的文档数量,当有TF(词频)和IDF(逆文档频率)后,将这两个词相乘,就能得到一个词的TF-IDF的值。某个词在文章中的TF-IDF越大,那么一般而言这个词在这篇文章的重要性会越高,所以通过计算文章中各个词的TF-IDF,由大到小排序,排在最前面的几个词,就是该文章的关键词。

    注意: 要想这部分的代码运行成功,一定要先看我的博客中前两章的内容 《 python 爬虫应用——校园网搜索引擎(crawler application——Campus web search engine part-one)(上)》 然后生成 viewsdu.db 数据库才可以运行成功。

    import sqlite3
    import jieba
    import urllib
    import lxml
    import math
    from urllib import request
    from collections import deque
    from bs4 import BeautifulSoup
    
    # 链接已经创建好的数据库(这个在上一篇博客中已经教了如何创建)
    conn = sqlite3.connect("viewsdu.db")
    # 创建游标对象
    c = conn.cursor()
    # 计算doc浏览器中的总函数
    c.execute('select count (*) from doc')
    # fetchall返回的是[(82,)],即文档的条目总数,为了计算IDF中的文档总数
    N = 1 + c.fetchall()[0][0]
    # target = input('请输入搜索词: ')
    target = '校园'
    # 将搜索内容粉刺
    seggen = jieba.cut_for_search(target)
    # 字典,用于存储“文档号: 文档得分”,文档得分越高,表示这个词在这个文档中的重要程度越高
    score = {}
    for word in seggen:
        print('得到查询词', word)
        # 创建字典,返回的是word在每个文档中出现的次数,即TF词频的结果
        tf = {}
        c.execute('select list from word where term=?', (word,))
        result = c.fetchall()
        if len(result) > 0:
            # 得到当 term=word 时的 list 的值,这里返回的是字符串,如'3 3 4 4 5 5 58 58'
            doclist = result[0][0]
            # 根据空格切割字符串,返回列表如 ['3', '3', '4', '4', '5', '5', '58', '58',]
            doclist = doclist.split(' ')
            # 把字符串转换为整型,返回的是 [3, 3, 4, 4, 5, 5, 58, 58]
            doclist = [int(x) for x in doclist]
            # set是集合,python中的集合主要用来去重,set(doclist)后结果就是 {3, 4, 5, 58},最终df再得到长度4
            df = len(set(doclist))
            # 逆文本频率指数的计算公式,IDF=log(文档总数/包含词条的文档数量)
            idf = math.log(N/df)
            # 计算词频TF,即在某文档中出现的次数,返回的结果是{3:2, 4:2, 5:2, 58:2}
            for num in doclist:
                if num in tf:
                    tf[num] = tf[num] + 1
                else:
                    tf[num] = 1
            # !!!注意,当你看懂了这个是用字典表示列表中每个字出现的次数的时候,你可以用下面这一行代码替换上面的5行代码,效果一样
            # tf = {i: doclist.count(i) for i in doclist}
    
            # TF统计结束,现在开始计算score=TF∗IDF
            for num in tf:
                if num in score:
                    # 如果该num文档已经有分数了,则累加
                    score[num] = score[num] + tf[num]*idf
                else:
                    score[num] = tf[num]*idf
    # 对score字典按字典的值排序
    sortedlist = sorted(score.items(), key=lambda d: d[1], reverse=True)
    print('得分列表', sortedlist)
    
    cnt = 0
    for num, docscore in sortedlist:
        cnt = cnt + 1
        # 根据num的值在doc浏览器中找到相对应的链接(网址)
        c.execute('select link from doc where id=?', (num,))
        # 得到具体链接的字符串
        url = c.fetchall()[0][0]
        # 输出网址和对应得分
        print(url, '得分: ', docscore)
        try:
            # 打开网页
            response = request.urlopen(url)
            # 可以输出网页内容
            content = response.read().decode('utf-8')
        except:
            print('oops...读取网页出错')
            continue
        # 解析网页输出标题
        soup = BeautifulSoup(content, 'lxml')
        # 得到网页标题
        title = soup.title
        if title is None:
            print('No title')
        else:
            # 
            title = title.text
            print(title)
        # 超过20条则结束,即输出前20条
        if cnt > 20:
            break
    if cnt == 0:
        print('无搜索结果')
    
    pass

    结果:

  • 相关阅读:
    异步任务----django-celery
    signal函数
    shell脚本字符显示颜色
    echo输出到文件
    windows下opencv安装
    模板
    下载vs地址
    关联容器 map
    构造函数初始化列表
    assert() fflush()
  • 原文地址:https://www.cnblogs.com/ttweixiao-IT-program/p/13332311.html
Copyright © 2011-2022 走看看