现代 Scrapy 开发者指南(第 3 部分):使用 Web Scraping Co-pilot 自动生成页面对象

发布: (2025年12月17日 GMT+8 02:55)
7 min read
原文: Dev.to

I’m ready to translate the article for you, but I’ll need the text you’d like translated. Could you please paste the content (excluding the source line you’ve already provided) here? Once I have the article text, I’ll translate it into Simplified Chinese while preserving the formatting, markdown, and code blocks.

先决条件与设置

本教程假设您已具备以下条件:

  • 已完成第 1 部分(请参阅上面的链接)。
  • 已安装 Visual Studio Code
  • 已安装 Web Scraping Co‑pilot 扩展(我们将在此后进行安装)。

第一步:Installing Web Scraping Co‑pilot

  1. 打开 VS Code 并前往 Extensions 选项卡。

  2. 搜索 Web Scraping Co‑pilot(由 Zyte 发布)并进行安装。

    Web Scraping Co‑pilot

  3. 安装后你会在侧边栏看到一个新图标。点击它,扩展会自动检测你的 Scrapy 项目。

  4. 如有提示,请允许它安装一些依赖(例如 pytest)。这可确保你的环境已准备好用于 AI 驱动的生成。

第2步:自动生成我们的 BookItem

我们将从第 1 部分的 spider 开始,让 Co‑pilot 为 BookItem 创建一个页面对象,添加比第 2 部分更多的字段

  1. 打开 Co‑pilot 聊天窗口。

  2. 选择 “Web Scraping”。

  3. 输入类似下面的提示:

    Create a page object for the item BookItem using the sample URL https://books.toscrape.com/catalogue/the-host_979/index.html

Co‑pilot 将会:

  • 检查你的项目——确认已安装 scrapy‑poetpytest(如果未安装会提供添加)。
  • 添加 scrapy‑poet 设置——自动在 settings.py 中插入 ADDONSSCRAPY_POET_DISCOVER 条目。
  • 创建 items.py——生成一个新的 BookItem 类,包含它在页面上能发现的所有字段。
# tutorial/items.py (Auto‑Generated!)
import attrs

@attrs.define
class BookItem:
    """
    The structured data we extract from a book *detail* page.
    """
    name: str
    price: str
    url: str
    availability: str          #  str:
        return self.response.css("h1::text").get()

    @field
    def price(self) -> str:
        return self.response.css("p.price_color::text").get()

    @field
    def url(self) -> str:
        return self.response.url

    @field
    def availability(self) -> str:
        # The second element contains the actual text
        return self.response.css("p.availability::text").getall()[1].strip()

    @field
    def number_of_reviews(self) -> int:
        return int(self.response.css("table tr:last-child td::text").get())

    @field
    def upc(self) -> str:
        return self.response.css("table tr:first-child td::text").get()

大约 30 秒后,Co‑pilot 已完成我们在第 2 部分手动完成的所有工作——并且还添加了额外的字段。

第 3 步:运行 AI‑生成的测试

Co‑pilot 也为你编写了单元测试。tests 文件夹中现在包含 test_bookstoscrape_com.py

通过 Co‑pilot UI(“Run Tests”)在终端运行测试:

$ pytest
=================== test session starts ===================
...
tests/test_bookstoscrape_com.py::test_book_detail[book_0] PASSED
tests/test_bookstoscrape_com.py::test_book_detail[book_1] PASSED
...
=================== 8 passed in 0.10s ====================

你的解析逻辑已被完整测试,而且你没有编写任何测试代码。

第4步:重构爬虫(简易方式)

现在更新 tutorial/spiders/books.py 以使用新架构,就像我们在第 2 部分所做的那样。

# tutorial/spiders/books.py

import scrapy
# Import our new, auto‑generated Item class
from tutorial.items import BookItem

class BooksSpider(scrapy.Spider):
    name = "books"
    # ... (rest of spider from Part 1) ...

    async def parse_listpage(self, response):
        product_urls = response.css("article.product_pod h3 a::attr(href)").getall()
        for url in product_urls:
            # We just tell Scrapy to call parse_book
            yield response.follow(url, callback=self.parse_book)

    async def parse_book(self, response):
        # Let the Page Object do the heavy lifting
        page = BookDetailPage(response)
        item = await page.to_item()
        yield item

有了自动生成的 BookDetailPage 处理所有解析,爬虫变得极其简洁。

🎉 就是这样!

在短短几分钟内,Web Scraping Co‑pilot 已经:

  1. 创建了包含所有相关字段的 BookItem 模式。
  2. 生成了功能完整的页面对象(BookDetailPage)。
  3. 生成了夹具和全面的单元测试。
  4. 将爬虫代码简化为干净、支持异步的实现。

现在你可以专注于爬取策略、数据管道和扩展——让 AI 处理重复的样板代码。祝爬取愉快!

t_page_url = response.css("li.next a::attr(href)").get()
if next_page_url:
    yield response.follow(next_page_url, callback=self.parse_listpage)

# We ask for the BookItem, and scrapy‑poet does the rest!
async def parse_book(self, response, book: BookItem):
    yield book

第5步:自动生成我们的 BookListPage

我们可以对列表页重复完全相同的过程,以完成重构。

提示 Co‑pilot:

Create a page object for the list item BookListPage using the sample URL

结果

  • Co‑pilot 在 items.py 中创建了 BookListPage 条目。
  • 它在 bookstoscrape_com.py 中创建了 BookListPageObject,并为 book_urlsnext_page_url 添加了解析器。
  • 它编写并通过了测试。

现在我们可以最后一次更新爬虫,使其 完全 架构化。

# tutorial/spiders/books.py (FINAL VERSION)

import scrapy
from tutorial.items import BookItem, BookListPage   # Import both

class BooksSpider(scrapy.Spider):
    # ... (name, allowed_domains, url) ...

    async def start(self):
        yield scrapy.Request(self.url, callback=self.parse_listpage)

    # 我们现在请求 BookListPage 条目!
    async def parse_listpage(self, response, page: BookListPage):
        # 所有解析逻辑已从爬虫中移除。
        for url in page.book_urls:
            yield response.follow(url, callback=self.parse_book)

        if page.next_page_url:
            yield response.follow(page.next_page_url, callback=self.parse_listpage)

    async def parse_book(self, response, book: BookItem):
        yield book

我们的爬虫现在只是一个 爬取器。它没有任何解析逻辑。所有寻找选择器和编写解析器的繁重工作都已由 Co‑pilot 自动完成。

结论:“混合开发者”

Web Scraping Co‑pilot 并不会取代你。它 加速 你的工作。它会自动化 90 % 的“繁琐工作”(寻找选择器、编写样板代码、创建测试),让你能够专注于那关键的 10 %:爬取逻辑、策略以及处理复杂站点

这就是我们——Scrapy 维护者——专业构建爬虫的方式。

接下来怎么办?加入社区

💬 在 Discord 上交流 – 在 Scrapy 代码上卡住了?在我们的 Discord 中向维护者和 5k+ 开发者求助。
▶️ 在 YouTube 上观看 – 本文基于我们的视频!在频道上观看完整演示。
📩 了解更多 – 想要获取更多内容?在第 2 部分我们将介绍 Scrapy Items 和 Pipelines。订阅 Extract 新闻通讯,别错过。

Back to Blog

相关文章

阅读更多 »