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

3203841-ce833c5b75e16d4d.png
聊聊?

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

如何分词?

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

3203841-e836ae1c82fcc3ee.gif
今天早上吃了葱油饼和豆腐脑

爬哪里?

现成的百度百科


3203841-89e4d04b61358605.png
百度百科

爬什么?

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


3203841-f5c3afffd206461b.gif
效果演示

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

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


3203841-29b4ec69c2bfbeb2.png
本地数据

爬不到怎么办?

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


3203841-542b43f44d51d7ac.png
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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值