在本指南中,您将学到:
- 为什么网页抓取是用真实世界数据丰富 LLM 的一个绝佳方法
- 在 LangChain 工作流中使用抓取数据的好处和挑战
- 如何通过分步教程构建一个完整的 LangChain 网页抓取集成
让我们开始吧!
使用网页抓取为您的 LLM 应用程序赋能
网页抓取指从网页检索数据。然后可以将这些数据用于驱动 RAG(Retrieval-Augmented Generation)应用以及利用 LLM(大型语言模型)。
RAG 应用需要访问实时的、特定领域的或庞大的数据集,这些数据可能无法通过静态数据库获得。通过从各种网络来源(例如文章、产品列表或社交媒体)中提取结构化和非结构化数据,网页抓取弥补了这种数据缺口。
欲了解更多信息,请查看我们关于收集 LLM 训练数据的文章。
在 LangChain 中使用抓取数据的好处和挑战
LangChain 是一个构建 AI 驱动工作流的强大框架,能够与多种数据源无缝集成 LLM。其优势在于结合 LLM 和实时、特定领域知识来进行数据分析、摘要和问答。然而,获取高质量数据始终是一个难题。
网页抓取可以帮助解决这个难题,但它也带来了一些挑战,包括反机器人机制、CAPTCHA 以及动态网站。此外,维护合规且高效的抓取工具既耗时又较为复杂。想了解更多,请阅读我们关于反抓取措施的指南。
这些障碍会减缓依赖实时数据的 AI 应用的开发进程。解决方案?Bright Data 的 Web Scraper API——为数百个网站提供现成的抓取端点。
通过 IP 轮换、CAPTCHA 解决以及 JavaScript 渲染等高级功能,Bright Data 能够无缝自动化数据提取。这样可以确保可靠、高效且无忧的数据收集,并可通过简单的 API 调用完成。
Bright Data 助力的 LangChain 网页抓取:分步教程
在本节中,您将学习如何构建一个 LangChain 网页抓取脚本。目标是使用 Bright Data Web Scraper API 从 CNN 文章获取内容,并通过 LangChain 发送到 OpenAI 进行摘要。
我们将使用以下的 CNN 文章作为目标:
我们构建的示例是一个简单的示范起点,但可以轻松地通过 LangChain 扩展额外功能和分析。例如,您甚至可以基于搜索引擎结果页面(SERP)数据创建一个RAG 聊天机器人。
按照以下步骤开始吧!
先决条件
完成本教程,您需要:
- 在机器上安装了 Python 3+
- 一个 OpenAI API Key
- 一个 Bright Data 账号
如果缺少以上任意一个条件,不必担心。我们会指导您整个流程,包括安装 Python 以及如何获取 OpenAI 和 Bright Data 的凭证。
步骤 #1:项目搭建
首先,检查您的机器上是否已经安装了 Python 3。如果没有,请从此处下载并安装。
在终端中运行以下命令来创建一个项目文件夹:
mkdir langchain_scraping
langchain_scrping
将会包含您的 Python LangChain 抓取项目。
然后,进入该项目文件夹并在内部初始化一个Python 虚拟环境:
cd langchain_scraping
python3 -m venv env
注意:在 Windows 上请使用 python
而不是 python3
。
现在,使用您喜欢的 Python IDE 打开该项目目录。PyCharm Community Edition 或 Visual Studio Code(安装 Python 扩展)都可以。
在 langchain_scraping
内,新建一个 script.py
文件。该文件目前是空的,但很快就会包含您的 LangChain 网页抓取逻辑。
在 IDE 的终端中,通过以下命令激活虚拟环境:
./env/bin/activate
在 Windows 上,执行:
env/Scripts/activate
好极了!项目已经完成初步设置。
步骤 #2:安装所需库
我们这个 Python LangChain 抓取项目依赖以下库:
python-dotenv
:从.env
文件中加载环境变量。它将用于管理 Bright Data 和 OpenAI 凭证等敏感信息。requests
:执行 HTTP 请求来与 Bright Data 的 Web Scraper API 交互。langchain_openai
:通过其openai
SDK,提供 OpenAI 的 LangChain 集成。
在已经激活的虚拟环境中,使用以下命令安装所有依赖:
pip install python-dotenv requests langchain-community
非常好!现在可以开始编写抓取逻辑了。
步骤 #3:准备项目
在 scripts.py
中添加如下导入:
from dotenv import load_dotenv
import os
上述两行可以让您读取环境变量文件。
注意:os
来自 Python 标准库,因此无需单独安装。
然后,在项目根目录创建一个 .env
文件用于存放所有凭证。下图展示了当前的项目文件结构示例:
在 script.py
中让 python-dotenv
从 .env
文件中加载环境变量:
load_dotenv()
现在,您可以通过以下方式读取 .env
文件或系统中的环境变量:
os.environ.get("<ENV_NAME>")
好!现在准备配置 Bright Data 的 Web Scraper API。
步骤 #4:配置 Web Scraper API
如前文所述,网页抓取伴随着许多挑战。然而,借助 Bright Data 的 Web Scraper API 这样的“一站式”解决方案,抓取就变得更加轻松。通过这些 API,您可以从超过 100 个网站轻松获取解析后的内容。
如果想采用其他方法,请参看我们关于如何抓取新闻文章的教程。
要设置 Web Scraper API,请参阅其官方文档,或者按照下面的说明进行操作。
如果您尚未注册,请先创建一个 Bright Data 账号。登录后,进入您的账户仪表盘,并在左侧点击 “Web Scraper API”:
由于目标站点是 CNN.com,在搜索框里输入“cnn”,然后选择 “CNN news — Collect by URL” 抓取器:
进入该页面后,点击 “Create token” 按钮以生成一个 Bright Data API token:
将会弹出如下对话框,您可以在此配置 token 详情:
配置完成后,点击 “Save”,然后复制您得到的 Bright Data API token。
将其加入到您的 .env
文件中,如下所示:
BRIGHT_DATA_API_TOKEN="<YOUR_BRIGHT_DATA_API_TOKEN>"
用您从弹窗复制下来的值替换 <YOUR_BRIGHT_DATA_API_TOKEN>
。
现在,您的 CNN news Web Scraper API 页面应类似如下示例:
好了!配置好您的 Web Scraper API 请求并进行尝试。
步骤 #5:使用 Bright Data 进行网页抓取
Web Scraper API 会根据您的需求启动一个网页抓取任务(如您在上个页面所见的配置),然后该过程会生成一个包含抓取数据的快照。
下面是 Web Scraper API 抓取过程的概览:
- 您向 Web Scraper API 发送请求,在请求体中提供要抓取的页面 URL。
- 系统启动一个抓取任务来获取并解析这些 URL 上的数据。
- 您反复调用快照检索 API,以在任务完成后获取结果数据。
对于 CNN Web Scraper API,其 POST 端点如下:
"https://api.brightdata.com/datasets/v3/trigger?dataset_id=gd_lycz8783197ch4wvwg&include_errors=true"
该端点接受一个对象数组,其中包含 url
字段,返回类似这样的响应:
{"snapshot_id":"<YOUR_SNAPSHOT_ID>"}
使用此响应中获得的 snapshot_id
,您需要调用以下端点来检索数据:
https://api.brightdata.com/datasets/v3/snapshot/<YOUR_SNAPSHOT_ID>?format=json
如果任务仍在进行,端点会返回 HTTP 状态码 202
;当任务完成并数据就绪时,端点会返回 200
。推荐做法是每隔 10 秒轮询此端点,直到任务完成。
任务完成后,该端点将返回类似如下格式的数据:
[
{
"input": {
"url": "https://www.cnn.com/2024/12/16/weather/white-christmas-forecast-climate/",
"keyword": ""
},
"id": "https://www.cnn.com/2024/12/16/weather/white-christmas-forecast-climate/index.html",
"url": "https://www.cnn.com/2024/12/16/weather/white-christmas-forecast-climate/index.html",
"author": "Mary Gilbert",
"headline": "White Christmas forecast: Will you be left dreaming of snow or reveling in it?",
"topics": [
"weather"
],
"publication_date": "2024-12-16T13:20:52.800Z",
"updated_last": "2024-12-16T13:20:52.800Z",
"content": "Christmas is approaching nearly as fast as Santa’s sleigh, but almost anyone in the United States fantasizing about a movie-worthy white Christmas might need to keep dreaming. Early forecasts indicate temperatures could max out around 10 to 15 degrees above normal for much of the country on Christmas Day. [omitted for brevity...]",
"videos": null,
"images": [
"omitted for brevity..."
],
"related_articles": [],
"keyword": null,
"timestamp": "2024-12-16T14:18:14.101Z"
}
]
content
属性包含了解析后的文章正文,即您想要用到的信息。
在代码中实现前,先从 .env
读取环境变量,并定义端点 URL 常量:
BRIGHT_DATA_API_TOKEN = os.environ.get("BRIGHT_DATA_API_TOKEN")
BRIGHT_DATA_CNN_WEB_SCRAPER_API_URL = "https://api.brightdata.com/datasets/v3/trigger?dataset_id=gd_lycz8783197ch4wvwg&include_errors=true"
接下来,可以将上述流程封装成一个可复用函数,如下所示:
def get_scraped_data(url):
# Authorization headers
headers = {
"Authorization": f"Bearer {BRIGHT_DATA_API_TOKEN}"
}
# Web Scraper API payload
data = [{
"url": url
}]
# Making the POST request to the Bright Data Web Scraper API
response = requests.post(BRIGHT_DATA_CNN_WEB_SCRAPER_API_URL, headers=headers, json=data)
if response.status_code == 200:
response_data = response.json()
snapshot_id = response_data.get("snapshot_id")
if snapshot_id:
# Iterate until the snapshot is ready
snapshot_url = f"https://api.brightdata.com/datasets/v3/snapshot/{snapshot_id}?format=json"
while True:
snapshot_response = requests.get(snapshot_url, headers=headers)
if snapshot_response.status_code == 200:
# Parse and return the snapshot data
snapshot_response_data = snapshot_response.json()
return snapshot_response_data[0].get("content")
elif snapshot_response.status_code == 202:
print("Snapshot not ready yet. Retrying in 10 seconds...")
time.sleep(10) # Wait for 10 seconds before retrying
else:
print(f"Failed to retrieve snapshot. Status code: {snapshot_response.status_code}")
print(snapshot_response.text)
break
else:
print("Snapshot ID not found in the response")
else:
print(f"Error: {response.status_code}")
print(response.text)
让这个函数能够正常工作,需要导入:
import requests
import time
非常棒!您已经学会了如何使用 Bright Data 的 Web Scraper API 进行网页抓取。
步骤 #6:准备使用 OpenAI 模型
本示例使用 OpenAI 模型进行 LangChain 的 LLM 整合。要使用这些模型,需要在环境变量中配置一个 OpenAI API key。
默认情况下,langchain_openai
会自动从 OPENAI_API_KEY
环境变量中读取 OpenAI API key。要进行此设置,请在 .env
文件中添加:
OPENAI_API_KEY="<YOUR_OPEN_API_KEY>"
用您的 OpenAI API key 值替换 <YOUR_OPENAI_API_KEY>
。如果您不知道如何获取该 key,请参考 官方指南。
很好!现在可以在您的 LangChain 抓取脚本中使用 OpenAI 模型了。
步骤 #7:生成 LLM Prompt
定义一个函数,用于接收抓取到的数据,并生成一个可让模型输出文章摘要的提示(prompt):
def create_summary_prompt(content, words=100):
return f"""Summarize the following content in less than {words} words.
CONTENT:
'{content}'
"""
在当前示例中,最终生成的提示大致如下:
Summarize the following content in less than 100 words.
CONTENT:
'Christmas is approaching nearly as fast as Santa’s sleigh, but almost anyone in the United States fantasizing about a movie-worthy white Christmas might need to keep dreaming. Early forecasts indicate temperatures could max out around 10 to 15 degrees above normal for much of the country on Christmas Day. It’s a forecast reminiscent of last Christmas for many, which came amid the warmest winter on record in the US. But the country could be split in two by warmth and cold in the run up to the big day. [omitted for brevity...]'
如果您将它输入 ChatGPT,就能得到想要的结果:
这就说明我们的提示可行!
步骤 #8:集成 OpenAI
首先,调用 get_scraped_data()
函数来获取文章的内容:
article_url = "https://www.cnn.com/2024/12/16/weather/white-christmas-forecast-climate/"
scraped_data = get_scraped_data(article_url)
如果 scraped_data
不为 None
,则生成 prompt:
if scraped_data is not None:
prompt = create_summary_prompt(scraped_data)
最后,使用 ChatOpenAI
(在 GPT-4o mini 模型上) 来处理此 prompt:
model = ChatOpenAI(model="gpt-4o-mini")
response = model.invoke(prompt)
别忘了从 langchain_openai
导入 ChatOpenAI
:
from langchain_openai import ChatOpenAI
整个过程结束后,summary
应当包含与之前在 ChatGPT 步骤中类似的摘要:
summary = response.content
非常棒!LangChain 网页抓取逻辑已完成。
步骤 #9:导出 AI 处理后的数据
接下来,您只需将经过所选 AI 模型(即 LangChain)处理后生成的数据导出为可读格式,例如 JSON 文件。
为此,先创建一个包含您想要数据的字典,然后将其保存为 JSON 文件:
export_data = {
"url": article_url,
"summary": summary
}
file_name = "summary.json"
with open(file_name, "w") as file:
json.dump(export_data, file, indent=4)
从 Python 标准库导入 json
:
import json
恭喜!您的脚本已经准备就绪。
步骤 #10:添加一些日志
由于使用 Web Scraping AI 和 ChatGPT 分析的抓取过程可能需要一些时间,因此最好在脚本中添加日志追踪进度。
可以在脚本的关键步骤中加入 print()
语句,例如:
article_url = "https://www.cnn.com/2024/12/16/weather/white-christmas-forecast-climate/"
print(f"Scraping data from '{article_url}'...")
scraped_data = get_scraped_data(article_url)
if scraped_data is not None:
print("Data successfully scraped, creating summary prompt")
prompt = create_summary_prompt(scraped_data)
# Ask ChatGPT to perform the task specified in the prompt
print("Sending prompt to ChatGPT for summarization")
model = ChatOpenAI(model="gpt-4o-mini")
response = model.invoke(prompt)
# Get the AI result
summary = response.content
print("Received summary from ChatGPT")
# Export the produced data to JSON
export_data = {
"url": article_url,
"summary": summary
}
print("Exporting data to JSON")
# Write the output dictionary to JSON file
file_name = "summary.json"
with open(file_name, "w") as file:
json.dump(export_data, file, indent=4)
print(f"Data exported to '${file_name}'")
else:
print("Scraping failed")
步骤 #11:最终整合
您的最终 script.py
文件应如下所示:
from dotenv import load_dotenv
import os
import requests
import time
from langchain_openai import ChatOpenAI
import json
load_dotenv()
BRIGHT_DATA_API_TOKEN = os.environ.get("BRIGHT_DATA_API_TOKEN")
BRIGHT_DATA_CNN_WEB_SCRAPER_API_URL = "https://api.brightdata.com/datasets/v3/trigger?dataset_id=gd_lycz8783197ch4wvwg&include_errors=true"
def get_scraped_data(url):
# Authorization headers
headers = {
"Authorization": f"Bearer {BRIGHT_DATA_API_TOKEN}"
}
# Web Scraper API payload
data = [{
"url": url
}]
# Making the POST request to the Bright Data Web Scraper API
response = requests.post(BRIGHT_DATA_CNN_WEB_SCRAPER_API_URL, headers=headers, json=data)
if response.status_code == 200:
response_data = response.json()
snapshot_id = response_data.get("snapshot_id")
if snapshot_id:
# Iterate until the snapshot is ready
snapshot_url = f"https://api.brightdata.com/datasets/v3/snapshot/{snapshot_id}?format=json"
while True:
snapshot_response = requests.get(snapshot_url, headers=headers)
if snapshot_response.status_code == 200:
# Parse and return the snapshot data
snapshot_response_data = snapshot_response.json()
return snapshot_response_data[0].get("content")
elif snapshot_response.status_code == 202:
print("Snapshot not ready yet. Retrying in 10 seconds...")
time.sleep(10) # Wait for 10 seconds before retrying
else:
print(f"Failed to retrieve snapshot. Status code: {snapshot_response.status_code}")
print(snapshot_response.text)
break
else:
print("Snapshot ID not found in the response")
else:
print(f"Error: {response.status_code}")
print(response.text)
def create_summary_prompt(content, words=100):
return f"""Summarize the following content in less than {words} words.
CONTENT:
'{content}'
"""
# Retrieve the content from the given web page
article_url = "https://www.cnn.com/2024/12/16/weather/white-christmas-forecast-climate/"
scraped_data = get_scraped_data(article_url)
# Ask ChatGPT to perform the task specified in the prompt
prompt = create_summary_prompt(scraped_data)
model = ChatOpenAI(model="gpt-4o-mini")
response = model.invoke(prompt)
# Get the AI result
summary = response.content
# Export the produced data to JSON
export_data = {
"url": article_url,
"summary": summary
}
# Write dictionary to JSON file
with open("summary.json", "w") as file:
json.dump(export_data, file, indent=4)
没想到吧?不到 100 行的代码,您就构建出了一个基于 AI 的 LangChain 网页抓取脚本。
使用如下命令测试:
python3 script.py
或在 Windows 上:
python script.py
终端输出应类似如下:
Scraping data from 'https://www.cnn.com/2024/12/16/weather/white-christmas-forecast-climate/'...
Snapshot not ready yet. Retrying in 10 seconds...
Data successfully scraped, creating summary prompt
Sending prompt to ChatGPT for summarization
Received summary from ChatGPT
Exporting data to JSON
Data exported to 'summary.json'
您会在项目目录下看到一个名为 summary.json
的新文件,内容大致如下:
{
"url": "https://www.cnn.com/2024/12/16/weather/white-christmas-forecast-climate/",
"summary": "As Christmas approaches, forecasts indicate temperatures in the US may be 10 to 15 degrees above normal, continuing a trend from last year\u2019s warm winter. The western US will likely remain warm, while the East experiences colder conditions leading up to Christmas. Some areas may see a mix of rain and snow, but a true \"white Christmas\" requires at least an inch of snow on the ground. Historically, cities like Minneapolis and Burlington have the best chances for snow, while places like New York City and Atlanta have significantly lower probabilities."
}
大功告成!
结论
在本教程中,您了解了为什么网页抓取是为 AI 工作流收集数据的好方法,以及如何使用 LangChain 对其进行分析。具体地说,您学习了如何构建一个基于 Python 的 LangChain 网页抓取脚本,从 CNN 新闻文章中提取数据并通过 OpenAI API 进行处理。
您可能需要考虑的主要挑战包括:
- 网站结构会经常变动。
- 许多网站都有复杂的反机器人措施。
- 同时获取大规模数据会比较复杂且昂贵。
Bright Data 的 Web Scraper API 提供了从主流网站无缝提取数据的解决方案,能够轻松克服这些挑战。它在支持 RAG 应用和其他基于 LangChain 的解决方案时是非常宝贵的工具。
同时也欢迎探索我们更多的 AI 和 LLM 相关服务。
立即注册,探索哪一种 Bright Data 代理服务或抓取产品最适合您的需求。可以先免费试用!