15天学会AI应用开发(十二)从PDF、WORD、网页构建RAG

上一篇文章介绍了如何从TXT文件读取文本信息,可是日常办公很少使用纯文本的TXT格式,而采用专业的PDF格式或者WORD格式,有时还需要通过网页抓取知识。

接下来就介绍如何从PDF、WORD、HTML等文件中读取文本内容。

一、从PDF文件读取文本

PDF是一种常用的文档格式,常用于只读的通知文件,或者电子版书籍。

Python提供了多种三方库用来解析PDF文件,其中pdfplumber较常用。使用Python代码读取PDF文件内容前,要先在命令行执行下面的pip安装命令:

复制代码
pip install pdfplumber

然后调用pdfplumber的open方法打开指定文件,即可逐页读取文档内容并拼接为文本字符串。读取PDF文件的代码例子如下所示:

复制代码
import pdfplumber

def read_from_pdf(file_path):
    full_text = ""
    with pdfplumber.open(file_path) as pdf:
        for page in pdf.pages:
            page_text = page.extract_text()
            if page_text:
                full_text += page_text + "\n"
    return full_text

二、从WORD文件读取文本

DOCX格式的WORD文件也是常用的文档格式,常用于可读可写的办公文档编写。

Python提供了多种三方库用来解析DOCX文件,其中python-docx较常用。使用Python代码读取DOCX文件内容前,要先在命令行执行下面的pip安装命令:

复制代码
pip install python-docx

然后通过python-docx的Document工具打开指定文件,即可逐页读取文档内容并拼接为文本字符串。读取DOCX文件的代码例子如下所示:

复制代码
from docx import Document

def read_from_word(file_path):
    doc = Document(file_path)
    content = []
    # 读取段落
    for para in doc.paragraphs:
        t = para.text.strip()
        if t:
            content.append(t)
    # 读取表格内容
    for table in doc.tables:
        for row in table.rows:
            for cell in row.cells:
                t = cell.text.strip()
                if t:
                    content.append(t)
    return "\n".join(content)

三、爬取网页读取文本

除了以PDF和DOCX为代表的本地文档之外,开发者还经常在网络上爬取网页资料作为在线知识库。

Python提供了多种三方库用来解析HTML网页,其中trafilatura较常用。使用Python代码读取HTML网页内容前,要先在命令行执行下面的pip安装命令:

复制代码
pip install trafilatura

接着调用requests库的get方法从指定网址获取应答信息,然后通过trafilatura的extract方法从应答信息中解析文本。读取网页内容的代码例子如下所示:

复制代码
import requests
import trafilatura

def get_webpage_text(url):
    # 请求网页
    headers = {
        "User-Agent":"Mozilla/5.0"
    }
    resp = requests.get(url, headers=headers, timeout=10)
    resp.encoding = "utf-8"

    # 自动提取纯净正文(剔除广告导航)
    raw = trafilatura.extract(resp.text)
    return raw if raw else "提取失败"

四、打造基于网页的在线知识库RAG

接下来结合之前介绍的BGE-small与FAISS,通过解析网页实现在线RAG的检索功能。

在编写Python代码前,要先在命令行执行下面的pip安装命令:

复制代码
pip install faiss-cpu sentence

然后编写下面的Python检索测试代码,与之前教程的代码相比,仅仅把knowledge数组改成从网页获取并分块:

复制代码
from sentence_transformers import SentenceTransformer
import faiss
import numpy as np

import requests
import trafilatura

# 加载一整段文本
def get_webpage_text(url):
    # 请求网页
    headers = {
        "User-Agent":"Mozilla/5.0"
    }
    resp = requests.get(url, headers=headers, timeout=10)
    resp.encoding = "utf-8"

    # 自动提取纯净正文(剔除广告导航)
    raw = trafilatura.extract(resp.text)
    return raw if raw else "提取失败"

# 读取一整段文本,并把换行符换成句号
url = "https://www.nhsa.gov.cn/art/2025/12/25/art_14_19130.html"
raw_text = get_webpage_text(url)

# 自动把一段文字切成多段
def split_text(text, max_len=50):
    sentences = text.split("。")  # 按句号分割
    chunks = []
    current = ""

    for sen in sentences:
        sen = sen.strip()
        if not sen:
            continue
        # 加回去句号,让语义完整
        sen += "。"

        if len(current) <= max_len:
            current += sen
        else:
            if current:
                chunks.append(current.strip())
            current = sen
    if current:
        chunks.append(current.strip())
    return chunks

# 自动分块
knowledge = split_text(raw_text)

# 加载本地已有的模型
embed_model = SentenceTransformer("./bge-small-zh-v1.5", device="cpu")

# 生成向量(把知识库向量化)
vectors = embed_model.encode(knowledge)

# 构建 FAISS 索引
index = faiss.IndexFlatL2(vectors.shape[1])
index.add(np.array(vectors).astype("float32"))

# RAG 检索
def rag(question):
    print("\n 问题:" + question)
    # 把问题向量化
    q_vec = embed_model.encode([question])
    # 从 FAISS 检索对应的知识
    D, I = index.search(np.array(q_vec).astype("float32"), 1)
    best = knowledge[I[0][0]]
    answer = best.split(":")[-1]
    print(" 答案:" + answer)
    print("-" * 50)

# 运行
if __name__ == "__main__":
    print("=== 本地智能 RAG 系统:问什么答什么 ===")
    while True:
        q = input("\n请输入问题(q退出):")
        if q.lower() == "q":
            break
        rag(q)

运行上面的Python代码,根据提示先后输入三个问题"GS1码是什么?"、"GS1编码是什么?"、"GS1码有什么作用?",输出日志结果如下:

复制代码
=== 本地智能 RAG 系统:问什么答什么 ===

请输入问题(q退出):GS1码是什么?

 问题:GS1码是什么?
 答案:国际 GS1 编码体系。GS1码在药品追溯体系中的应用。在药品追溯中,GS1码通常由数字、字母和符号组成,常见载体为二维码格式。
--------------------------------------------------

请输入问题(q退出):GS1编码是什么?

 问题:GS1编码是什么?
 答案:最后一种就是国际 GS1 编码(Global Standard 1,即全球统一编码标识系统)GS1编码载体为二维码,多见于进口药品。
--------------------------------------------------

请输入问题(q退出):GS1码有什么作用?

 问题:GS1码有什么作用?
 答案:采集GS1码的准备工作。在我国医药市场上,吉利德、安进、辉瑞、渤健、强生等公司的部分或全部药品采用了GS1码作为药品追溯码,大部分医疗器械也都使用GS1码制进行追溯。

由日志信息发现,在线RAG对几个问题的回答基本正确,说明结合BGE-small与FAISS成功实现了对网页的在线检索功能。

本系列的AI应用开发文章目录为《15天学会AI应用开发全目录(零基础小白,零Token消耗)》。