【百度地图】获取实时路况地图瓦片

悠悠 2022-10-14 12:51 601阅读 0赞

步骤一:下载地图瓦片

增加了几个反反爬虫策略:

  1. 每请求50次更换ip及header
  2. 每次请求生成1-100的随机数,当为66时暂停0-20s内一个随机时长
  3. 每完成一个时刻瓦片下载,暂停100-300s内一个随机时长
  4. 当请求报错时,更换ip及header重新请求

    s1_getTrafficData.py

    -- coding: utf-8 --

    import http, time, random, os
    import urllib.request

    http://its.map.baidu.com:8002/traffic/TrafficTileService?time=1604900544967&v=016&level=19&x=98760&y=19742

    百度地图切片原点左下角,(x, y),x为列,y为行

    研究范围:左下(98697, 19700) - 右上(98787, 19766)

  1. def getUserAgent():
  2. agent_list = [
  3. "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0",
  4. "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",
  5. 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0'
  6. ]
  7. agent = random.choice(agent_list)
  8. header = (
  9. 'User-Agent', agent
  10. )
  11. return header
  12. def getProxy():
  13. ip_list = [
  14. "http://117.93.118.88:3000",
  15. "http://111.177.192.57:3256",
  16. "http://112.195.242.60:3256",
  17. "http://124.205.153.81:80",
  18. "http://49.85.2.17:3000"
  19. "http://117.88.208.32:3000",
  20. "http://114.99.9.117:1133",
  21. "http://125.72.106.132:3256",
  22. "http://49.85.188.37:8014",
  23. "http://124.206.34.66:80",
  24. "http://117.68.192.93:1133",
  25. "http://114.233.170.151:8056",
  26. "http://60.168.207.147:1133",
  27. "http://114.233.170.48:8056",
  28. "http://1.70.67.20:9999",
  29. "http://121.226.215.247:9999",
  30. "http://114.233.194.202:8086",
  31. "http://114.112.127.78:80",
  32. "http://117.66.233.26:9999",
  33. "http://180.122.38.235:8090",
  34. "http://117.95.192.119:9999",
  35. "http://49.85.188.21:8058",
  36. "http://114.233.168.211:8088",
  37. "http://180.120.209.130:8888",
  38. ]
  39. ip = random.choice(ip_list)
  40. proxy = urllib.request.ProxyHandler({ 'http': ip})
  41. return proxy
  42. def requestImg(proxy, header, url, file_name):
  43. if os.path.exists(file_name):
  44. return proxy, header
  45. try:
  46. opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler)
  47. opener = urllib.request.build_opener()
  48. opener.addheaders=[header]
  49. urllib.request.install_opener(opener)
  50. # req=urllib.request.Request(url=url,headers=header)
  51. # res = urllib.request.urlopen(url, timeout=60)
  52. req = urllib.request.Request(url)
  53. res = opener.open(req, timeout=30)
  54. with open(file_name, "wb") as f:
  55. content = res.read()
  56. f.write(content)
  57. res.close()
  58. # except urllib.error.HTTPError or urllib.error.URLError as e:
  59. # print(e.reason)
  60. # except http.client.IncompleteRead or http.client.RemoteDisconnected as e:
  61. # if num_retries == 0: # 重连机制
  62. # return
  63. # else:
  64. # requestImg(proxy, header, url, file_name, num_retries - 1)
  65. except:
  66. print("exception...")
  67. proxy = getProxy()
  68. header = getUserAgent()
  69. proxy, header = requestImg(proxy, header, url, file_name)
  70. return proxy, header
  71. if __name__ == "__main__":
  72. # 3.15-3.21 7:00-20:00
  73. day_index = 7
  74. hour_index = 27
  75. for i in range(1, day_index):
  76. for j in range(hour_index):
  77. t = 1615762800000 + i * 86400000 + j * 1800000
  78. dir_path = "./tiles/images_" + str(i) + "_" + str(j)
  79. if not os.path.exists(dir_path):
  80. os.makedirs(dir_path)
  81. base_url = "http://its.map.baidu.com:8002/traffic/TrafficTileService?level=17&v=016&time="
  82. reset_clock = 50
  83. proxy = getProxy()
  84. header = getUserAgent()
  85. for x in range(24670, 24710):
  86. for y in range(4920, 4950):
  87. url = base_url + str(t) + "&x=" + str(x) + "&y=" + str(y)
  88. file_name = dir_path + "/" + str(x) + "-" + str(y) + '.png'
  89. # 每50次更换ip、header
  90. if reset_clock == 0:
  91. proxy = getProxy()
  92. header = getUserAgent()
  93. reset_clock = 50
  94. # 请求
  95. proxy1, header1 = requestImg(proxy, header, url, file_name)
  96. proxy = proxy1
  97. header = header1
  98. reset_clock = reset_clock - 1 # 重置时钟-1
  99. print(i,j,x,y)
  100. time.sleep(random.random())
  101. # 每次请求如果遇到随机数66,暂停20s
  102. if random.randint(1, 100) == 66:
  103. print("sleeping......")
  104. time.sleep(20 * random.random())
  105. # 某天某时所有请求完毕时,停留久一点
  106. time.sleep(random.uniform(100, 300))
  107. print("------ok------")

步骤二:去除无数据空图

  1. # s2_replaceEmpty
  2. # -*- coding: utf-8 -*-
  3. #!/usr/bin/env python
  4. import glob, re
  5. from PIL import Image
  6. d = 7
  7. t = 27
  8. for i in range(d):
  9. for j in range(t):
  10. p = './tiles/images_'+str(i)+ '_' + str(j) +'/*.png'
  11. # 按照x、y顺序对文件名进行排序
  12. files = glob.glob(p)
  13. for x in files:
  14. try:
  15. img = Image.open(x)
  16. img.close()
  17. except:
  18. img = Image.new(mode='RGBA', size=(256, 256))
  19. img.save(x)

步骤三:拼接瓦片

  1. # s3_mergeImages.py
  2. # -*- coding: utf-8 -*-
  3. #!/usr/bin/env python
  4. import glob, re
  5. from PIL import Image
  6. d = 7
  7. t = 27
  8. for i in range(d):
  9. for j in range(t):
  10. s = './tiles/images_'+str(i)+ '_' + str(j) +'/*.png'
  11. # 按照x、y顺序对文件名进行排序
  12. files = glob.glob(s)
  13. files.sort(key=lambda x: tuple(int(i) for i in re.findall(r'\d+', x)[2:4]))
  14. # 将每一行文件名保存到一个数组中
  15. imagefiles = { }
  16. for item in files:
  17. match = re.findall(r'\d+', item)
  18. # pre = int(match.group())
  19. pre = match[2]
  20. if not imagefiles.get(pre):
  21. imagefiles[pre] = []
  22. imagefiles[pre].append(item)
  23. # 键值对转排序后的列表
  24. imagefiles = sorted(zip(imagefiles.keys(), imagefiles.values()))
  25. # 预先生成合并后大小的空图片
  26. total_width = len(imagefiles) * 256
  27. total_height = len(imagefiles[0][1]) * 256
  28. new_image = Image.new("RGBA", (total_width, total_height))
  29. # 逐行拼接
  30. x_offset = 0
  31. for item in imagefiles:
  32. y_offset = total_height - 256
  33. images = list(map(Image.open, item[1])) # 映射函数,返回列表
  34. for subitem in images:
  35. new_image.paste(subitem, (x_offset, y_offset))
  36. y_offset -= subitem.size[0]
  37. x_offset += images[0].size[0]
  38. f_name = "./merge/merge_"+str(i) + "_"+str(j)+".png"
  39. new_image.save(f_name, quality = 100)

发表评论

表情:
评论列表 (有 0 条评论,601人围观)

还没有评论,来说两句吧...

相关阅读