Support JSON server list in addition to XML server list(s)

The JSON server list (https://www.speedtest.net/api/js/servers) is what the
Speedtest.net web interface currently uses.
This commit is contained in:
Daniel Lenski 2021-12-30 16:03:50 -05:00
parent ca4f4a3222
commit 0096adccf7
1 changed files with 41 additions and 25 deletions

View File

@ -1286,6 +1286,7 @@ class Speedtest(object):
) )
urls = [ urls = [
'https://www.speedtest.net/api/js/servers',
'://www.speedtest.net/speedtest-servers-static.php', '://www.speedtest.net/speedtest-servers-static.php',
'http://c.speedtest.net/speedtest-servers-static.php', 'http://c.speedtest.net/speedtest-servers-static.php',
'://www.speedtest.net/speedtest-servers.php', '://www.speedtest.net/speedtest-servers.php',
@ -1311,6 +1312,10 @@ class Speedtest(object):
raise ServersRetrievalError() raise ServersRetrievalError()
stream = get_response_stream(uh) stream = get_response_stream(uh)
try:
is_json = uh.headers.getheader('content-type').startswith('application/json')
except AttributeError:
is_json = uh.getheader('content-type').startswith('application/json')
serversxml_list = [] serversxml_list = []
while 1: while 1:
@ -1328,37 +1333,48 @@ class Speedtest(object):
raise ServersRetrievalError() raise ServersRetrievalError()
serversxml = ''.encode().join(serversxml_list) serversxml = ''.encode().join(serversxml_list)
attriblist = []
printer('Servers XML:\n%s' % serversxml, debug=True) if is_json:
printer('Servers JSON:\n%s' % serversxml, debug=True)
try:
attriblist = json.loads(serversxml)
except (ValueError, json.JSONDecodeError):
raise ServersRetrievalError()
else:
printer('Servers XML:\n%s' % serversxml, debug=True)
try:
try: try:
try: try:
root = ET.fromstring(serversxml) try:
except ET.ParseError: root = ET.fromstring(serversxml)
e = get_exception() except ET.ParseError:
raise SpeedtestServersError( e = get_exception()
'Malformed speedtest.net server list: %s' % e raise SpeedtestServersError(
) 'Malformed speedtest.net server list: %s' % e
elements = root.getiterator('server') )
except AttributeError: elements = root.getiterator('server')
except AttributeError:
try:
root = DOM.parseString(serversxml)
except ExpatError:
e = get_exception()
raise SpeedtestServersError(
'Malformed speedtest.net server list: %s' % e
)
elements = root.getElementsByTagName('server')
except (SyntaxError, xml.parsers.expat.ExpatError):
raise ServersRetrievalError()
for server in elements:
try: try:
root = DOM.parseString(serversxml) attrib = server.attrib
except ExpatError: except AttributeError:
e = get_exception() attrib = dict(list(server.attributes.items()))
raise SpeedtestServersError( attriblist.append(attrib)
'Malformed speedtest.net server list: %s' % e
)
elements = root.getElementsByTagName('server')
except (SyntaxError, xml.parsers.expat.ExpatError):
raise ServersRetrievalError()
for server in elements:
try:
attrib = server.attrib
except AttributeError:
attrib = dict(list(server.attributes.items()))
for attrib in attriblist:
if servers and int(attrib.get('id')) not in servers: if servers and int(attrib.get('id')) not in servers:
continue continue