بنقرة واحدة
scrape-codegen-generate
Generate web-poet page object code from per-page extraction analyses
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Generate web-poet page object code from per-page extraction analyses
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Extract structured data (all available fields with values) from a page saved locally as an HTML file, optionally following a schema. Use this skill only to process already downloaded files. Do not invoke when the user provides a URL. When invoking, pass the user's full request verbatim as args — do not pre-parse file paths and don't rephrase it.
Analyze an HTML page to produce field extraction instructions for code generation
Generate web-poet page object code from an extraction spec
Generate a Scrapy spider that wires page objects together
Create a new extraction spec from a URL — explore a detail page, discover fields, quick schema approval
Generate an HTML review page for schema and extracted data verification
| name | scrape-codegen-generate |
| description | Generate web-poet page object code from per-page extraction analyses |
| argument-hint | [work-path] [output-path] [spec-path] |
| allowed-tools | Skill, Bash, Read, Write |
You are generating web-poet page object code. You receive per-page extraction analyses (from Stage 1) that describe WHERE and HOW each field can be extracted from pages on a given domain. Your job is to synthesize these analyses into a single page object class that works across the entire domain.
The raw argument string is $ARGUMENTS. Split it into 3 whitespace-separated positional arguments:
.scrape/.work/spec.scrape/spec/page_object.py.scrape/spec/spec.jsonPlus, taken from the surrounding prompt text (not from the argument string):
@field methods for those fields. When not set, generate all fields found in the analyses.Read web-poet.md and docs-access.md from ${CLAUDE_SKILL_DIR}/../scrape/references/.
Read the schema from {spec_path} — use the properties object inside schema.
Also read data_type from {spec_path}.
If data_type ends with -list, set is_list_type = true.
Read all Stage 1 analysis files from {work_path}/codegen-analyze/:
{work_path}/codegen-analyze/list-1.json
{work_path}/codegen-analyze/list-2.json
...
(or detail-*.json for non-list specs)
For each field in the schema, review all per-page analyses together:
No content filtering — ever. Even if the user's prompt asks to filter, exclude, or limit results by value, do NOT implement that logic in the page object. Page objects extract; spiders filter. Mention in your summary that filtering belongs at the spider level.
Generate a complete, self-contained Python module following the web-poet reference. The code must:
None when a field is not present (never empty string or []).extruct for JSON-LD/microdata, price_parser for prices, jmespath for JSON queries.For non-list types (is_list_type = false), standard structure:
from web_poet import WebPage, field
# ... other imports as needed
class PageObject(WebPage[dict]):
# shared helpers as @cached_property if multiple fields need them
@field
def field_name(self) -> type | None:
# extraction logic
...
For list types (is_list_type = true), use web-poet's SelectorExtractor
(see the "Processors for nested fields" section of the
web-poet fields reference).
Define a private SelectorExtractor subclass for per-item extraction, then
iterate over the container selector in the items field. Each analysis file has
container_selector and per-field relative selectors.
import logging
from web_poet import WebPage, Returns, SelectorExtractor, field, handle_urls
from {project}.items import Product, ProductListItems
logger = logging.getLogger(__name__)
class _ProductExtractor(SelectorExtractor[Product]):
@field
def title(self) -> str | None:
return self.css("h3 a::attr(title)").get()
@field
def price(self) -> str | None:
return self.css("p.price_color::text").get()
@handle_urls("example.com")
class ProductListPage(WebPage, Returns[ProductListItems]):
@field
async def items(self) -> list[Product] | None:
result = []
for el in self.css("article.product_pod"):
try:
result.append(await _ProductExtractor(el).to_item())
except Exception:
logger.error("Failed to extract item from %s", self.url, exc_info=True)
return result or None
Key rules for list-type code:
_<ItemClass>Extractor class (e.g. _ProductExtractor) that extends
SelectorExtractor[ItemClass] and has one @field method per item fielditems field must be async def because to_item() is a coroutineawait extractor.to_item() in try/except Exception with a
logger.error(..., exc_info=True) call — this isolates extraction failures to
individual items and logs a full traceback without aborting the whole listreturn result or None (never return [])self.css(...) on the extractor operates on el, not the full page)ItemClass and WrapperClass from the project's items moduleSave the generated code to {output_path}.
Return a summary of what was generated:
Generated page object with N fields:
name: CSS h1.product-title::text
price: JSON-LD offers.price, fallback to CSS span.price
description: CSS div.product-description (text join)
rating: JSON-LD aggregateRating.ratingValue
image_url: CSS img.product-image::attr(src) + urljoin
Include notes on any fields where consensus was difficult or where extraction may be fragile.