codekingpro/portable-devtools
114k
1"""ScrapingAnt Web Extractor."""2 3import logging4from typing import Iterator, List, Optional5 6from langchain_core.document_loaders import BaseLoader7from langchain_core.documents import Document8from langchain_core.utils import get_from_env9 10logger = logging.getLogger(__file__)11 12 13class ScrapingAntLoader(BaseLoader):14 """Turn an url to LLM accessible markdown with `ScrapingAnt`.15 16 For further details, visit: https://docs.scrapingant.com/python-client17 """18 19 def __init__(20 self,21 urls: List[str],22 *,23 api_key: Optional[str] = None,24 scrape_config: Optional[dict] = None,25 continue_on_failure: bool = True,26 ) -> None:27 """Initialize client.28 29 Args:30 urls: List of urls to scrape.31 api_key: The ScrapingAnt API key. If not specified must have env var32 SCRAPINGANT_API_KEY set.33 scrape_config: The scraping config from ScrapingAntClient.markdown_request34 continue_on_failure: Whether to continue if scraping an url fails.35 """36 try:37 from scrapingant_client import ScrapingAntClient38 except ImportError:39 raise ImportError(40 "`scrapingant-client` package not found,"41 " run `pip install scrapingant-client`"42 )43 if not urls:44 raise ValueError("URLs must be provided.")45 api_key = api_key or get_from_env("api_key", "SCRAPINGANT_API_KEY")46 self.client = ScrapingAntClient(token=api_key)47 self.urls = urls48 self.scrape_config = scrape_config49 self.continue_on_failure = continue_on_failure50 51 def lazy_load(self) -> Iterator[Document]:52 """Fetch data from ScrapingAnt."""53 54 scrape_config = self.scrape_config if self.scrape_config is not None else {}55 for url in self.urls:56 try:57 result = self.client.markdown_request(url=url, **scrape_config)58 yield Document(59 page_content=result.markdown,60 metadata={"url": result.url},61 )62 except Exception as e:63 if self.continue_on_failure:64 logger.error(f"Error fetching data from {url}, exception: {e}")65 else:66 raise e67 