专栏首页木子昭的博客<进击的虫师>如何让程序"懂很多"?

<进击的虫师>如何让程序"懂很多"?

最近在做一个有意思的小项目, 在一个聊天对话中, 你向电脑提出问题, 他会自动分词,然后根据关键字, 自动答复你 对所有的关键字做出解释, 工作量实在太大, 即使能解释, 数据库容量也不够 最后, 想到了实时爬虫...

如何分词?

目前比较好用的分词器 结巴(jieba)

爬哪里?

现成的百度百科

爬什么?

那要看用户问什么了, 爬虫最好是实时的, 这样就能根据用户的提问, 直接获取关键词数据

如何让程序变得更聪明(优化程序)?

每次爬完一个关键词后, 做一个本地备份, 既能避免百度策略临时变更带来的灾难, 也便于根据用户习惯, 优化程序

爬不到怎么办?

对于用户问到, 但百度百科未收录的关键词, 会自动记录到log日志里面,便于后期改进词库

实时爬取百度百科

import os
import sys
import requests
from lxml import etree
import re
import time

# 从本地获取数据
def getLocalData(keyword):
    # 获取/baikeInfo下的所有文件名
    print("尝试查询本地数据信息")
    fileNames = os.listdir('./baikeInfo/')
    # 查询本地是否存在缓存数据
    latestCreateTime = ''
    for fileName in fileNames:
        # 文件关键字
        fileName0 = fileName.split("_")[0]
        # 文件创建时间
        fileName1 = fileName.split("_")[1].split('.')[0]
        # 如果当前文件名与目的文件名一致的话
        if fileName0 == keyword:
            # 如果时间缓存变量为空, 则存储当前时间戳
            if latestCreateTime == '':
                latestCreateTime = fileName1
            # 如果时间缓存变量不为空, 则比较时间戳, 如果当前时间更晚, 则更新时间戳
            elif int(fileName1) > int(latestCreateTime):
                latestCreateTime = fileName1
    # 创建需要读取的文件名
    NeedFileName = ''
    result = ''
    # 如果时间戳为空, 则说明文件不存在
    if latestCreateTime == '':
        return "未收录本词条"
    else:
        NeedFileName = keyword+"_"+latestCreateTime+'.txt'
        NeedFileNamePath = './baikeInfo/'+NeedFileName
        with open(NeedFileNamePath, 'r') as f:
            result = f.read()

    return result

# 从网络获取数据
def getInfo(keyword):
    headers = {
        # 设置用户代理头(为狼披上羊皮)
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",
    }
    target_url = "https://baike.baidu.com/item/"+ str(keyword)
    result = ""

    try:
        # 尝试驱动爬虫获取实时数据
        try:
            data = requests.get(target_url, headers = headers)
            data_etree = etree.HTML(data.content)
            content_list = data_etree.xpath('//div[@class="lemma-summary"]/div[@class="para"]')
            # 如果不存在这个词条
            if len(content_list) == 0:
                return "未收录本词条"
            for content in content_list:
                # 递归抽取子节点数据
                result +=content.xpath('string(.)')
        # 如果无法获取响应数据, 则尝试读取本地数据, 做出响应
        except Exception as e:
            result = getLocalData(keyword)
            return result
    # 如果本地没有数据, 也无法从互联网获取, 则返回未收录词条
    except Exception as e:
        result = "未收录本词条"
        return result
    # 数据清洗, 移除类似[1][2]之类的标记字符
    result_list, num = [r for r in re.subn(r'\[\d{0,3}\]', '', result)]
    # 数据清洗, 移除多余的空格字符
    result = ''
    for r in result_list:
        result += str(r).strip()
    return result

# 保存数据, 并通过log记录未收录的的词条
def saveData(fileName, info):
    # 记录用户未查找到的词条, 结束函数
    if info == "未收录本词条":
        if os.path.exists("./log/"):
            pass
        else:
            os.makedirs("./log/")
        with open("./log/log.txt", "a") as f:
            newlog = time.strftime("%Y年%m月%d日%H时%M分%S秒")+"  "+"未找到关键词:"+fileName+"\n"
            f.write(newlog)
            return

    # 尝试创建baikeInfo文件夹    
    if os.path.exists("./baikeInfo/"):
        pass
    else:
        os.makedirs("./baikeInfo/")
    # 获取当前的年月日时分秒
    # 将数据保存到baikeInfo中, fileName.txt
    file_path = "./baikeInfo/" + fileName +"_"+ time.strftime("%Y%m%d%H%M%S") +'.txt'
    # 存储数据
    with open(file_path, "w+") as f:
        f.write(info)

# 程序入口
def getInput():
    wd = ''
    try: 
        wd = sys.argv[1]
    except:
        wd = "人工智能"
    result = getInfo(wd)
    if len(result)>0:
        saveData(wd,result)
    print(result)
    if result == "未收录本词条":
        return False
    return result

def main():
    result = getInput()
    return result

if __name__ == '__main__':
    main()

为程序加入彩蛋?

彩蛋很容易加, 可以先写好一个字典, 里面放入一些关键词, 并放入彩蛋, 当分词器得到用户关键词时,先查字典, 如果能匹配到彩蛋, 就在最终的结果里面加入彩蛋信息,

本篇文章彩蛋:

文章点赞过50, 作者会上线程序的彩蛋版本,并将彩蛋链接更新到文章底部!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python交互数据库(Mysql | Mongodb | Redis)Mysql操作数据库Mongdbredis

    数据库 Mysql Mysql MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,后来被Sun公司收购,Sun公司后来又被Oracle公司...

    zhaoolee
  • Windows免费好用软件推荐(第二期)

    前两天推送了一期Windows装机免费好用软件推荐 效果非常好, 但上一次的篇幅较短, 没有把好用的软件推荐完, 所以这次做个第二期

    zhaoolee
  • <进击的虫师>舆情监测之获取数据

    舆情监测是对互联网上公众的言论和观点进行监视和预测的行为.监测技术大多是基于爬虫的, 如果我们把相关热点事件的关键词, 用搜索引擎进行搜索, 并将结果保存到本...

    zhaoolee
  • python列表与元组的用法

    7.列表生成式   #[i*i for i in range(10)]       [i*i for i in range(10) if i>5]

    py3study
  • 研报复制(四):基于Logistic回归的大小盘轮动

    一种是从技术面出发,基于量价指标建立模型,典型的比如上篇复制的基于相对强弱指标的大小盘轮动策略。

    量化小白
  • Leetcode: Reverse Bits

    题目: Reverse bits of a given 32 bits unsigned integer.

    卡尔曼和玻尔兹曼谁曼
  • 2015.11.30 HTML5真题练习

    HTML5学堂:每天一道题,强壮程序员!今日主要涉及昨日题目的解答,以及一道涉及函数的形参实参、arguments对象的题目 HTML5真题【2015.11.2...

    HTML5学堂
  • Python版组合数计算方法优化思路和源码

    总体说明:本文的优化思路并不局限于Python,但C、C++、C#、Java等语言无法使用内置类型直接表示大整数,需要通过数组等特定形式并自己实现大整数乘除法才...

    Python小屋屋主
  • AttributeError: 'list' object has no attribute 'keys'

    hankleo
  • 【PAT乙级】旧键盘打字

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    喜欢ctrl的cxk

扫码关注云+社区

领取腾讯云代金券