You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

fetch_webpage.py 3.1 kB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. from typing import Dict, Optional
  2. from urllib.parse import urljoin
  3. import html2text
  4. import httpx
  5. from autogen_core.code_executor import ImportFromModule
  6. from autogen_core.tools import FunctionTool
  7. from bs4 import BeautifulSoup
  8. async def fetch_webpage(
  9. url: str, include_images: bool = True, max_length: Optional[int] = None, headers: Optional[Dict[str, str]] = None
  10. ) -> str:
  11. """Fetch a webpage and convert it to markdown format.
  12. Args:
  13. url: The URL of the webpage to fetch
  14. include_images: Whether to include image references in the markdown
  15. max_length: Maximum length of the output markdown (if None, no limit)
  16. headers: Optional HTTP headers for the request
  17. Returns:
  18. str: Markdown version of the webpage content
  19. Raises:
  20. ValueError: If the URL is invalid or the page can't be fetched
  21. """
  22. # Use default headers if none provided
  23. if headers is None:
  24. headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"}
  25. try:
  26. # Fetch the webpage
  27. async with httpx.AsyncClient() as client:
  28. response = await client.get(url, headers=headers, timeout=10)
  29. response.raise_for_status()
  30. # Parse HTML
  31. soup = BeautifulSoup(response.text, "html.parser")
  32. # Remove script and style elements
  33. for script in soup(["script", "style"]):
  34. script.decompose()
  35. # Convert relative URLs to absolute
  36. for tag in soup.find_all(["a", "img"]):
  37. if tag.get("href"):
  38. tag["href"] = urljoin(url, tag["href"])
  39. if tag.get("src"):
  40. tag["src"] = urljoin(url, tag["src"])
  41. # Configure HTML to Markdown converter
  42. h2t = html2text.HTML2Text()
  43. h2t.body_width = 0 # No line wrapping
  44. h2t.ignore_images = not include_images
  45. h2t.ignore_emphasis = False
  46. h2t.ignore_links = False
  47. h2t.ignore_tables = False
  48. # Convert to markdown
  49. markdown = h2t.handle(str(soup))
  50. # Trim if max_length is specified
  51. if max_length and len(markdown) > max_length:
  52. markdown = markdown[:max_length] + "\n...(truncated)"
  53. return markdown.strip()
  54. except httpx.RequestError as e:
  55. raise ValueError(f"Failed to fetch webpage: {str(e)}") from e
  56. except Exception as e:
  57. raise ValueError(f"Error processing webpage: {str(e)}") from e
  58. # Create the webpage fetching tool
  59. fetch_webpage_tool = FunctionTool(
  60. func=fetch_webpage,
  61. description="Fetch a webpage and convert it to markdown format, with options for including images and limiting length",
  62. global_imports=[
  63. "os",
  64. "html2text",
  65. ImportFromModule("typing", ("Optional", "Dict")),
  66. "httpx",
  67. ImportFromModule("bs4", ("BeautifulSoup",)),
  68. ImportFromModule("html2text", ("HTML2Text",)),
  69. ImportFromModule("urllib.parse", ("urljoin",)),
  70. ],
  71. )