Adding new class type TextHandlers
This commit is contained in:
@@ -3,7 +3,7 @@ from types import MappingProxyType
|
|||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
|
|
||||||
from scrapling.core.utils import _is_iterable, flatten
|
from scrapling.core.utils import _is_iterable, flatten
|
||||||
from scrapling.core._types import Dict, List, Union, Pattern
|
from scrapling.core._types import Dict, List, Union, Pattern, SupportsIndex
|
||||||
|
|
||||||
from orjson import loads, dumps
|
from orjson import loads, dumps
|
||||||
from w3lib.html import replace_entities as _replace_entities
|
from w3lib.html import replace_entities as _replace_entities
|
||||||
@@ -69,7 +69,7 @@ class TextHandler(str):
|
|||||||
return [TextHandler(_replace_entities(s)) for s in results]
|
return [TextHandler(_replace_entities(s)) for s in results]
|
||||||
|
|
||||||
def re_first(self, regex: Union[str, Pattern[str]], default=None, replace_entities: bool = True,
|
def re_first(self, regex: Union[str, Pattern[str]], default=None, replace_entities: bool = True,
|
||||||
clean_match: bool = False, case_sensitive: bool = False,):
|
clean_match: bool = False, case_sensitive: bool = False) -> Union[str, None]:
|
||||||
"""Apply the given regex to text and return the first match if found, otherwise return the default value.
|
"""Apply the given regex to text and return the first match if found, otherwise return the default value.
|
||||||
|
|
||||||
:param regex: Can be either a compiled regular expression or a string.
|
:param regex: Can be either a compiled regular expression or a string.
|
||||||
@@ -83,6 +83,51 @@ class TextHandler(str):
|
|||||||
return result[0] if result else default
|
return result[0] if result else default
|
||||||
|
|
||||||
|
|
||||||
|
class TextHandlers(List[TextHandler]):
|
||||||
|
"""
|
||||||
|
The :class:`TextHandlers` class is a subclass of the builtin ``List`` class, which provides a few additional methods.
|
||||||
|
"""
|
||||||
|
__slots__ = ()
|
||||||
|
|
||||||
|
def __getitem__(self, pos: Union[SupportsIndex, slice]) -> Union[TextHandler, "TextHandlers[TextHandler]"]:
|
||||||
|
lst = super().__getitem__(pos)
|
||||||
|
if isinstance(pos, slice):
|
||||||
|
return self.__class__(lst)
|
||||||
|
else:
|
||||||
|
return lst
|
||||||
|
|
||||||
|
def re(self, regex: Union[str, Pattern[str]], replace_entities: bool = True, clean_match: bool = False,
|
||||||
|
case_sensitive: bool = False) -> 'List[str]':
|
||||||
|
"""Call the ``.re()`` method for each element in this list and return
|
||||||
|
their results flattened as TextHandlers.
|
||||||
|
|
||||||
|
:param regex: Can be either a compiled regular expression or a string.
|
||||||
|
:param replace_entities: if enabled character entity references are replaced by their corresponding character
|
||||||
|
:param clean_match: if enabled, this will ignore all whitespaces and consecutive spaces while matching
|
||||||
|
:param case_sensitive: if enabled, function will set the regex to ignore letters case while compiling it
|
||||||
|
"""
|
||||||
|
results = [
|
||||||
|
n.re(regex, replace_entities, clean_match, case_sensitive) for n in self
|
||||||
|
]
|
||||||
|
return flatten(results)
|
||||||
|
|
||||||
|
def re_first(self, regex: Union[str, Pattern[str]], default=None, replace_entities: bool = True,
|
||||||
|
clean_match: bool = False, case_sensitive: bool = False) -> Union[str, None]:
|
||||||
|
"""Call the ``.re_first()`` method for each element in this list and return
|
||||||
|
the first result or the default value otherwise.
|
||||||
|
|
||||||
|
:param regex: Can be either a compiled regular expression or a string.
|
||||||
|
:param default: The default value to be returned if there is no match
|
||||||
|
:param replace_entities: if enabled character entity references are replaced by their corresponding character
|
||||||
|
:param clean_match: if enabled, this will ignore all whitespaces and consecutive spaces while matching
|
||||||
|
:param case_sensitive: if enabled, function will set the regex to ignore letters case while compiling it
|
||||||
|
"""
|
||||||
|
for n in self:
|
||||||
|
for result in n.re(regex, replace_entities, clean_match, case_sensitive):
|
||||||
|
return result
|
||||||
|
return default
|
||||||
|
|
||||||
|
|
||||||
class AttributesHandler(Mapping):
|
class AttributesHandler(Mapping):
|
||||||
"""A read-only mapping to use instead of the standard dictionary for the speed boost but
|
"""A read-only mapping to use instead of the standard dictionary for the speed boost but
|
||||||
at the same time I use it to add more functionalities.
|
at the same time I use it to add more functionalities.
|
||||||
|
|||||||
+3
-1
@@ -3,7 +3,7 @@ from difflib import SequenceMatcher
|
|||||||
|
|
||||||
from scrapling.core.translator import HTMLTranslator
|
from scrapling.core.translator import HTMLTranslator
|
||||||
from scrapling.core.mixins import SelectorsGeneration
|
from scrapling.core.mixins import SelectorsGeneration
|
||||||
from scrapling.core.custom_types import TextHandler, AttributesHandler
|
from scrapling.core.custom_types import TextHandler, TextHandlers, AttributesHandler
|
||||||
from scrapling.core.storage_adaptors import SQLiteStorageSystem, StorageSystemMixin, _StorageTools
|
from scrapling.core.storage_adaptors import SQLiteStorageSystem, StorageSystemMixin, _StorageTools
|
||||||
from scrapling.core.utils import setup_basic_logging, logging, clean_spaces, flatten, html_forbidden
|
from scrapling.core.utils import setup_basic_logging, logging, clean_spaces, flatten, html_forbidden
|
||||||
from scrapling.core._types import Any, Dict, List, Tuple, Optional, Pattern, Union, Callable, Generator, SupportsIndex
|
from scrapling.core._types import Any, Dict, List, Tuple, Optional, Pattern, Union, Callable, Generator, SupportsIndex
|
||||||
@@ -158,6 +158,8 @@ class Adaptor(SelectorsGeneration):
|
|||||||
results = [self.__get_correct_result(n) for n in result]
|
results = [self.__get_correct_result(n) for n in result]
|
||||||
if all(isinstance(res, self.__class__) for res in results):
|
if all(isinstance(res, self.__class__) for res in results):
|
||||||
return Adaptors(results)
|
return Adaptors(results)
|
||||||
|
elif all(isinstance(res, TextHandler) for res in results):
|
||||||
|
return TextHandlers(results)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
return self.__get_correct_result(result)
|
return self.__get_correct_result(result)
|
||||||
|
|||||||
Reference in New Issue
Block a user