QtWebengine不加载openstreetmap图块
我写了一个这样的python测试程序来显示openstreetmap:
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QUrl
from PyQt5.QtWebEngineWidgets import QWebEngineView
import sys
def mainPyQt5():
url = 'file:///./index.html'
app = QApplication(sys.argv)
browser = QWebEngineView()
browser.load(QUrl(url))
browser.show()
sys.exit(app.exec_())
mainPyQt5()
QWebEngineView 获取的 index.html 只需调用 openstreetmap:
<title>OSM and Leaflet</title>
<link rel = "stylesheet" href = "http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css"/>
<div id = "map" style = "width: 900px; height: 580px"></div><script src = "http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<script>
// Creating map options
var mapOptions = {
center: [45.641174, 9.114828],
zoom: 10
}
// Creating a map object
var map = new L.map('map', mapOptions);
// Creating a Layer object
var layer = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
// Adding layer to the map
map.addLayer(layer);
</script>
如果我使用普通浏览器获取 index.html,地图会按预期显示,但如果我使用 QWebEngineView 调用简单的 python 程序,则不会从 openstreetmap 下载任何图块。如果我用 maps.stamen.com 替换 openstreetmap,那么无论是浏览器还是 python 脚本,一切都很好。
回答
默认情况下,QtWebEngine 不会像流行的浏览器那样设置默认标头。在这种情况下,openstreetmap 服务器需要知道“接受语言”制作地图,因为例如城市的名称将取决于语言过滤非浏览器流量。解决方案是实现QWebEngineUrlRequestInterceptor添加该标头的 a :
import os.path
import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor
from PyQt5.QtWebEngineWidgets import QWebEngineView
class Interceptor(QWebEngineUrlRequestInterceptor):
def interceptRequest(self, info):
info.setHttpHeader(b"Accept-Language", b"en-US,en;q=0.9,es;q=0.8,de;q=0.7")
def mainPyQt5():
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
filename = os.path.join(CURRENT_DIR, "index.html")
app = QApplication(sys.argv)
browser = QWebEngineView()
interceptor = Interceptor()
browser.page().profile().setUrlRequestInterceptor(interceptor)
browser.load(QUrl.fromLocalFile(filename))
browser.show()
sys.exit(app.exec_())
if __name__ == "__main__":
mainPyQt5()
- Yes I think crnm is correct about this header restriction being more about filtering out non-browser traffic. The core openstreetmap tile server has had many struggles with traffic, and so basically you shouldn't really use it for this kind of thing, or at least _"Do not hardcode any URL at tile.openstreetmap.org as doing so will limit your ability to react quickly if the service is disrupted or blocked"_ But instead check out some alternatives listed here: https://wiki.openstreetmap.org/wiki/Tile_servers