Выманне IP-адрасоў проксі і шаснаццатковых партоў з убудаванага JSON
Дэкадуйце вядомыя JSON-нагрузкі з выклікаў скрыптоў спісаў проксі і інтэрпрэтуйце шаснаццатковы порт толькі тады, калі фармат крыніцы гэта паведамляе.
Пустая HTML-табліца не заўсёды азначае, што ў адказе няма запісаў проксі. Некаторыя спісы змяшчаюць аб'екты JSON унутры выклікаў JavaScript і запоўніваюць радкі пазней.
Для ўжо атрыманай крыніцы, якая выкарыстоўвае пэўную абгортку gp.insertPrx, за якой ідзе аб'ект 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 — гэта тэкст крыніцы, а не аб'ект браўзера. Рэгулярны выраз знаходзіць вядомую абгортку; JSONDecoder вызначае, дзе заканчваецца значэнне JSON. Гэта пазбягае спробы разбору ўкладзенага JSON толькі рэгулярным выразам.
Поле порта ў прыкладзе відавочна шаснаццатковае: C38 азначае дзесятковае 3128. Не ўжывайце аснову 16 да дзесятковага поля іншага пастаўшчыка толькі таму, што абодва называюцца портам.
Гэта парсер для пазначанага фармату, а не інтэрпрэтатар JavaScript. Аб'ектныя літаралы ў адзінарных лапках, вылічаныя значэнні і іншыя выразы JavaScript патрабуюць іншага дакументаванага інтэрфейсу даных. Не выконвайце адвольны код старонкі, каб атрымаць спіс канчатковых пунктаў.
Праверце кантракт крыніцы і захоўвайце палі пратакола асобна. Калі крыніца мае запоўненыя радкі HTML, выкарыстоўвайце выманне канчатковых пунктаў у межах радка замест гэтага парсера абгортак JavaScript. Выманне адраса і порта не даказвае, што канчатковы пункт зараз прапануе працаздольную паслугу проксі.