(html_text, fallback_url)
| 15344 | return merged |
| 15345 | |
| 15346 | def _extract_from_html(html_text, fallback_url): |
| 15347 | scripts = re.findall(r"<script[^>]*>(.*?)</script>", html_text, flags=re.DOTALL | re.IGNORECASE) |
| 15348 | json_scripts = re.findall(r"<script[^>]*type=[\"']application/json[\"'][^>]*>(.*?)</script>", html_text, flags=re.DOTALL | re.IGNORECASE) |
| 15349 | ldjson_scripts = re.findall(r"<script[^>]*type=[\"']application/ld\\+json[\"'][^>]*>(.*?)</script>", html_text, flags=re.DOTALL | re.IGNORECASE) |
| 15350 | next_json = re.findall(r"<script[^>]*id=[\"']__NEXT_DATA__[\"'][^>]*>(.*?)</script>", html_text, flags=re.DOTALL | re.IGNORECASE) |
| 15351 | parsed = [] |
| 15352 | script_images = [] |
| 15353 | |
| 15354 | def _extract_json_obj(blob, start_idx=0): |
| 15355 | i = start_idx |
| 15356 | while i < len(blob) and blob[i].isspace(): |
| 15357 | i += 1 |
| 15358 | if i >= len(blob) or blob[i] != "{": |
| 15359 | return "" |
| 15360 | depth = 0 |
| 15361 | in_string = False |
| 15362 | esc = False |
| 15363 | quote = "" |
| 15364 | j = i |
| 15365 | while j < len(blob): |
| 15366 | ch = blob[j] |
| 15367 | if in_string: |
| 15368 | if esc: |
| 15369 | esc = False |
| 15370 | elif ch == "\\": |
| 15371 | esc = True |
| 15372 | elif ch == quote: |
| 15373 | in_string = False |
| 15374 | else: |
| 15375 | if ch in ("'", '"'): |
| 15376 | in_string = True |
| 15377 | quote = ch |
| 15378 | elif ch == "{": |
| 15379 | depth += 1 |
| 15380 | elif ch == "}": |
| 15381 | depth -= 1 |
| 15382 | if depth == 0: |
| 15383 | return blob[i:j + 1] |
| 15384 | j += 1 |
| 15385 | return "" |
| 15386 | |
| 15387 | prefixes = ( |
| 15388 | "window.__NUXT__", |
| 15389 | "window.__INITIAL_STATE__", |
| 15390 | "__NUXT__", |
| 15391 | "window.__NEXT_DATA__", |
| 15392 | "__NEXT_DATA__", |
| 15393 | "window.__STATE__" |
| 15394 | ) |
| 15395 | |
| 15396 | def _append_json_candidates(text): |
| 15397 | for pfx in prefixes: |
| 15398 | pat = pfx + r"\s*=\s*" |
| 15399 | for m in re.finditer(pat, text, flags=re.IGNORECASE): |
| 15400 | start = m.end() |
| 15401 | js = text[start:start + 60000] |
| 15402 | obj_txt = _extract_json_obj(js, 0) |
| 15403 | if obj_txt: |
nothing calls this directly
no test coverage detected