Data Processing Pipeline
Omnivore's data processing pipeline transforms raw web content into structured, analyzable data. From HTML parsing to entity extraction, each stage is optimized for performance and accuracy.
HTML Parsing
Fast, accurate HTML parsing with content extraction
Content Cleaning
Remove noise, ads, and extract main content
Enrichment
Add metadata, classify content, extract entities
Processing Pipeline Overview
Pipeline Stages
The processing pipeline consists of sequential stages, each optimized for specific tasks:
1. Raw Content Ingestion
Receive HTML, PDF, or text content from crawler
2. Content Parsing
Parse HTML structure, extract text and metadata
3. Content Cleaning
Remove boilerplate, ads, navigation elements
4. Text Processing
Normalize text, language detection, encoding fixes
5. Metadata Extraction
Extract title, author, dates, tags, categories
6. Content Enrichment
Entity extraction, classification, sentiment analysis
7. Storage & Indexing
Store processed data, create search indexes
HTML Parsing
Parser Configuration
TOML001[processing.parser]002# Parser engine003engine = "html5ever" # Fast HTML5 parser004005# Parsing options006fix_errors = true007remove_scripts = true008remove_styles = true009decode_entities = true010011# Content extraction012extract_text = true013extract_links = true014extract_images = true015extract_metadata = true016017# Performance018max_parse_size = 10485760 # 10MB019timeout = 5000 # 5 seconds
Structured Data Extraction
Extract structured data from HTML using various methods:
RUST001// Extract structured data002let extractor = DataExtractor::new()003 .extract_json_ld() // JSON-LD structured data004 .extract_microdata() // Schema.org microdata005 .extract_rdfa() // RDFa annotations006 .extract_opengraph() // Open Graph metadata007 .extract_twitter_card() // Twitter Card data008 .build();009010let structured_data = extractor.extract(&html)?;
Content Cleaning
Boilerplate Removal
Omnivore uses advanced algorithms to identify and remove non-content elements:
- Navigation menus: Header and footer navigation
- Advertisements: Ad blocks and promotional content
- Sidebars: Related articles, widgets, social media
- Comments: User comments and discussion threads
TOML001[processing.cleaning]002# Cleaning algorithms003algorithm = "readability" # or "boilerpipe", "custom"004005# Content detection006min_text_length = 100007min_word_count = 50008max_link_density = 0.3009010# Element removal011remove_elements = ["script", "style", "iframe", "embed"]012remove_classes = ["advertisement", "sidebar", "footer", "header"]013remove_ids = ["comments", "related-posts", "social-share"]014015# Text cleaning016normalize_whitespace = true017remove_empty_lines = true018fix_encoding = true
Main Content Extraction
BASH001# Extract main content from HTML002omnivore process extract-content page.html --output content.txt003004# With custom rules005omnivore process extract-content page.html \006 --algorithm readability \007 --min-words 100 \008 --output content.txt009010# Batch processing011omnivore process extract-content ./html-files/ \012 --output-dir ./clean-content/ \013 --workers 10
Text Processing
Text Normalization
TOML001[processing.text]002# Language detection003detect_language = true004supported_languages = ["en", "es", "fr", "de", "zh"]005006# Text normalization007lowercase = false # Preserve case for NER008remove_accents = false009expand_contractions = true010fix_unicode = true011012# Tokenization013tokenizer = "spacy" # or "nltk", "custom"014preserve_entities = true015preserve_urls = true016preserve_emails = true
Language Processing
RUST001use omnivore::processing::{LanguageDetector, TextProcessor};002003// Detect language004let detector = LanguageDetector::new();005let language = detector.detect(&text)?;006007// Process text based on language008let processor = TextProcessor::for_language(language);009let processed = processor010 .tokenize()011 .lemmatize()012 .remove_stopwords()013 .process(&text)?;
Metadata Extraction
Automatic Metadata Detection
Omnivore automatically extracts various types of metadata:
Document Metadata
- Title and headings
- Author and publication date
- Description and keywords
- Language and encoding
- Document type and format
Technical Metadata
- URL and domain
- Content-Type and size
- Last modified date
- HTTP headers
- Response codes
Metadata Extraction Rules
JSON001{002 "metadata_rules": {003 "title": [004 {"selector": "title"},005 {"selector": "meta[property='og:title']", "attribute": "content"},006 {"selector": "h1", "first": true}007 ],008 "author": [009 {"selector": "meta[name='author']", "attribute": "content"},010 {"selector": ".author-name"},011 {"pattern": "By ([A-Z][a-z]+ [A-Z][a-z]+)"}012 ],013 "date": [014 {"selector": "meta[property='article:published_time']", "attribute": "content"},015 {"selector": "time", "attribute": "datetime"},016 {"pattern": "\d{4}-\d{2}-\d{2}"}017 ],018 "category": [019 {"selector": "meta[property='article:section']", "attribute": "content"},020 {"selector": ".category"},021 {"xpath": "//nav[@class='breadcrumb']/a[last()]"}022 ]023 }024}
Content Enrichment
Entity Recognition
BASH001# Extract entities from text002omnivore process extract-entities content.txt \003 --types person,org,location \004 --output entities.json005006# With confidence threshold007omnivore process extract-entities content.txt \008 --min-confidence 0.8 \009 --output entities.json010011# Custom NER model012omnivore process extract-entities content.txt \013 --model custom-ner-model.bin \014 --output entities.json
Content Classification
TOML001[processing.classification]002# Classification model003model = "fasttext" # or "bert", "custom"004model_path = "./models/classifier.bin"005006# Categories007categories = [008 "technology",009 "business",010 "science",011 "health",012 "sports",013 "entertainment"014]015016# Classification settings017min_confidence = 0.7018multi_label = true019max_categories = 3
Sentiment Analysis
BASH001# Analyze sentiment002omnivore process analyze-sentiment content.txt003004# Output:005# Overall: Positive (0.78)006# Polarity: 0.65007# Subjectivity: 0.42008# Emotions: joy (0.45), trust (0.32)
Processing Pipelines
Custom Pipeline Configuration
YAML001# pipeline.yaml002name: news-processing003description: Pipeline for news article processing004005stages:006 - name: parse007 type: html_parser008 config:009 engine: html5ever010 extract_metadata: true011012 - name: clean013 type: content_cleaner014 config:015 algorithm: readability016 min_words: 100017018 - name: extract_entities019 type: ner020 config:021 model: en_core_web_lg022 types: [person, org, location]023024 - name: classify025 type: classifier026 config:027 model: news-classifier028 categories: [politics, tech, business]029030 - name: summarize031 type: summarizer032 config:033 algorithm: extractive034 sentences: 3035036 - name: store037 type: storage038 config:039 backend: elasticsearch040 index: news-articles
Pipeline Execution
BASH001# Run custom pipeline002omnivore process run-pipeline pipeline.yaml \003 --input crawled-data.json \004 --output processed-data.json005006# Run with monitoring007omnivore process run-pipeline pipeline.yaml \008 --input crawled-data.json \009 --output processed-data.json \010 --monitor \011 --metrics-port 9090
Storage & Indexing
Storage Backends
TOML001[processing.storage]002# Primary storage003backend = "postgresql" # or "mongodb", "elasticsearch", "rocksdb"004connection_string = "postgres://user:pass@localhost/omnivore"005006# Batch settings007batch_size = 1000008flush_interval = 5000 # ms009010# Compression011compress = true012compression_algorithm = "zstd"013014# Indexing015create_indexes = true016index_fields = ["title", "content", "url", "domain"]017018# Full-text search019enable_fts = true020fts_language = "english"
Search Index Creation
BASH001# Create search index002omnivore index create processed-data.json \003 --backend elasticsearch \004 --index omnivore-content005006# With custom mapping007omnivore index create processed-data.json \008 --backend elasticsearch \009 --index omnivore-content \010 --mapping custom-mapping.json011012# Update existing index013omnivore index update omnivore-content \014 --add-documents new-data.json
Batch Processing
Large-Scale Processing
BASH001# Process large dataset in batches002omnivore process batch \003 --input s3://bucket/crawled-data/ \004 --output s3://bucket/processed-data/ \005 --batch-size 10000 \006 --workers 20 \007 --checkpoint ./checkpoints/008009# Resume from checkpoint010omnivore process batch \011 --resume ./checkpoints/batch-12345.json \012 --output s3://bucket/processed-data/
Stream Processing
BASH001# Process streaming data002omnivore process stream \003 --input kafka://localhost:9092/crawled-pages \004 --output kafka://localhost:9092/processed-pages \005 --pipeline news-pipeline.yaml \006 --workers 10
Quality Control
Data Validation
TOML001[processing.validation]002# Validation rules003validate_required_fields = ["title", "content", "url"]004min_content_length = 100005max_content_length = 1000000006007# Quality checks008check_language = true009expected_language = "en"010check_encoding = true011check_duplicates = true012013# Rejection criteria014reject_on_error = false015log_rejected = true016rejected_output = "./rejected.json"
Processing Metrics
BASH001# View processing statistics002omnivore process stats003004# Output:005# Documents processed: 45,231006# Success rate: 98.5%007# Average processing time: 125ms008# Entities extracted: 234,521009# Categories assigned: 89.3%010# Errors: 679 (1.5%)
Performance Optimization
Optimization Strategies
- Parallel Processing: Use multiple workers for CPU-bound tasks
- Caching: Cache parsed HTML and extracted entities
- Batch Operations: Process documents in batches
- Lazy Loading: Load models on-demand
- GPU Acceleration: Use GPU for NLP models when available
TOML001[processing.performance]002# Parallel processing003workers = 16004thread_pool_size = 32005006# Caching007enable_cache = true008cache_backend = "redis"009cache_ttl = 3600010011# Memory management012max_memory = "8GB"013gc_interval = 1000014015# GPU settings016use_gpu = true017gpu_device = 0018gpu_batch_size = 32
Error Handling
Error Recovery
BASH001# Process with error handling002omnivore process run \003 --input data.json \004 --output processed.json \005 --on-error continue \006 --error-log errors.log \007 --max-errors 100008009# Retry failed documents010omnivore process retry \011 --failed errors.log \012 --output retry-processed.json \013 --max-retries 3
Best Practices
- Validate input data before processing
- Use appropriate algorithms for content type
- Set reasonable timeouts for each stage
- Monitor memory usage with large documents
- Implement checkpointing for long-running jobs
- Log processing metrics for optimization
- Test pipelines with sample data first