from urllib.parse import parse_qs, unquote, urlparse import requests from bs4 import BeautifulSoup from config import REQUEST_HEADERS from tools.common import truncate_text def clean_html_text(raw_html: str) -> str: soup = BeautifulSoup(raw_html, "html.parser") for tag in soup(["script", "style", "noscript", "svg", "nav", "footer"]): tag.decompose() title = soup.title.string.strip() if soup.title and soup.title.string else "" text = soup.get_text("\n") lines = [line.strip() for line in text.splitlines() if line.strip()] compact_text = "\n".join(lines) if title: return f"标题:{title}\n正文:\n{compact_text}" return compact_text def fetch_url_text(url: str, limit: int = 8000) -> str: try: response = requests.get(url, headers=REQUEST_HEADERS, timeout=25) response.raise_for_status() content_type = response.headers.get("content-type", "") if "text/html" in content_type or " str: parsed = urlparse(href) query = parse_qs(parsed.query) if "uddg" in query: return unquote(query["uddg"][0]) return href def search_web(query: str, max_results: int = 5) -> list[dict[str, str]]: try: response = requests.get( "https://duckduckgo.com/html/", params={"q": query}, headers=REQUEST_HEADERS, timeout=25, ) response.raise_for_status() soup = BeautifulSoup(response.text, "html.parser") results = [] for anchor in soup.select("a.result__a"): title = anchor.get_text(" ", strip=True) href = decode_duckduckgo_href(anchor.get("href", "")) if title and href.startswith("http"): results.append({"title": title, "url": href}) if len(results) >= max_results: break return results except Exception as exc: print(f"搜索失败:{exc}") return [] def collect_web_evidence(question: str, limit: int = 10000) -> str: search_results = search_web(question) if not search_results: return "网页搜索没有返回可用结果。" evidence_parts = ["网页搜索结果:"] for index, result in enumerate(search_results, start=1): evidence_parts.append(f"{index}. {result['title']} - {result['url']}") for result in search_results[:3]: page_text = fetch_url_text(result["url"], limit=3500) evidence_parts.append( f"\n--- 网页内容:{result['title']} ({result['url']}) ---\n{page_text}" ) return truncate_text("\n".join(evidence_parts), limit)