Extract profile-level citation stats when the sidebar table is available.
(html_text: str)
| 641 | |
| 642 | |
| 643 | def _parse_scholar_stats(html_text: str) -> Dict[str, int]: |
| 644 | """Extract profile-level citation stats when the sidebar table is available.""" |
| 645 | stats: Dict[str, int] = {} |
| 646 | row_pattern = ( |
| 647 | r'<tr[^>]*>\s*' |
| 648 | r'<td[^>]*class=["\'][^"\']*\bgsc_rsb_sc1\b[^"\']*["\'][^>]*>(.*?)</td>\s*' |
| 649 | r'<td[^>]*class=["\'][^"\']*\bgsc_rsb_std\b[^"\']*["\'][^>]*>(.*?)</td>' |
| 650 | ) |
| 651 | for match in re.finditer(row_pattern, html_text or "", re.IGNORECASE | re.DOTALL): |
| 652 | label = _strip_html(match.group(1)).lower().replace(" ", "_") |
| 653 | value_match = re.search(r"\d+", _strip_html(match.group(2))) |
| 654 | if label and value_match: |
| 655 | stats[label] = int(value_match.group(0)) |
| 656 | return stats |
| 657 | |
| 658 | |
| 659 | def _parse_author_names(author_line: str, scholar_name: str = "") -> List[str]: |
no test coverage detected