以三门峡水电站为例,网站能提供的数据非常丰富,这里我只关心基本信息如名字,摘要信息,经纬度,电厂定位精度,边界信息
其中名字,摘要信息,经纬度,电厂定位精度等都可以在通过requests.get的方式直接获取,边界经纬度信息无法直接获取
- 经验告诉我,边界信息可能在页面中以html标签属性的方式给出,然后在地图上画出边界信息,检查发现没有
- 查看网络请求,看是否有其他链接,提供边界数据,发现也没有,麻烦,两个地方都没有,有点懵逼-.-!!!
- 在地图上打点或者画边界信息,一定需要传入经纬度,既然在源码和请求连接中均未发现,那数据就是被隐式给出了,此时我想到的是看下是不是js处理了边界数据
- 溜达了一圈,js太长,且由于暂无搜索关键字可以快速帮我定位关键代码,导致速度很慢,有点烦躁,突然灵光一闪,既然没找到边界数据来源,那Google地图在画边界信息的时候总得传入边界数据吧?稍微研究了下Google Maps API ,其添加多边形的方法是 google.maps.Polygon(),于是乎搜索了一波google.maps.Polygon关键字,一不小心发现了今天的主角
- 分析图片中的js片段可知,多边形边界信息来自 path: google.maps.geometry.encoding.decodePath(Points),其中 Points = document.getElementById(‘Points’+overlaysCount).value;,行吧,我去源码看看属性id 含"Points"的标签,如图
好吧,此前并未注意到该标签,此时js中Points = “{hqsEqnqfTwDuCoB}b@lAaExD]z@dPm@Fp@bLbGq@h@jAkGjD”,要想获取path,还需知道google.maps.geometry.encoding.decodePath函数,此时走断点调试
整理出关键js
// var Points = document.getElementById('Points'+overlaysCount).value;
var Points = '{hqsEqnqfTwDuCoB}b@lAaExD]z@dPm@Fp@bLbGq@h@jAkGjD';
var Points = 'ksoxDwtqfTiT~PwD}JpBaCjClEnBkAzFmEo@_FrAoD';
L = function(a) {
return a ? a.length: 0
};
Xc = function(a) {
if (! (a instanceof Vc)) throw a;
Uc(a.name + ": " + a.message)
};
Kc = function(a, b, c) {
null != b && (a = Math.max(a, b));
null != c && (a = Math.min(a, c));
return a
};
Lc = function(a, b, c) {
c -= b;
return ((a - b) % c + c) % c + b
};
R = function(a, b, c) {
console.log('---['+a+','+b+']---')
if (a && (void 0 !== a.lat || void 0 !== a.lng)) try {
sd(a),
console.log(sd(a))
b = a.lng,
a = a.lat,
c = !1
} catch(d) {
Xc(d)
}
a -= 0;
b -= 0;
c || (a = Kc(a, -90, 90), 180 != b && (b = Lc(b, -180, 180)));
// console.log(a);
// console.log(b);
console.log('['+a+','+b+']')
this.lat = function() {
return a
};
this.lng = function() {
return b
}
};
decodePath = function(a) {
for (var b = L(a), c = Array(Math.floor(a.length / 2)), d = 0, e = 0, f = 0, g = 0; d < b; ++g) {
var h = 1,
k = 0;
do {
var l = a.charCodeAt(d++) - 63 - 1;
h += l << k;
k += 5
} while ( 31 <= l );
e += h & 1 ? ~ (h >> 1) : h >> 1;
h = 1;
k = 0;
do l = a.charCodeAt(d++) - 63 - 1,
h += l << k,
k += 5;
while (31 <= l);
f += h & 1 ? ~ (h >> 1) : h >> 1;
c[g] = new R(1E-5 * e, 1E-5 * f, !0)
// console.log('['+c[g].lat+','+c[g].lng+']')
}
c.length = g;
// console.log(c) ;
return c;
};
decodePath(Points);
将这组经纬度一次在地图上打点,发现就是我们要的边界信息,此时破解完成!我们把它转成python版本
def descrypt_bounds(encrypt_str):
d ,e , f , g = 0,0,0,0
results = []
for m in range(0,len(encrypt_str)):
h,k = 1,0
l = 0
if d>=len(encrypt_str):
break
while 1:
l = ord(encrypt_str[d]) - 63 - 1
h += l << k
k += 5
d += 1
if l<31:
break
temp = ~ (h >> 1) if h & 1 else h >> 1
e += temp
h, k = 1, 0
while 1:
# print('dddddddd------', d)
l = ord(encrypt_str[d]) - 63 - 1
h += l << k
k += 5
d += 1
# print('LLLLL:' + str(l))
if l < 31:
break
temp = ~ (h >> 1) if h & 1 else h >> 1
f += temp
results.append([1E-5 * e,1E-5 * f])
print(results)
return results
- 调试js如果有比较巧的思路,能起到事半功倍的效果,有机会把js调试的一些方法和经验分享给大家
- 该网站整理了不少电厂类数据,数据维度相当丰富
- js调试很需要耐心!!!!
文档仅作学习和记录使用,请不要用于商业和违法用途,如有侵权,请告知删除。