arxplorer / src /lib /web_scrape.py
Subhadeep Mandal
Fresh deploy
54eb2ce
Raw
History Blame Contribute Delete
3.36 kB
import asyncio
from typing import List, Optional
from fastapi import Request
from langchain_core.documents import Document
from langchain_community.document_loaders.firecrawl import (
FireCrawlLoader as BasFireCrawlLoader,
)
from firecrawl.v2.utils.error_handler import (
WebsiteNotSupportedError,
PaymentRequiredError,
BadRequestError,
UnauthorizedError,
)
from ..core.logger import SingletonLogger
from ..utils.api_key_utils import get_api_key_for_service
class FirecrawlLoader:
@staticmethod
async def _load_single(url: str, api_key: str) -> List[Document]:
logger = SingletonLogger().get_logger()
loader = BasFireCrawlLoader(
url=url,
api_key=api_key,
mode="scrape",
params={"formats": ["markdown"]},
)
try:
docs = await loader.aload()
return docs or []
except (
WebsiteNotSupportedError,
PaymentRequiredError,
BadRequestError,
UnauthorizedError,
):
logger.warning(
"Website not supported/payment required/bad request/unauthorized for URL: %s",
url,
)
return [
Document(
page_content="Website not supported/payment required/bad request/unauthorized",
metadata={"url": url},
)
]
except Exception:
logger.exception("Error while loading url with firecrawl: %s", url)
return []
@staticmethod
async def scrape(
urls: List[str],
api_key: Optional[str] = None,
request: Optional[Request] = None,
) -> List[Document]:
logger = SingletonLogger().get_logger()
try:
if not api_key and request:
api_key = get_api_key_for_service(request, "firecrawl")
if not urls:
return []
if isinstance(urls, str):
urls = [urls]
tasks = [FirecrawlLoader._load_single(url, api_key) for url in urls]
results = await asyncio.gather(*tasks)
documents: List[Document] = []
for res in results:
if res:
documents.extend(
[
Document(
page_content=doc.page_content,
metadata={
"title": doc.metadata.get("title", ""),
"description": doc.metadata.get("description", ""),
"url": doc.metadata.get("url", ""),
"image": doc.metadata.get("og_image", ""),
"favicon": doc.metadata.get("favicon", ""),
"sitename": doc.metadata.get("og:site_name", ""),
},
)
for doc in res
]
)
return documents
except Exception:
logger.exception("Error while loading urls with firecrawl: %s", urls)
return []