---
title: "Scrape Figma Community with CrewAI | EnConvert"
description: "Scrape Figma Community pages into a CrewAI pipeline with EnConvert Perceive, returning clean Markdown with navigation and sidebars stripped in a batch call"
canonical: "https://www.enconvert.com/solutions/scrape-figma-community-with-crewai-enconvert"
locale: "en"
---

# How to Scrape Figma Community with CrewAI

A developer building a CrewAI pipeline that reads Figma Community pages needs clean page text before passing it into an agent tool. Figma Community pages mix content with a resource sidebar, plugin cards, file preview thumbnails, like and duplicate counts, creator profile links, tag filters, community nav tabs, comment sections, and featured banners, and scraping them by hand requires CSS selectors that break when Figma updates its layout. EnConvert Perceive renders up to 10 Figma Community pages in a single batch call and returns clean Markdown for each one, with navigation and sidebars stripped by default. The extracted Markdown is ready to pass into a CrewAI agent tool with no HTML parsing.

## Example

```python
import os
import requests
from crewai import Agent, Crew, Task
from crewai.tools import BaseTool
from pydantic import BaseModel, Field

# CrewAI reads OPENAI_API_KEY from the environment

BASE_URL = "https://api.enconvert.com/v2"
headers = {
    "X-API-Key": os.environ["ENCONVERT_API_KEY"],
    "Content-Type": "application/json",
}

FIGMA_URLS = [url.strip() for url in os.environ["FIGMA_COMMUNITY_URLS"].split(",")]  # public Figma Community page URLs

class FigmaUrlsInput(BaseModel):
    urls: list[str] = Field(description="Up to 10 Figma Community page URLs to scrape.")

class FigmaCommunityTool(BaseTool):
    name: str = "read_figma_community_pages"
    description: str = (
        "Reads publicly accessible Figma Community pages and returns the main "
        "content of each as clean Markdown, labelled with its source URL."
    )
    args_schema: type[BaseModel] = FigmaUrlsInput

    def _run(self, urls: list[str]) -> str:
        if len(urls) > 10:
            raise ValueError("Send 10 URLs or fewer for an inline response")

        response = requests.post(
            f"{BASE_URL}/perceive/batch",
            headers=headers,
            json={"urls": urls, "options": {"outputs": ["markdown"]}},
            timeout=300,
        )

        if response.status_code == 402:
            raise RuntimeError("Monthly ops allowance exhausted")
        response.raise_for_status()

        sections = []
        for result in response.json()["items"]:
            page_url = result["url"]
            if result.get("status") != "completed":
                sections.append(f"Source: {page_url}\nCould not be read ({result.get('status')}).")
                continue
            if result.get("is_blocked"):
                sections.append(f"Source: {page_url}\nCould not be read (blocked).")
                continue
            render_quality = result.get("render_quality", 1.0)
            if render_quality < 0.40:
                sections.append(f"Source: {page_url}\nCould not be read (render quality {render_quality}).")
                continue
            markdown = requests.get(
                result["outputs"]["markdown"]["url"], timeout=60
            )
            markdown.raise_for_status()
            sections.append(f"Source: {page_url}\n\n{markdown.text}")

        return "\n\n---\n\n".join(sections) or "No pages were returned."

figma_tool = FigmaCommunityTool()

agent = Agent(
    role="Figma Community researcher",
    goal=(
        "Answer questions about Figma Community plugins and files using only "
        "the retrieved page content, citing the source URL for every statement."
    ),
    backstory="You read Figma Community pages and answer questions from their content.",
    tools=[figma_tool],
    llm="gpt-4.1",
)

task = Task(
    description=(
        f"Read these Figma Community pages: {', '.join(FIGMA_URLS)}. "
        "Summarise what each plugin or file does and how they differ."
    ),
    expected_output="A concise answer supported by the retrieved page content, with source URLs cited.",
    agent=agent,
)

crew = Crew(agents=[agent], tasks=[task])
result = crew.kickoff()
print(result)
```

## Output

Perceive returns clean Markdown for each URL in the batch, with navigation and sidebars stripped by default, delivered as pre-signed URLs that you fetch once per page. Scraping Figma Community by hand needs CSS selectors that break when the layout changes, and passing raw Figma Community HTML into a CrewAI agent fills the agent context with plugin cards, like counts, and community nav chrome that add noise to every task run.

## Get started

[Get free API key — 500 ops per month, no card required.](https://www.enconvert.com/auth?mode=signup)

## Related solutions

- [How to Scrape Wikipedia with LlamaIndex](https://www.enconvert.com/solutions/scrape-wikipedia-with-llamaindex-enconvert.md)
- [How to Ingest Markdown into LangChain with EnConvert](https://www.enconvert.com/solutions/ingest-markdown-into-langchain-with-heading-context.md)
- [Best JigsawStack Alternative for Structured Data Extraction](https://www.enconvert.com/solutions/jigsawstack-alternative-for-structured-data-enconvert.md)
- [How to Ingest Audio Transcripts into Qdrant with EnConvert](https://www.enconvert.com/solutions/ingest-audio-transcripts-into-qdrant-enconvert-api.md)
- [How to Ingest a CSV into pgvector Without Losing Row Context](https://www.enconvert.com/solutions/ingest-csv-into-pgvector-with-row-context-enconvert-api.md)
- [How to Ingest CSV into CrewAI with EnConvert](https://www.enconvert.com/solutions/ingest-csv-into-crewai-with-enconvert.md)
