Files
mql5-skills/docs-dev/extraction.md
T
2026-06-23 21:47:51 +08:00

151 lines
4.5 KiB
Markdown

# Extraction Workflow — Web Content to Markdown
Two-phase pipeline: download HTML (lossless) → convert to Markdown (offline).
```
Phase 1: sitemap XML → URL list → fetch HTML → save to html_cache/
Phase 2: html_cache/ HTML → parse → download images → write Markdown
```
- **Input**: `sitemaps/sitemap_book_en.xml`, `sitemaps/sitemap_docs_en.xml`
- **HTML cache**: `html_cache/book/`, `html_cache/docs/`
- **Output**: `skills/mql5/references/book/`, `skills/mql5/references/docs/`
- **Tool**: Python script using `requests` + `beautifulsoup4`
## Script — `scripts/extract.py`
### CLI
```bash
# Phase 1: download HTML
python scripts/extract.py download --sitemap sitemaps/sitemap_book_en.xml
python scripts/extract.py download --all
# Phase 2: convert to Markdown
python scripts/extract.py convert --sitemap sitemaps/sitemap_book_en.xml
python scripts/extract.py convert --all
# Debug single page (fetches + analyzes)
python scripts/extract.py debug URL
```
Options (download/convert):
- `--sitemap PATH` — single sitemap
- `--all` — all known sitemaps
- `--force` — re-process everything (ignore progress log)
- `--dry-run` — show plan without processing
### Phase 1 — Download
1. Parse sitemap XML → URL list
2. Build file map (naming convention, see `naming.md`)
3. For each URL:
- Skip if already cached (idempotent)
- Fetch HTML with retry + rate limiting (0.5s delay)
- Save raw HTML to `html_cache/{label}/{NN-chapter}/{NNNN-name}.html`
4. Progress: `html_cache/{label}/.download.log`
HTML files are saved as-is — no parsing, no transformation.
### Phase 2 — Convert
1. Parse sitemap XML → URL list (same mapping)
2. For each URL:
- Skip if already converted (idempotent)
- Read local HTML from `html_cache/`
- Parse `#help` content → elements
- Convert elements to Markdown
- Download images to `pics/` subfolder
- Write `.md` file
3. Progress: `{output_dir}/.convert.log`
### HTML Cache Structure
```
html_cache/
├── book/
│ ├── 0000-book.html
│ ├── .download.log
│ ├── 00-intro/
│ │ ├── 0001-intro.html
│ │ ├── 0002-intro-edit-compile-run.html
│ │ └── ...
│ └── ...
└── docs/
├── 0000-docs.html
├── .download.log
├── 00-basis/
│ ├── 0001-basis.html
│ └── ...
└── ...
```
Filenames mirror the markdown output (same 4-digit prefix, same derived name).
## Content Extraction Rules
### Main Content Selector
```css
#help > h1:nth-child(1)
```
Extract from this `<h1>` through to the last content element.
**Fallback**: If no `h1` exists (e.g. root pages like `/en/book`), use the
first `<Tag>` child of `#help` as the start element.
### Table Handling
| Has `<thead>` | Meaning | Render as |
|---------------|---------|-----------|
| Yes | Data table with headers | Markdown table with `|---|` separator |
| No | Code block or console output | Fenced code block (` ``` `) |
Tables without `<thead>` on mql5.com typically contain:
- MQL5 code (with `<span>` color classes for syntax highlighting)
- MetaTrader 5 Strategy Tester console output
### Image Handling
The `<img>` is often nested inside `<p class="p_ImageCaption">`.
**Alt text extraction**:
1. Try `img.find_next_sibling("p")`
2. If not found, try `img.parent.find_next_sibling("p")`
3. Fall back to `img.get("alt", "")`
**`<p>` containing `<img>`**: The `<p>` is treated as an image block —
the `<img>` is routed through the image download path.
### Code Blocks
- `<pre><code>` → fenced code block with language detection
- Language detected from CSS classes (`mql`, `cpp`, `sql`, etc.)
- Text whitespace preserved (no space-joining)
## Debug Target — TesterStatistics
URL: `https://www.mql5.com/en/book/automation/tester/tester_testerstatistics`
Content boundaries:
- Start: `#help > h1:nth-child(1)` → "Getting testing financial statistics: TesterStatistics"
- End: `p.p_Text:nth-child(45)`
Exercises: data tables (thead), code blocks (no thead), images, console output.
## Error Handling
| Error | Phase 1 | Phase 2 |
|-------|---------|---------|
| HTTP 404 | Skip, log, continue | N/A (offline) |
| HTTP 429/5xx | Retry with backoff | N/A |
| Missing HTML | N/A | Log warning, skip |
| Parse error | N/A | Log error, skip |
| Image download fail | N/A | Log warning, use original URL |
## Resumability
Each phase has its own progress log. Re-running skips completed items.
Use `--force` to re-process everything.