Pusta tabela HTML nie zawsze oznacza, że odpowiedź nie zawiera rekordów proxy. Niektóre listy umieszczają obiekty JSON w wywołaniach JavaScript i uzupełniają wiersze później.

Dla już pobranego źródła, które używa konkretnego wrappera gp.insertPrx, po którym następuje obiekt JSON:

import ipaddress
import json
import re

decoder = json.JSONDecoder()
endpoints = set()
for marker in re.finditer(r"gp[.]insertPrx\(\s*", html):
    try:
        row, end = decoder.raw_decode(html, marker.end())
        if not isinstance(row, dict):
            continue
        address = ipaddress.ip_address(row["PROXY_IP"])
        port = int(row["PROXY_PORT"], 16)
    except (ValueError, KeyError, TypeError):
        continue
    if 1 <= port <= 65535 and html[end:].lstrip().startswith(");"):
        endpoints.add((str(address), port))

html to tekst źródła, a nie obiekt przeglądarki. Wyrażenie regularne znajduje znany wrapper; JSONDecoder określa, gdzie kończy się wartość JSON. Dzięki temu unika się próby parsowania zagnieżdżonego JSON wyłącznie wyrażeniem regularnym.

Pole portu w przykładzie jest wyraźnie szesnastkowe: C38 oznacza dziesiętnie 3128. Nie stosuj podstawy 16 do dziesiętnego pola innego dostawcy tylko dlatego, że oba nazywają się portem.

To parser dla podanego formatu, a nie interpreter JavaScript. Literały obiektów w pojedynczych cudzysłowach, wartości obliczane i inne wyrażenia JavaScript wymagają innego udokumentowanego interfejsu danych. Nie uruchamiaj dowolnego kodu strony, aby uzyskać listę punktów końcowych.

Zweryfikuj kontrakt źródła i przechowuj pola protokołu osobno. Jeśli źródło ma zamiast tego wypełnione wiersze HTML, użyj wyodrębniania punktów końcowych wiersz po wierszu zamiast tego parsera wrapperów JavaScript. Wyodrębnienie adresu i portu nie dowodzi, że punkt końcowy obecnie oferuje użyteczną usługę proxy.

Powiązane artykuły