Bootstrap

【LangChain系列】实战案例2:通过URL加载网页内容 - LangChain对爬虫功能的封装

Web检索是AI大模型应用的一个热门应用方向。其涉及的主要步骤如下:

在这里插入图片描述

参考:python.langchain.com/docs/use_ca…

(1)用户提问,联网检索 (2)通过URLs记载网页HTML数据 (3)加载到的数据通过转换,获取关注的内容,形成文本 (4)对文本进行分块、向量化、存储 (5)调用大模型进行总结、答案生成

其实就是RAG的基本流程,只不过知识库不再局限在你自己的知识库,而是利用在线检索,搜罗互联网上的数据作为相关知识。

搜罗数据的过程,可以有两种方法,一种是调用检索的API,例如GoogleSearch的API,直接获取检索结果。另一种方法,就是靠爬虫,将网页数据抓取下来,存入向量数据库使用。

本文我们探讨一下爬虫的相关的使用方法。

0. LangChain接口

LangChain中,将爬虫功能分成了两个模块,LoadingTransforming

  • Loading模块的功能是将 URL 加载转换成 HTML 内容。封装的类包括:AsyncHtmlLoader类、AsyncChromiumLoader类等。
  • Transforming模块的功能是将 HMTL 内容转换成需要的文本。封装的类包括:HTML2Text类、Beautiful Soup类等。

0.1 Loading模块简介

  • AsyncHtmlLoader: 使用aiohttp库生成异步HTTP请求,适用于更简单、轻量级的抓取。
  • AsyncChromiumLoader:使用Playwright启动Chromium实例,该实例可以处理JavaScript渲染和更复杂的web交互。Chromium是Playwright支持的浏览器之一,Playwright是一个用于控制浏览器自动化的库。

0.2 Transforming模块简介

  • HTML2Text:将HTML内容直接转换为纯文本,而无需任何特定的标记操作。它最适合于目标是提取人类可读文本而不需要操作特定HTML元素的场景。
  • Beautiful Soup:对HTML内容提供了更细粒度的控制,支持特定的标记提取、删除和内容清理。它适用于需要提取特定信息并根据需要清理HTML内容的情况。

1. 快速上手 - Quick Start

1.1 Demo代码

python
复制代码

urls = ["https://mp.weixin.qq.com/s/Zklc3p5uosXZ7XMHD1k2QA"]

from langchain_community.document_loaders import AsyncChromiumLoader
from langchain_community.document_transformers import BeautifulSoupTransformer

# Load HTML
loader = AsyncChromiumLoader(urls)
html = loader.load()

print("============= html =====================")
print(html)

# Transform
bs_transformer = BeautifulSoupTransformer()
docs_transformed = bs_transformer.transform_documents(html, tags_to_extract=["span"])

print("================= doc_transformed ===============")
print(docs_transformed)

1.2 代码解释

(1)该程序使用了 AsyncChromiumLoader 类来加载URL为HTML内容。

注意:AsyncChromiumLoader 接收的参数是一个URL数组,这意味着它可以同时加载多个URL。

(2)使用了 BeautifulSoupTransformer 类作为transform来将HTML内容转换成文本内容

注意:transform_documents 函数中的 tags_to_extract 参数,指定了将 HTML 中的什么 tag 内的内容提取成文本。

1.3 运行效果

  • URL转HTML内容结果如下:

在这里插入图片描述 抓出来的其实是HTML脚本语言,程序代码。并不是我们想要的文本信息。所以后面有个Transform步骤。

  • Transform步骤后的结果:

在这里插入图片描述 可以看到经过 Transform 步骤后,出现了我们需要的文本信息。

原网页内容如下:经过对比,发现提取的文本丢失了很多内容。主要的原因是tags_to_extract 参数设置的问题。

在这里插入图片描述

1.4 效果改善

HTML脚本语言的常用的文本标签 tags 大体有 ,

,

  • ,
    和 :
    • :标题标签,用于定义标题的级别,

      是最高级别的标题,依次递减。

    • :段落标签,用于定义段落。

    • :链接标签,用于创建超链接,通过href属性指定链接目标。
    • :内联容器标签,用于包裹一小段文本或行内元素。
    • :块级容器标签,用于组合和布局其他元素。
    • :强调文本标签,使文本加粗显示。
    • :强调文本标签,使文本以斜体显示。

    • :换行标签,用于插入一个换行符。

    要改善上面的提取结果,使其能提取出更多的文本,我们可以修改提取的 tags 参数,如下,提取出,

    的内容:

    clike
    复制代码
    docs_transformed = bs_transformer.transform_documents(html, tags_to_extract=["span", "code", "p"])
    

    修改后运行效果如下:已经将里面的文字和代码全部提取出来了(虽然还有些特殊符号,不过没关系,后面可以再过滤一层去掉):

    在这里插入图片描述

    1.5 怎么确认 tags_to_extract 的参数

    那上面我是怎么确认要提取 "span", "code", "p" 这三个tag内的文本的呢?

    (1)打开你要爬取的网页,按 F12 打开网页调试工具

    (2)找到 “元素” 选项卡,然后点击左上角的这个图标(如图)

    在这里插入图片描述 (3)将鼠标悬浮在你想提取的文字上面,它就会自动展示当前文字所在的标签 tag 是什么。如下面图片:

    在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 (4)将这些tag全部填到参数里,就OK了。

    2. 高级方法 - 使用大模型的Function Calling提取所需文本

    该方法是在以上方法的基础上,在得到文本后,再利用大模型,从文本中二次提取出所关注的文本内容。

    这种方法的好处在于,对于网页内容和结构变化时,我们不需要再去频繁的调整提取tag等参数,而是最后利用大模型统一提取关心内容即可。

    2.1 Demo代码

    clike
    复制代码
    def scraping_with_extraction():
        from langchain_openai import ChatOpenAI
    
        llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-0613")
        
        from langchain.chains import create_extraction_chain
    
        schema = {
            "properties": {
                "article_title": {"type": "string"},
                "article_content": {"type": "string"},
                "article_example_python_code": {"type": "string"},
            },
            "required": ["article_title", "article_content", "article_example_python_code"],
        }
    
    
        def extract(content: str, schema: dict):
            return create_extraction_chain(schema=schema, llm=llm).run(content)
        
        import pprint
    
        from langchain.text_splitter import RecursiveCharacterTextSplitter
    
    
        def scrape_with_playwright(urls, schema):
            from langchain_community.document_loaders import AsyncChromiumLoader
            from langchain_community.document_transformers import BeautifulSoupTransformer
            loader = AsyncChromiumLoader(urls)
            docs = loader.load()
            bs_transformer = BeautifulSoupTransformer()
            docs_transformed = bs_transformer.transform_documents(
                docs, tags_to_extract=["span", "code", "p"]
            )
            print("Extracting content with LLM")
    
            # Grab the first 1000 tokens of the site
            splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
                chunk_size=1000, chunk_overlap=0
            )
            splits = splitter.split_documents(docs_transformed)
    
            # Process the first split
            extracted_content = extract(schema=schema, content=splits[0].page_content)
            pprint.pprint(extracted_content)
            return extracted_content
    
        extracted_content = scrape_with_playwright(urls, schema=schema)
        
    scraping_with_extraction()
    

    2.2 代码解释

    (1)schema定义

    定义一个模式来指定要提取的数据类型。在这里,key的名称很重要,因为这是告诉LLM我们想要什么样的信息。所以,尽可能详细。

    (2)正常走上面的流程,获取网页数据 docs_transformed

    (3)代码中还做了 split,将全部文本分块了,可能是为了避免超出 LLM 的Token长度限制?

    (4)最重要、最灵魂的几句,将文本内容,和模式传入 create_extraction_chain 来获取输出:

    clike
    复制代码
    def extract(content: str, schema: dict):
           return create_extraction_chain(schema=schema, llm=llm).run(content)
    extracted_content = extract(schema=schema, content=splits[0].page_content)
    

    2.3 运行效果

    在这里插入图片描述

    输出的结果不是很好。

    2.4 create_extraction_chain 源码解析

    该函数源码如下: 在这里插入图片描述 其做的事儿,也比较简单,就是通过 _get_extraction_function 函数将上面我们定义的 schema 转换成了 function calling 中的 function 的结构。

    在这里插入图片描述 然后创建了一个 LLMChain 链。

    看下它内置的Prompt,让大模型提取出在 information_extraction 函数中定义的 properties相关信息 :

    python
    复制代码
    _EXTRACTION_TEMPLATE = """Extract and save the relevant entities mentioned \
    in the following passage together with their properties.
    
    Only extract the properties mentioned in the 'information_extraction' function.
    
    If a property is not present and is not required in the function parameters, do not include it in the output.
    
    Passage:
    {input}
    """
    

    很明显,这个 Prompt 比较简单,要想大模型提取的结果好,information_extraction 函数中定义的 properties必须要尽可能详细。怎么提供详细的说明呢?看下我之前的Function calling的文章,可以看到参数下面可以加一个描述来详细描述该参数的含义。

    image.png

    仿照这个方法,我们可以优化schema:

    python
    复制代码
    schema = {
        "properties": {
            "文章标题": {"type": "string", "description": "文章题目"},
            "文章正文全部内容": {"type": "string", "description": "文章的正文内容,不要包含Python代码,只输出文字"},
            "文章中的示例Python代码": {"type": "string", "description": "文章中的Python代码,只输出代码,用markdonw格式输出,可能存在多段代码,多段代码之间分开"},
        },
        "required": ["文章标题", "文章正文全部内容", "文章中的示例Python代码"],
    }
    

    还有一种方法,create_extraction_chain 函数的参数接收一个额外的 Prompt,我们也可以通过此参数来调优提取结果。

    然而最终结果并没有多少改善… 待继续研究怎么优化。

    该方法有点过于依赖大模型的能力,并且会大量消耗Token,目前还没看到有实际的落地效果,处于探索阶段。

    如何系统的去学习大模型LLM ?

    作为一名热心肠的互联网老兵,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。

    但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的 AI大模型资料 包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来

    😝有需要的小伙伴,可以V扫描下方二维码免费领取🆓

    在这里插入图片描述

    一、全套AGI大模型学习路线

    AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

    img

    二、640套AI大模型报告合集

    这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

    img

    三、AI大模型经典PDF籍

    随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

    img

    在这里插入图片描述

    四、AI大模型商业化落地方案

    img

    阶段1:AI大模型时代的基础理解

    • 目标:了解AI大模型的基本概念、发展历程和核心原理。
    • 内容
      • L1.1 人工智能简述与大模型起源
      • L1.2 大模型与通用人工智能
      • L1.3 GPT模型的发展历程
      • L1.4 模型工程
        - L1.4.1 知识大模型
        - L1.4.2 生产大模型
        - L1.4.3 模型工程方法论
        - L1.4.4 模型工程实践
      • L1.5 GPT应用案例

    阶段2:AI大模型API应用开发工程

    • 目标:掌握AI大模型API的使用和开发,以及相关的编程技能。
    • 内容
      • L2.1 API接口
        - L2.1.1 OpenAI API接口
        - L2.1.2 Python接口接入
        - L2.1.3 BOT工具类框架
        - L2.1.4 代码示例
      • L2.2 Prompt框架
        - L2.2.1 什么是Prompt
        - L2.2.2 Prompt框架应用现状
        - L2.2.3 基于GPTAS的Prompt框架
        - L2.2.4 Prompt框架与Thought
        - L2.2.5 Prompt框架与提示词
      • L2.3 流水线工程
        - L2.3.1 流水线工程的概念
        - L2.3.2 流水线工程的优点
        - L2.3.3 流水线工程的应用
      • L2.4 总结与展望

    阶段3:AI大模型应用架构实践

    • 目标:深入理解AI大模型的应用架构,并能够进行私有化部署。
    • 内容
      • L3.1 Agent模型框架
        - L3.1.1 Agent模型框架的设计理念
        - L3.1.2 Agent模型框架的核心组件
        - L3.1.3 Agent模型框架的实现细节
      • L3.2 MetaGPT
        - L3.2.1 MetaGPT的基本概念
        - L3.2.2 MetaGPT的工作原理
        - L3.2.3 MetaGPT的应用场景
      • L3.3 ChatGLM
        - L3.3.1 ChatGLM的特点
        - L3.3.2 ChatGLM的开发环境
        - L3.3.3 ChatGLM的使用示例
      • L3.4 LLAMA
        - L3.4.1 LLAMA的特点
        - L3.4.2 LLAMA的开发环境
        - L3.4.3 LLAMA的使用示例
      • L3.5 其他大模型介绍

    阶段4:AI大模型私有化部署

    • 目标:掌握多种AI大模型的私有化部署,包括多模态和特定领域模型。
    • 内容
      • L4.1 模型私有化部署概述
      • L4.2 模型私有化部署的关键技术
      • L4.3 模型私有化部署的实施步骤
      • L4.4 模型私有化部署的应用场景

    学习计划:

    • 阶段1:1-2个月,建立AI大模型的基础知识体系。
    • 阶段2:2-3个月,专注于API应用开发能力的提升。
    • 阶段3:3-4个月,深入实践AI大模型的应用架构和私有化部署。
    • 阶段4:4-5个月,专注于高级模型的应用和部署。
    这份完整版的大模型 LLM 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

    😝有需要的小伙伴,可以Vx扫描下方二维码免费领取🆓

    在这里插入图片描述

;