Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
app.py
CHANGED
@@ -40,7 +40,7 @@ def extract_keywords(text: str, top_k: int = 5) -> str:
|
|
40 |
return " ".join(key_tokens)
|
41 |
|
42 |
##############################################################################
|
43 |
-
#
|
44 |
# - 상위 20개 결과 JSON을 LLM에 넘길 때 link, snippet 등 모두 포함
|
45 |
##############################################################################
|
46 |
def do_web_search(query: str) -> str:
|
@@ -50,30 +50,62 @@ def do_web_search(query: str) -> str:
|
|
50 |
"""
|
51 |
try:
|
52 |
url = "https://api.serphouse.com/serp/live"
|
|
|
|
|
53 |
params = {
|
54 |
"q": query,
|
55 |
"domain": "google.com",
|
56 |
-
"
|
57 |
"device": "desktop",
|
58 |
-
"
|
59 |
-
"num_result": "20",
|
60 |
-
"api_token": SERPHOUSE_API_KEY,
|
61 |
}
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
results = data.get("results", {})
|
67 |
-
organic =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
if not organic:
|
69 |
-
|
|
|
|
|
|
|
|
|
70 |
|
71 |
summary_lines = []
|
72 |
for idx, item in enumerate(organic[:20], start=1):
|
73 |
item_json = json.dumps(item, ensure_ascii=False, indent=2)
|
74 |
summary_lines.append(f"Result {idx}:\n{item_json}\n")
|
75 |
-
|
|
|
76 |
return "\n".join(summary_lines)
|
|
|
77 |
except Exception as e:
|
78 |
logger.error(f"Web search failed: {e}")
|
79 |
return f"Web search failed: {str(e)}"
|
|
|
40 |
return " ".join(key_tokens)
|
41 |
|
42 |
##############################################################################
|
43 |
+
# SerpHouse Live endpoint 호출
|
44 |
# - 상위 20개 결과 JSON을 LLM에 넘길 때 link, snippet 등 모두 포함
|
45 |
##############################################################################
|
46 |
def do_web_search(query: str) -> str:
|
|
|
50 |
"""
|
51 |
try:
|
52 |
url = "https://api.serphouse.com/serp/live"
|
53 |
+
|
54 |
+
# 기본 GET 방식으로 파라미터 간소화
|
55 |
params = {
|
56 |
"q": query,
|
57 |
"domain": "google.com",
|
58 |
+
"serp_type": "web", # 기본 웹 검색
|
59 |
"device": "desktop",
|
60 |
+
"lang": "en"
|
|
|
|
|
61 |
}
|
62 |
+
|
63 |
+
headers = {
|
64 |
+
"Authorization": f"Bearer {SERPHOUSE_API_KEY}"
|
65 |
+
}
|
66 |
+
|
67 |
+
logger.info(f"SerpHouse API 호출 중... 검색어: {query}")
|
68 |
+
logger.info(f"요청 URL: {url} - 파라미터: {params}")
|
69 |
+
|
70 |
+
# GET 요청 수행
|
71 |
+
response = requests.get(url, headers=headers, params=params, timeout=30)
|
72 |
+
response.raise_for_status()
|
73 |
+
|
74 |
+
logger.info(f"SerpHouse API 응답 상태 코드: {response.status_code}")
|
75 |
+
data = response.json()
|
76 |
+
|
77 |
+
# 다양한 응답 구조 처리
|
78 |
results = data.get("results", {})
|
79 |
+
organic = None
|
80 |
+
|
81 |
+
# 가능한 응답 구조 1
|
82 |
+
if isinstance(results, dict) and "organic" in results:
|
83 |
+
organic = results["organic"]
|
84 |
+
|
85 |
+
# 가능한 응답 구조 2 (중첩된 results)
|
86 |
+
elif isinstance(results, dict) and "results" in results:
|
87 |
+
if isinstance(results["results"], dict) and "organic" in results["results"]:
|
88 |
+
organic = results["results"]["organic"]
|
89 |
+
|
90 |
+
# 가능한 응답 구조 3 (최상위 organic)
|
91 |
+
elif "organic" in data:
|
92 |
+
organic = data["organic"]
|
93 |
+
|
94 |
if not organic:
|
95 |
+
logger.warning("응답에서 organic 결과를 찾을 수 없습니다.")
|
96 |
+
logger.debug(f"응답 구조: {list(data.keys())}")
|
97 |
+
if isinstance(results, dict):
|
98 |
+
logger.debug(f"results 구조: {list(results.keys())}")
|
99 |
+
return "No web search results found or unexpected API response structure."
|
100 |
|
101 |
summary_lines = []
|
102 |
for idx, item in enumerate(organic[:20], start=1):
|
103 |
item_json = json.dumps(item, ensure_ascii=False, indent=2)
|
104 |
summary_lines.append(f"Result {idx}:\n{item_json}\n")
|
105 |
+
|
106 |
+
logger.info(f"검색 결과 {len(organic)} 개 찾음")
|
107 |
return "\n".join(summary_lines)
|
108 |
+
|
109 |
except Exception as e:
|
110 |
logger.error(f"Web search failed: {e}")
|
111 |
return f"Web search failed: {str(e)}"
|