(html_text)
| 14722 | return "" |
| 14723 | |
| 14724 | def _extract_from_embedded_json(html_text): |
| 14725 | script_blobs = re.findall(r"<script[^>]*>(.*?)</script>", html_text, flags=re.DOTALL | re.IGNORECASE) |
| 14726 | prefixes = ( |
| 14727 | "window.__NUXT__", |
| 14728 | "__NUXT__", |
| 14729 | "window.__INITIAL_STATE__", |
| 14730 | "__NEXT_DATA__", |
| 14731 | "window.__NEXT_DATA__", |
| 14732 | "window.__INITIAL_DATA__", |
| 14733 | ) |
| 14734 | candidates = [] |
| 14735 | for s in script_blobs: |
| 14736 | if not s: |
| 14737 | continue |
| 14738 | for pfx in prefixes: |
| 14739 | pattern = pfx + r"\s*=\s*" |
| 14740 | for m in re.finditer(pattern, s, flags=re.IGNORECASE): |
| 14741 | start = m.end() |
| 14742 | js = s[start:start + 50000] |
| 14743 | obj_txt = _extract_json_obj(js, 0) |
| 14744 | if obj_txt: |
| 14745 | candidates.append(obj_txt) |
| 14746 | if pfx == "__NUXT__" or pfx == "window.__NUXT__": |
| 14747 | # nel caso in cui il JSON sia racchiuso in json stringa di nuxt |
| 14748 | if "window.__NUXT__=" in pfx: |
| 14749 | pass |
| 14750 | if "=" in pfx: |
| 14751 | continue |
| 14752 | |
| 14753 | # fallback anche a oggetti "id/name/username" serializzati in script plain |
| 14754 | for s in script_blobs: |
| 14755 | if '"username"' in s and '"id"' in s and ('"avatar"' in s or '"header"' in s): |
| 14756 | for m in re.finditer(r"\{.*?\}", s, flags=re.DOTALL): |
| 14757 | obj_txt = m.group(0) |
| 14758 | if len(obj_txt) < 120: |
| 14759 | continue |
| 14760 | candidates.append(obj_txt) |
| 14761 | |
| 14762 | parsed = [] |
| 14763 | for txt in candidates: |
| 14764 | try: |
| 14765 | parsed.append(json.loads(txt)) |
| 14766 | except Exception: |
| 14767 | pass |
| 14768 | return parsed |
| 14769 | |
| 14770 | def _walk_and_pick(obj): |
| 14771 | if not isinstance(obj, (dict, list)): |
nothing calls this directly
no outgoing calls
no test coverage detected