CoolFace
Apppublic

npmaker/Final_Assignment

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
selenium_wiki_tool.py161 linesDownload Raw Back to root
1from selenium import webdriver2from selenium.webdriver.firefox.options import Options3from selenium.webdriver.firefox.service import Service4from webdriver_manager.firefox import GeckoDriverManager5from selenium.webdriver.common.by import By6from selenium.webdriver.support.ui import WebDriverWait7from selenium.webdriver.support import expected_conditions as EC8import time9import re10from smolagents import Tool11import json12 13class WikipediaSeleniumTool(Tool):14    name = "wikipediaSeleniumTool"15    #description = "Tool that uses Selenium with Firefox to scrape Wikipedia pages efficiently."16    description = """17        This tool extracts content from Wikipedia pages using Selenium with Firefox.18        It's optimized for token efficiency and works well for parsing Wikipedia articles.19        Input should be a task containing a Wikipedia URL (e.g., 'Extract information from https://en.wikipedia.org/wiki/Artificial_intelligence').20        """21    inputs = {22        'task': {23            'type': 'string',24            'description': 'A task description that includes a Wikipedia URL'25        }26    }27    output_type = "string"28    is_initialized = False29 30    def __init__(self):31        """Initialize the Wikipedia Selenium Tool.32        """33        self.max_output_length = 100000034        self.headless = True35        36    def _setup_driver(self):37        """Set up and return a Firefox WebDriver."""38        print("setup driver")39        options = Options()40        if self.headless:41            options.add_argument('--headless')42        43        # Add more options for stability in containerized environments44        options.add_argument('--width=1920')45        options.add_argument('--height=1080')46        47        # Use GeckoDriverManager to automatically handle the driver48        service = Service(GeckoDriverManager().install())49        return webdriver.Firefox(service=service, options=options)50    51    def _is_wikipedia_url(self, url):52        """Check if the URL is a Wikipedia URL."""53        return bool(re.match(r'^https?://([\w-]+\.)?wikipedia\.org', url))54    55    def _extract_wikipedia_content(self, driver):56        """Extract content from Wikipedia page, focusing on the main content area."""57        print("_extract_wikipedia_content")58        try:59            # Wait for the content to load60            WebDriverWait(driver, 10).until(61                EC.presence_of_element_located((By.ID, "content"))62            )63            64            # Get the main content area65            content_div = driver.find_element(By.ID, "mw-content-text")66            67            # Extract title68            title_element = driver.find_element(By.ID, "firstHeading")69            title = title_element.text if title_element else "Unknown Title"70            71            # Extract only the paragraphs and headings from the content72            paragraphs = content_div.find_elements(By.TAG_NAME, "p")73            #print(f"paragraphs: {paragraphs}")74            headings = content_div.find_elements(By.XPATH, ".//h2|.//h3|.//h4|.//h5|.//h6")75            #print(f"headings: {headings}")76            #tr = content_div.find_elements(By.TAG_NAME,"tr")77            td = content_div.find_elements(By.TAG_NAME,"td")78            #print(f"tables: {td}")79            80            # Combine all texts81            text_parts = [f"# {title}\n\n"]82            83            # Process headings and paragraphs84            all_elements = []85            for heading in headings:86                all_elements.append({"type": "heading", "element": heading, "position": heading.location['y']})87            for para in paragraphs:88                if para.text.strip():  # Only include non-empty paragraphs89                    all_elements.append({"type": "paragraph", "element": para, "position": para.location['y']})90            for td in td:91                all_elements.append({"type": "td", "element": td, "position": td.location['y']})92            93            # Sort elements by their Y position94            all_elements.sort(key=lambda x: x["position"])95            96            # Extract and format text97            for item in all_elements:98                if item["type"] == "heading":99                    level = item["element"].tag_name[1]  # Get the heading level (2-6)100                    heading_text = item["element"].text.strip()101                    if heading_text and not heading_text.lower() == "contents":102                        text_parts.append(f"\n{'#' * int(level)} {heading_text}\n")103                elif item["type"] == "td":104                    td_text = re.sub('<[^<]+?>', '', item["element"].text)105                    if td_text:106                        text_parts.append(f"{td_text}\n")107                else:  # paragraph108                    para_text = item["element"].text.strip()109                    if para_text:110                        text_parts.append(f"{para_text}\n\n")111            112            full_content = "".join(text_parts)113            print(f"full_content: {full_content}")114            # Truncate if necessary115            if len(full_content) > self.max_output_length:116                full_content = full_content[:self.max_output_length] + "...[content truncated]"117                118            return full_content119        120        except Exception as e:121            return f"Error extracting Wikipedia content: {str(e)}"122    123    def forward(self, task) -> str:124        """Process Wikipedia URLs to extract content in a token-efficient way.125        126        Args:127            task: A task description that includes a Wikipedia URL128        129        Returns:130            The extracted content from the Wikipedia page131        """132        print("extract url from task")133        # Extract URL from task134        url_match = re.search(r'https?://[^\s"\'<>]+', task)135        if not url_match:136            return "No URL found in the task. Please provide a Wikipedia URL."137        138        url = url_match.group(0)139        140        # Check if it's a Wikipedia URL141        if not self._is_wikipedia_url(url):142            return f"The URL {url} is not a Wikipedia URL. This tool only handles Wikipedia pages."143        144        # Set up the driver145        driver = self._setup_driver()146        147        try:148            driver.get(url)149            time.sleep(2)  # Brief pause to ensure page loads150            151            # Extract the content152            content = self._extract_wikipedia_content(driver)153            154            return content155        156        except Exception as e:157            return f"Error processing Wikipedia page: {str(e)}"158        159        finally:160            driver.quit()161