https://github.com/xcrap-dev/xcrap-python
A modern, declarative, and modular web scraping framework for Python.
https://github.com/xcrap-dev/xcrap-python
alternative declarative framework modular python scraping scrapy web
Last synced: about 17 hours ago
JSON representation
A modern, declarative, and modular web scraping framework for Python.
- Host: GitHub
- URL: https://github.com/xcrap-dev/xcrap-python
- Owner: xcrap-dev
- Created: 2026-02-23T07:20:47.000Z (4 months ago)
- Default Branch: master
- Last Pushed: 2026-04-13T11:55:51.000Z (3 months ago)
- Last Synced: 2026-06-24T01:33:41.864Z (5 days ago)
- Topics: alternative, declarative, framework, modular, python, scraping, scrapy, web
- Language: Python
- Homepage: https://pypi.org/project/xcrap/
- Size: 372 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Xcrap for Python
Xcrap é um framework originalmente feito para Node.js, mas, digamos que eu também sou um desenvolvedor Python e, estava um pouco entediado; por isso, resolvi fazer uma versão para Python.
Ainda está em fase experimental, mas já conta com funcionalidades poderosas portadas da versão original em TypeScript, garantindo paridade entre os ecossistemas.
## 🚀 Como funciona
A ideia é ser declarativo e fácil. Veja um exemplo de como você já pode usar o `xcrap` para extrair dados estruturados:
```python
from xcrap.extractor import HtmlExtractionModel, HtmlBaseField, HtmlNestedField, css
from xcrap.clients import HttpxClient
import asyncio
# 1. Defina seus modelos de forma declarativa
class AuthorModel(HtmlExtractionModel):
name = HtmlBaseField(query=css("small.author::text"))
link = HtmlBaseField(query=css("a::attr(href)"))
class QuoteModel(HtmlExtractionModel):
text = HtmlBaseField(query=css("span.text::text"))
# Modelos aninhados sem esforço!
author = HtmlNestedField(model=AuthorModel)
tags = HtmlBaseField(query=css("div.tags a.tag::text"), multiple=True)
class QuotesPageModel(HtmlExtractionModel):
quotes = HtmlNestedField(query=css("div.quote"), model=QuoteModel, multiple=True)
async def main():
client = HttpxClient()
# 2. Busque a página
response = await client.fetch(url="http://quotes.toscrape.com")
# 3. Transforme em um parser e extraia os dados
parser = response.as_html_parser()
data = parser.extract_model(QuotesPageModel)
for quote in data["quotes"][:3]:
print(f"Quote: {quote['text']}")
print(f"Author: {quote['author']['name']}")
if __name__ == "__main__":
asyncio.run(main())
```
## ✨ Funcionalidades Principais
### 🔒 Descriptografia Automática
Suporte integrado para descriptografar respostas HTTP (AES-CBC/ECB).
```python
from xcrap.core import decrypt_client
from xcrap.utils.decryption import DecryptConfig, DecryptKeyConfig
config = DecryptConfig(
algorithm="aes-256-cbc",
key=DecryptKeyConfig(value="sua-chave-aqui"),
iv=DecryptKeyConfig(value="seu-iv-aqui")
)
@decrypt_client(config)
class MySecureClient(HttpxClient):
pass
# Todas as respostas deste cliente agora virão descriptografadas!
```
### 🏭 Sistema de Factories
O sistema de Factory permite a criação dinâmica de componentes a partir de arquivos de configuração (JSON/Dict), facilitando a manutenção de bots sem alteração de código.
#### 1. Model Factory
Constrói modelos complexos de forma recursiva:
```python
from xcrap.factory import create_extraction_model
from xcrap.extractor import HtmlExtractionModel
config = {
"type": "html",
"model": {
"title": {"query": {"type": "css", "value": "h1::text"}},
"items": {
"query": {"type": "css", "value": "li"},
"multiple": true,
"nested": {
"type": "html",
"model": {"name": {"query": {"type": "css", "value": "span::text"}}}
}
}
}
}
model = create_extraction_model(config, allowed_models={"html": HtmlExtractionModel})
```
#### 2. Client Factory
Instancia clientes com configurações específicas:
```python
from xcrap.factory import create_client
from xcrap.clients import HttpxClient
client = create_client(
client_type="httpx",
allowed_clients={"httpx": HttpxClient},
options={"user_agent": "CustomAgent", "proxy_url": "http://..."}
)
```
#### 3. Extractor Factory
Cria extratores a partir de strings, suportando argumentos:
```python
from xcrap.factory import create_extractor
# 'attr:src' chamará o gerador 'attr' com o argumento 'src'
get_src = create_extractor("attr:src", allowed_extractors={"attr": lambda a: lambda el: el.attrib.get(a)})
```
### 🛠️ Extratores Customizados
Você pode passar funções customizadas para processar campos individualmente:
```python
class MyModel(HtmlExtractionModel):
# 'extractor' permite transformar o dado logo após a captura
price = HtmlBaseField(
query=css(".price::text"),
extractor=lambda text: float(text.replace("$", ""))
)
```
### 📊 Extração de JSON (JMESPath)
Também suportamos extração de JSON usando JMESPath:
```python
from xcrap.extractor import JsonExtractionModel, JsonBaseField, jmes_path, JsonParser
class ProjectModel(JsonExtractionModel):
name = JsonBaseField(query=jmes_path("title"))
tags = JsonBaseField(query=jmes_path("tags"), multiple=True)
content = '{"title": "Xcrap", "tags": ["python", "scraping"]}'
parser = JsonParser(content)
data = parser.extract_model(ProjectModel) # {'name': 'Xcrap', 'tags': ['python', 'scraping']}
```
## 🛠️ Desenvolvimento
Para rodar os testes e verificar a cobertura:
```bash
poetry run pytest --cov=xcrap --cov-report=term-missing
```
Atualmente o projeto conta com **100% de cobertura de código**, garantindo a confiabilidade de todas as funcionalidades.
---
Feito com ❤️ por Marcuth