Google Maps explicitly forbid using map tiles offline or caching them, but I think Microsoft Bing Maps don't say anything explicitly against it, and I guess you are not planning to use your program commercially (?)
This colab notebook show you how to get a title from tiles.virtualearth.net.
The source code is simple:
class TileServer(object):
def __init__(self):
self.imagedict = {}
self.mydict = {}
self.layers = 'ROADMAP'
self.path = './'
self.urlTemplate = 'http://ecn.t{4}.tiles.virtualearth.net/tiles/{3}{5}?g=0'
self.layerdict = {'SATELLITE': 'a', 'HYBRID': 'h', 'ROADMAP': 'r'}
def tiletoquadkey(self, xi, yi, z, layers):
quadKey = ''
for i in range(z, 0, -1):
digit = 0
mask = 1 << (i - 1)
if(xi & mask) != 0:
digit += 1
if(yi & mask) != 0:
digit += 2
quadKey += str(digit)
return quadKey
def loadimage(self, fullname, tilekey):
im = Image.open(fullname)
self.imagedict[tilekey] = im
return self.imagedict[tilekey]
def tile_as_image(self, xi, yi, zoom):
tilekey = (xi, yi, zoom)
result = None
try:
result = self.imagedict[tilekey]
print(result)
except:
print(self.layers)
filename = '{}_{}_{}_{}.jpg'.format(zoom, xi, yi, self.layerdict[self.layers])
print("filename is " + filename)
fullname = self.path + filename
try:
result = self.loadimage(fullname, tilekey)
except:
server = random.choice(range(1,4))
quadkey = self.tiletoquadkey(*tilekey)
print (quadkey)
url = self.urlTemplate.format(xi, yi, zoom, self.layerdict[self.layers], server, quadkey)
print ("Downloading tile %s to local cache." % filename)
urllib.request.urlretrieve(url, fullname)
#urllib.urlretrieve(url, fullname)
result = self.loadimage(fullname, tilekey)
return result