# πŸ•·οΈ Scrapling: Lightning-Fast, Adaptive Web Scraping for Python [![PyPI version](https://badge.fury.io/py/scrapling.svg)](https://badge.fury.io/py/scrapling) [![Supported Python versions](https://img.shields.io/pypi/pyversions/scrapling.svg)](https://pypi.org/project/scrapling/) [![License](https://img.shields.io/badge/License-BSD--3-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) Dealing with failing web scrapers due to website changes? Meet Scrapling. Scrapling is a high-performance, intelligent web scraping library for Python that automatically adapts to website changes while significantly outperforming popular alternatives. Whether you're a beginner or an expert, Scrapling provides powerful features while maintaining simplicity. ```python from scrapling import Adaptor # Scrape data that survives website changes page = Adaptor(html, auto_match=True) products = page.css('.product', auto_save=True) # Later, even if selectors change: products = page.css('.product', auto_match=True) # Still finds them! ``` ## Key Features ### Adaptive Scraping - πŸ”„ **Smart Element Tracking**: Locate previously identified elements after website structure changes, using an intelligent similarity system and integrated storage. - 🎯 **Flexible Querying**: Use CSS selectors, XPath, text search, or regex - chain them however you want! - πŸ” **Find Similar Elements**: Automatically locate elements similar to the element you want on the page (Ex: other products like the product you found on the page). - 🧠 **Smart Content Scraping**: Extract data from multiple websites without specific selectors using its powerful features. ### Performance - πŸš€ **Lightning Fast**: Built from the ground up with performance in mind, outperforming most popular Python scraping libraries (outperforming BeautifulSoup by up to 237x in our tests). - πŸ”‹ **Memory Efficient**: Optimized data structures for minimal memory footprint. - ⚑ **Fast JSON serialization**: 10x faster JSON serialization than the standard json library with more options. ### Developing Experience - πŸ› οΈ **Powerful Navigation API**: Traverse the DOM tree easily in all directions and get the info you want (parent, ancestors, sibling, children, next/previous element, and more). - 🧬 **Rich Text Processing**: All strings have built-in methods for regex matching, cleaning, and more. All elements' attributes are read-only dictionaries that are faster than standard dictionaries with added methods. - πŸ“ **Automatic Selector Generation**: Create robust CSS/XPath selectors for any element. - πŸ”Œ **Scrapy-Compatible API**: Familiar methods and similar pseudo-elements for Scrapy users. - πŸ“˜ **Type hints**: Complete type coverage for better IDE support and fewer bugs. ## Getting Started Let's walk through a basic example that demonstrates small group of Scrapling's core features: ```python import requests from scrapling import Adaptor # Fetch a web page url = 'https://quotes.toscrape.com/' response = requests.get(url) # Create an Adaptor instance page = Adaptor(response.text, url=url) # Get all strings in the full page page.get_all_text(ignore_tags=('script', 'style')) # Get all quotes, any of these methods will return a list of strings (TextHandlers) quotes = page.css('.quote .text::text') # CSS selector quotes = page.xpath('//span[@class="text"]/text()') # XPath quotes = page.css('.quote').css('.text::text') # Chained selectors quotes = [element.text for element in page.css('.quote').css('.text')] # Slower than bulk query above # Get the first quote element quote = page.css('.quote').first # or [0] or .get() # Working with elements quote.html_content # Inner HTML quote.prettify() # Prettified version of Inner HTML quote.attrib # Element attributes quote.path # DOM path to element (List) ``` To keep it simple, all methods can be chained on top of each other as long as you are chaining methods that return an element (It's called an `Adaptor` object) or a List of Adaptors (It's called `Adaptors` object) ### Installation Scrapling is a breeze to get started with - We only require at least Python 3.6 to work and the rest of the requirements are installed automatically with the package. ```bash # Using pip pip install scrapling # Or the latest from GitHub pip install git+https://github.com/D4Vinci/Scrapling.git@master ``` ## Performance Scrapling isn't just powerful - it's also blazing fast. Scrapling implements many best practices, design patterns, and numerous optimizations to save fractions of seconds. All of that while focusing exclusively on parsing HTML documents. Here are benchmarks comparing Scrapling to popular Python libraries in two tests. ### Text Extraction Speed Test (5000 nested elements). | # | Library | Time (ms) | vs Scrapling | |---|:-----------------:|:---------:|:------------:| | 1 | Scrapling | 5.44 | 1.0x | | 2 | Parsel/Scrapy | 5.53 | 1.017x | | 3 | Raw Lxml | 6.76 | 1.243x | | 4 | PyQuery | 21.96 | 4.037x | | 5 | Selectolax | 67.12 | 12.338x | | 6 | BS4 with Lxml | 1307.03 | 240.263x | | 7 | MechanicalSoup | 1322.64 | 243.132x | | 8 | BS4 with html5lib | 3373.75 | 620.175x | As you see, Scrapling is on par with Scrapy and slightly faster than Lxml which both libraries are built on top of. These are the closest results to Scrapling. PyQuery is also built on top of Lxml but still, Scrapling is 4 times faster. ### Extraction By Text Speed Test | Library | Time (ms) | vs Scrapling | |:-----------:|:---------:|:------------:| | Scrapling | 2.51 | 1.0x | | AutoScraper | 11.41 | 4.546x | Scrapling can find elements with more methods and it returns full element `Adaptor` objects not only the text like AutoScraper. So, to make this test fair, both libraries will extract an element with text, find similar elements, and then extract the text content for all of them. As you see, Scrapling is still 4.5 times faster at same task. > All benchmarks' results are an average of 100 runs. See our [benchmarks.py](/benchmarks.py) for methodology and to run your comparisons. ## Advanced Features ### Smart Navigation ```python >>> quote.tag 'div' >>> quote.parent
...'> >>> quote.parent.tag 'div' >>> quote.children [β€œThe...' parent='
, Tags: