MCPcopy Create free account
hub / github.com/OpenRaiser/PaperFlow / _fetch_google_scholar_profile_pages

Function _fetch_google_scholar_profile_pages

agents/coldstart-agent/main.py:1263–1323  ·  view source on GitHub ↗

Fetch one or more Scholar profile pages with lightweight fallbacks.

(scholar_url: str)

Source from the content-addressed store, hash-verified

1261
1262
1263def _fetch_google_scholar_profile_pages(scholar_url: str) -> Dict[str, Any]:
1264 """Fetch one or more Scholar profile pages with lightweight fallbacks."""
1265 timeout_seconds = max(5, _get_env_int("PAPERFLOW_SCHOLAR_TIMEOUT", SCHOLAR_TIMEOUT_SECONDS))
1266 publication_limit = max(1, _get_env_int("PAPERFLOW_SCHOLAR_PUBLICATION_LIMIT", SCHOLAR_PUBLICATION_LIMIT))
1267 page_size = max(20, _get_env_int("PAPERFLOW_SCHOLAR_PAGE_SIZE", 100))
1268 max_pages = max(1, _get_env_int("PAPERFLOW_SCHOLAR_MAX_PAGES", SCHOLAR_MAX_PAGES))
1269
1270 session = requests.Session()
1271 errors: List[str] = []
1272 profile: Dict[str, Any] = {}
1273
1274 for page_index in range(max_pages):
1275 cstart = page_index * page_size
1276 if len(profile.get("all_publications", [])) >= publication_limit:
1277 break
1278
1279 candidate_urls = [
1280 _build_scholar_profile_url(scholar_url, cstart=cstart, pagesize=page_size, hl="en"),
1281 _build_scholar_profile_url(scholar_url, cstart=cstart, pagesize=20, hl="en"),
1282 _build_scholar_profile_url(scholar_url, cstart=cstart, pagesize=20, hl="zh-CN"),
1283 ]
1284
1285 page_data: Dict[str, Any] = {}
1286 page_loaded = False
1287 for candidate_url in candidate_urls:
1288 try:
1289 response = session.get(candidate_url, headers=SCHOLAR_HEADERS, timeout=timeout_seconds)
1290 response.raise_for_status()
1291 parsed = _parse_google_scholar_profile_html(response.text)
1292 if parsed.get("blocked"):
1293 errors.append("Scholar returned an anti-bot / captcha page")
1294 continue
1295 if not parsed.get("interests") and not parsed.get("all_publications") and not parsed.get("publications"):
1296 fallback_excerpt = _build_scholar_fallback_excerpt(response.text)
1297 if fallback_excerpt:
1298 parsed["fallback_excerpt"] = fallback_excerpt
1299 errors.append("Scholar page loaded but structured profile signals were empty")
1300 continue
1301 page_data = parsed
1302 page_loaded = True
1303 break
1304 except requests.RequestException as exc:
1305 errors.append(f"{type(exc).__name__}: {exc}")
1306
1307 if not page_loaded:
1308 if profile.get("all_publications") or profile.get("interests"):
1309 break
1310 raise ValueError("failed to fetch Google Scholar profile; " + "; ".join(errors[-3:]))
1311
1312 profile = _merge_scholar_page_data(profile, page_data, publication_limit)
1313
1314 current_page_publications = page_data.get("all_publications") or page_data.get("publications") or []
1315 if len(current_page_publications) < page_size:
1316 break
1317
1318 if not profile.get("interests") and not profile.get("publications"):
1319 raise ValueError("no scholar interests or publication rows found")
1320

Callers 1

Calls 7

_merge_scholar_page_dataFunction · 0.85
getMethod · 0.80
_get_env_intFunction · 0.70
raise_for_statusMethod · 0.45

Tested by

no test coverage detected