scraper-rust 0.4.3__tar.gz → 0.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/.gitignore +1 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/AGENTS.md +41 -24
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/Cargo.lock +159 -193
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/Cargo.toml +5 -4
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/PKG-INFO +7 -5
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/README.md +6 -4
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/benchmarks/README.md +9 -13
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/docs/README.md +4 -3
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/docs/api.md +12 -9
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/docs/architecture.md +13 -12
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/docs/async-api.md +3 -3
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/docs/development.md +5 -4
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/docs/limits-and-errors.md +7 -7
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/pyproject.toml +1 -1
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/scraper_rs/asyncio.py +41 -80
- scraper_rust-0.5.1/src/async_core.rs +304 -0
- scraper_rust-0.5.1/src/cache.rs +42 -0
- scraper_rust-0.5.1/src/document.rs +275 -0
- scraper_rust-0.5.1/src/element.rs +208 -0
- scraper_rust-0.5.1/src/functions.rs +249 -0
- scraper_rust-0.5.1/src/html5_dict.rs +493 -0
- scraper_rust-0.5.1/src/lib.rs +66 -0
- scraper_rust-0.5.1/src/limits.rs +30 -0
- scraper_rust-0.5.1/src/prettify.rs +207 -0
- scraper_rust-0.5.1/src/runtime.rs +32 -0
- scraper_rust-0.5.1/src/selectors.rs +85 -0
- scraper_rust-0.5.1/src/tests.rs +462 -0
- scraper_rust-0.5.1/src/text.rs +76 -0
- scraper_rust-0.5.1/src/xpath.rs +249 -0
- scraper_rust-0.5.1/uv.lock +247 -0
- scraper_rust-0.4.3/src/lib.rs +0 -2610
- scraper_rust-0.4.3/uv.lock +0 -247
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/.github/workflows/benchmark.yml +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/.github/workflows/bump-version.yml +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/.github/workflows/release.yml +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/.github/workflows/tests.yml +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/LICENSE +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/benchmarks/bench_parse_memory.py +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/benchmarks/bench_sync_async.py +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/benchmarks/bench_vs_markupever.py +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/examples/demo.py +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/examples/demo_async_document.py +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/examples/demo_asyncio.py +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/examples/demo_prettify_url.py +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/justfile +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/py.typed +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/scraper_rs/__init__.py +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/scraper_rs/asyncio.pyi +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/scraper_rs.pyi +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/tests/test_asyncio.py +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/tests/test_performance.py +0 -0
- {scraper_rust-0.4.3 → scraper_rust-0.5.1}/tests/test_scraper.py +0 -0
|
@@ -17,10 +17,11 @@ This file contains essential information for Large Language Models (LLMs) to eff
|
|
|
17
17
|
|
|
18
18
|
### Core Technologies
|
|
19
19
|
- **Rust** (2024 edition)
|
|
20
|
-
- `scraper` v0.
|
|
20
|
+
- `scraper` v0.27.0 from `rust-scraper/scraper` with the `atomic` feature - HTML parsing and CSS selection
|
|
21
21
|
- `xee-xpath` v0.1.5 - XPath support
|
|
22
|
-
- `
|
|
23
|
-
- `pyo3
|
|
22
|
+
- `html5ever` v0.39.0 - parse-tree dictionary helpers
|
|
23
|
+
- `pyo3` v0.28.3 with `abi3-py310`; the `extension-module` feature is enabled through the package build config
|
|
24
|
+
- `pyo3-async-runtimes` v0.28 with `tokio-runtime` feature
|
|
24
25
|
- `tokio` v1 (rt, macros) for async wrappers
|
|
25
26
|
- **Python** 3.10+
|
|
26
27
|
- Type annotations and stub files (`scraper_rs.pyi`, `py.typed`)
|
|
@@ -40,13 +41,25 @@ This file contains essential information for Large Language Models (LLMs) to eff
|
|
|
40
41
|
```
|
|
41
42
|
scraper-rs/
|
|
42
43
|
├── src/
|
|
43
|
-
│
|
|
44
|
+
│ ├── lib.rs # PyO3 module entry point
|
|
45
|
+
│ ├── document.rs # Document class
|
|
46
|
+
│ ├── element.rs # Element class and snapshots
|
|
47
|
+
│ ├── functions.rs # Top-level functions
|
|
48
|
+
│ ├── selectors.rs # CSS selector helpers/cache
|
|
49
|
+
│ ├── xpath.rs # XPath helpers/cache
|
|
50
|
+
│ ├── limits.rs # Size limits and truncation
|
|
51
|
+
│ ├── prettify.rs # Pretty-print helpers
|
|
52
|
+
│ ├── html5_dict.rs # parse_document/parse_fragment dictionaries
|
|
53
|
+
│ └── async_core.rs # Extension-level async core helpers
|
|
44
54
|
├── tests/
|
|
45
55
|
│ ├── test_scraper.py # Synchronous API tests
|
|
46
|
-
│
|
|
56
|
+
│ ├── test_asyncio.py # Asynchronous API tests
|
|
57
|
+
│ └── test_performance.py # Performance behavior tests
|
|
47
58
|
├── examples/
|
|
48
59
|
│ ├── demo.py # Sync usage examples
|
|
49
|
-
│
|
|
60
|
+
│ ├── demo_asyncio.py # Async usage examples
|
|
61
|
+
│ ├── demo_async_document.py
|
|
62
|
+
│ └── demo_prettify_url.py
|
|
50
63
|
├── scraper_rs/ # Python package directory (async wrappers + import glue)
|
|
51
64
|
├── scraper_rs.pyi # Type stub file
|
|
52
65
|
├── py.typed # PEP 561 marker for type support
|
|
@@ -59,18 +72,17 @@ scraper-rs/
|
|
|
59
72
|
|
|
60
73
|
### Key Files
|
|
61
74
|
|
|
62
|
-
- **`src/lib.rs`**:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
- Truncation support (`truncate_on_limit` parameter)
|
|
75
|
+
- **`src/lib.rs`**: PyO3 module initializer that registers classes, helper functions, metadata, and extension-level async helpers
|
|
76
|
+
- **`src/document.rs`**: `Document` class and persistent DOM/XPath state
|
|
77
|
+
- **`src/element.rs`**: `Element` class, owned element snapshots, lazy field computation
|
|
78
|
+
- **`src/functions.rs`**: Top-level helpers: `parse()`, `parse_document()`, `parse_fragment()`, `prettify()`, `select()`, `select_first()`, `first()`, `xpath()`, `xpath_first()`
|
|
79
|
+
- **`src/selectors.rs`**, **`src/xpath.rs`**, **`src/limits.rs`**: selector caches, XPath conversion, size limit enforcement, and UTF-8-safe truncation
|
|
68
80
|
|
|
69
81
|
- **`scraper_rs.pyi`**: Type stubs for IDE support and type checking
|
|
70
82
|
|
|
71
83
|
- **`Cargo.toml`**: Rust crate configuration
|
|
72
84
|
- `crate-type = ["cdylib"]` for Python extension module
|
|
73
|
-
- Release optimizations: LTO, `codegen-units = 1`, `opt-level = "
|
|
85
|
+
- Release optimizations: fat LTO, `codegen-units = 1`, `opt-level = 3`, `panic = "abort"`, `strip = true`
|
|
74
86
|
|
|
75
87
|
- **`pyproject.toml`**: Python package metadata and build configuration
|
|
76
88
|
- Maturin build backend
|
|
@@ -170,7 +182,7 @@ pytest tests/ -v
|
|
|
170
182
|
### CI/CD
|
|
171
183
|
- **GitHub Actions**: `.github/workflows/tests.yml`
|
|
172
184
|
- Runs on Ubuntu latest
|
|
173
|
-
- Tests against Python 3.10, 3.11, 3.12, 3.13, 3.14
|
|
185
|
+
- Tests against Python 3.10, 3.11, 3.12, 3.13, 3.13t, 3.14, 3.14t
|
|
174
186
|
- Steps: checkout → setup Python/Rust → install deps → build with maturin → run pytest
|
|
175
187
|
|
|
176
188
|
## API Design
|
|
@@ -201,6 +213,9 @@ pytest tests/ -v
|
|
|
201
213
|
|
|
202
214
|
### Top-Level Functions
|
|
203
215
|
- `parse(html, max_size_bytes, truncate_on_limit) -> Document`
|
|
216
|
+
- `parse_document(html, max_size_bytes, truncate_on_limit) -> dict`
|
|
217
|
+
- `parse_fragment(html, max_size_bytes, truncate_on_limit) -> dict`
|
|
218
|
+
- `prettify(html, max_size_bytes, truncate_on_limit) -> str`
|
|
204
219
|
- `select(html, css, max_size_bytes, truncate_on_limit) -> list[Element]`
|
|
205
220
|
- `select_first(html, css, max_size_bytes, truncate_on_limit) -> Element | None`
|
|
206
221
|
- `first(html, css, max_size_bytes, truncate_on_limit) -> Element | None`
|
|
@@ -211,12 +226,12 @@ pytest tests/ -v
|
|
|
211
226
|
Module: `scraper_rs.asyncio`
|
|
212
227
|
- `AsyncDocument` and `AsyncElement` wrappers mirror the sync API
|
|
213
228
|
- `parse()` yields to the event loop once before constructing the document
|
|
214
|
-
- `
|
|
229
|
+
- The public `scraper_rs.asyncio` Python wrappers yield once and then call the sync helpers. They provide coroutine API consistency, but do not make CPU-bound parsing parallel on their own.
|
|
215
230
|
- Same keyword arguments as sync versions
|
|
216
231
|
|
|
217
232
|
## Code Conventions
|
|
218
233
|
|
|
219
|
-
### Rust Code (`src
|
|
234
|
+
### Rust Code (`src/`)
|
|
220
235
|
- Use `#[pyclass]` for Python-exposed classes
|
|
221
236
|
- Use `#[pymethods]` for Python-exposed methods
|
|
222
237
|
- Use `#[getter]` for property accessors
|
|
@@ -242,7 +257,7 @@ Module: `scraper_rs.asyncio`
|
|
|
242
257
|
## Common Development Tasks
|
|
243
258
|
|
|
244
259
|
### Adding a New Method to Document
|
|
245
|
-
1. Add Rust implementation in `src/
|
|
260
|
+
1. Add Rust implementation in `src/document.rs` under `impl Document`
|
|
246
261
|
2. Add `#[pymethods]` annotation if needed
|
|
247
262
|
3. Update `scraper_rs.pyi` with type signature
|
|
248
263
|
4. Add tests in `tests/test_scraper.py`
|
|
@@ -252,7 +267,7 @@ Module: `scraper_rs.asyncio`
|
|
|
252
267
|
8. Run `pytest tests/` to verify
|
|
253
268
|
|
|
254
269
|
### Adding a New Top-Level Function
|
|
255
|
-
1. Add Rust function in `src/
|
|
270
|
+
1. Add Rust function in `src/functions.rs` with `#[pyfunction]`
|
|
256
271
|
2. Register with `m.add_function(wrap_pyfunction!(function_name, m)?)?` in `scraper_rs` module
|
|
257
272
|
3. Export in `__all__` if applicable
|
|
258
273
|
4. Update `scraper_rs.pyi`
|
|
@@ -270,7 +285,8 @@ Module: `scraper_rs.asyncio`
|
|
|
270
285
|
### Release Process
|
|
271
286
|
See `.github/workflows/release.yml` and `.github/workflows/bump-version.yml`
|
|
272
287
|
- Version is specified in both `Cargo.toml` and `pyproject.toml` (must match)
|
|
273
|
-
-
|
|
288
|
+
- Release workflow builds abi3 wheels for Linux, Windows, and macOS, plus free-threaded wheels for Python 3.13t and 3.14t
|
|
289
|
+
- Local manylinux builds are available via Docker with `just build_manylinux`
|
|
274
290
|
- Published to PyPI via `maturin publish`
|
|
275
291
|
|
|
276
292
|
## Important Notes for LLMs
|
|
@@ -279,8 +295,8 @@ See `.github/workflows/release.yml` and `.github/workflows/bump-version.yml`
|
|
|
279
295
|
2. **PyO3 limitations**: Not all Rust types can cross the FFI boundary - use owned data
|
|
280
296
|
3. **Size limits**: Always respect `max_size_bytes` to prevent memory issues
|
|
281
297
|
4. **UTF-8 safety**: Truncation must respect character boundaries
|
|
282
|
-
5. **Async wrappers**:
|
|
283
|
-
6. **
|
|
298
|
+
5. **Async wrappers**: Public async wrappers live in `scraper_rs/asyncio.py`; keep their stubs and tests aligned with sync behavior
|
|
299
|
+
6. **Rust modules are split by responsibility**: `src/lib.rs` is the module entry point; add core behavior to the focused module that owns it
|
|
284
300
|
7. **Type stubs are critical**: Always update `scraper_rs.pyi` when changing APIs
|
|
285
301
|
8. **Tests are comprehensive**: Follow existing test patterns in `tests/`
|
|
286
302
|
9. **Build artifacts**: `target/` and `.venv/` should not be committed
|
|
@@ -289,11 +305,12 @@ See `.github/workflows/release.yml` and `.github/workflows/bump-version.yml`
|
|
|
289
305
|
## Dependencies
|
|
290
306
|
|
|
291
307
|
### Rust Dependencies (Cargo.toml)
|
|
292
|
-
- `pyo3 = { version = "0.
|
|
293
|
-
- `pyo3-async-runtimes = { version = "0.
|
|
308
|
+
- `pyo3 = { version = "0.28.3", features = ["abi3-py310"] }`
|
|
309
|
+
- `pyo3-async-runtimes = { version = "0.28", features = ["tokio-runtime"] }`
|
|
294
310
|
- `tokio = { version = "1", features = ["rt", "macros"] }`
|
|
295
|
-
- `scraper = "0.
|
|
311
|
+
- `scraper = { version = "0.27.0", git = "https://github.com/rust-scraper/scraper", features = ["atomic"], rev = "9c1eff304e45a8bccb463968268ce6758703e821" }`
|
|
296
312
|
- `xee-xpath = "0.1.5"`
|
|
313
|
+
- `html5ever = "0.39.0"`
|
|
297
314
|
|
|
298
315
|
### Python Dependencies (pyproject.toml)
|
|
299
316
|
**Runtime**: None (self-contained binary wheel)
|