NSDT工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎 - AI模型在线查看 - Three.js虚拟轴心开发包 - 3D模型在线减面 - STL模型在线切割 - 3D道路快速建模
使用 Scrapy 时,你可以轻松使用大型语言模型 (LLM) 来自动化或增强你的 Web 解析。
有多种使用 LLM 来帮助进行 Web 抓取的方法。在本指南中,我们将在每个页面上调用一个 LLM,从中抽取我们定义的一组属性,而无需编写任何选择器或训练任何模型。
1、启动 Scrapy 项目
按照 Web 抓取教程的启动 Scrapy 项目页面上的说明启动 Scrapy 项目。
2、安装 LLM 依赖项
本指南将使用 LiteLLM 作为 LLM 的 API。
出于本指南的目的,我们将通过 Ollama 运行 Mistral 7B LLM,但 LiteLLM 几乎可以运行任何 LLM,正如你稍后将看到的那样。
首先安装 html2text、LiteLLM 和 Ollama:
pip install html2text litellm ollama
然后启动 Ollama 服务器:
ollama serve
打开第二个终端,安装 Mistral 7B:
ollama pull mistral
3、在你的爬虫程序中使用 LLM
现在你有一个包含简单爬虫程序和 LLM 的 Scrapy 项目可供使用,请在 tutorial/spiders/books_toscrape_com_llm.py
中使用以下代码创建第一个爬虫程序的替代方案:
import json
from json.decoder import JSONDecodeError
from logging import getLogger
import ollama
from html2text import HTML2Text
from litellm import acompletion
from scrapy import Spider
html_cleaner = HTML2Text()
logger = getLogger(__name__)
async def llm_parse(response, prompts):
key_list = ", ".join(prompts)
formatted_scheme = "\n".join(f"{k}: {v}" for k, v in prompts.items())
markdown = html_cleaner.handle(response.text)
llm_response = await acompletion(
messages=[
{
"role": "user",
"content": (
f"Return a JSON object with the following root keys: "
f"{key_list}\n"
f"\n"
f"Data to scrape:\n"
f"{formatted_scheme}\n"
f"\n"
f"Scrape it from the following Markdown text:\n"
f"\n"
f"{markdown}"
),
},
],
model="ollama/mistral",
)
data = llm_response["choices"][0]["message"]["content"]
try:
return json.loads(data)
except JSONDecodeError:
logger.error(f"LLM returned an invalid JSON for {response.url}: {data}")
return {}
class BooksToScrapeComLLMSpider(Spider):
name = "books_toscrape_com_llm"
start_urls = [
"http://books.toscrape.com/catalogue/category/books/mystery_3/index.html"
]
def parse(self, response):
next_page_links = response.css(".next a")
yield from response.follow_all(next_page_links)
book_links = response.css("article a")
yield from response.follow_all(book_links, callback=self.parse_book)
async def parse_book(self, response):
prompts = {
"name": "Product name",
"price": "Product price as a number, without the currency symbol",
}
llm_data = await llm_parse(response, prompts)
yield {
"url": response.url,
**llm_data,
}
在上面的代码中:
首先定义了一个 llm_parse
函数,它接受 Scrapy 响应和要提取的字段字典及其字段特定提示。
然后,将响应转换为 Markdown 语法,以便 LLM 更轻松地解析,并向 LLM 发送一个提示,要求输入具有相应字段的 JSON 对象。
注意:构建一个以预期格式获取预期数据的提示是此过程中最困难的部分。此处的示例提示适用于 Mistral 7B 和 books.toscrape.com,但可能不适用于其他 LLM 或其他网站。
如果是有效的 JSON,则返回 LLM 结果。
使用字段提示调用 llm_parse
来提取名称和价格,并在包含非来自 LLM(url)的额外字段后生成结果字典。
现在可以运行你的代码:
scrapy crawl books_toscrape_com_llm -O books.csv
在大多数计算机上,执行将需要很长时间。运行 ollama serve
的终端中的日志将显示你的 LLM 如何获取提示并为其生成响应。
执行完成后,生成的 books.csv
文件将包含 books.toscrape.com 神秘类别中所有书籍的记录(CSV 格式)。您可以使用任何电子表格应用程序打开 books.csv
。
4、后续步骤
以下是一些后续步骤的想法:
- 尝试其他 LLM。
上述代码中的以下一行通过 Ollama 的本地实例确定要使用的 LLM 是 Mistral 7B:
model="ollama/mistral"
如果你可以访问其他 LLM,则可以将此行更改为使用其他 LLM,并查看更改如何影响速度、质量和成本。
请参阅 LiteLLM 文档,了解许多不同 LLM 的设置说明。
- 看看你是否可以获得与 Zyte API 自动提取相同的输出(例如产品),同时具有可比的速度、质量和成本。
- 看看你是否还可以自动化抓取部分并实现与 Zyte 的 AI 驱动蜘蛛可以做的事情类似的目标。
- 尝试提取源 HTML 中无法以结构化方式获得的数据,例如书籍作者,有时可以在书籍描述中找到。
- 尝试提取源 HTML 中无法直接获得的数据,例如书籍语言(英语)、货币代码(GBP)或书籍描述的摘要。
- 尝试不同的 HTML 清理方法,或者根本不进行清理。
上面的代码将响应 HTML 转换为 Markdown,因为这允许 Mistral 7B 按预期工作。其他 LLM 可能适用于原始 HTML,可能在经过一些清理之后(请参阅 clear-html),从而能够提取转换为 Markdown 时可能丢失的一些额外数据。
但请注意,LLM 的上下文长度有限,可能需要清理和修剪 HTML 才能将 HTML 放入提示中,而不会超过该上下文长度。
- 如果你可以访问支持图像解析的 LLM,请查看是否可以扩展蜘蛛以下载书籍封面,并从中提取其他信息,例如书籍作者。
- 不要每页使用一个 LLM,而是使用 LLM 根据第一页的原始 HTML 为所需字段生成 CSS 选择器,并使用这些选择器解析所有其他页面。
这样可以最大限度地减少 LLM 的使用,以获得更好的速度和成本,但对于具有多种不同布局或执行某些布局 A-B 测试的网站,或者网站在抓取过程中更改布局的不幸情况,可能会影响质量。
BimAnt翻译整理,转载请标明出处