首页 > 其他分享 >百度离线地图地点搜索 离线地图poi搜索

百度离线地图地点搜索 离线地图poi搜索

时间:2023-01-31 18:11:13浏览次数:59  
标签:地图 await 离线 搜索 poi input page

1. 场景和需求:

在局域网开发的web项目,不能连接公网
1 需要使用离线地图展示设备点位;
2 需要实现地图的城市范围内的离线搜索,可以检索到百度地图上的点位,类似与百度地图首页的搜索功能,但是把搜索限定在指定城市或区域;
离线地图的实现不在此做讲解,其他一些博客讲解的比较详细,可以搜索一下
这里重点讲一下离线地图的poi数据获取

2. 实现思路:

两种实现方法

  1. 从百度地图或者高德地图, 根据地图厂商的poi分类和检索接口,根据接口获取数据后保存起来,数据整理后保存到数据库,搜索时根据关键词做模糊搜索
  2. 从地图页面爬取poi数据

1. 根据接口检索

以百度地图为例:
百度地图poi分类:
https://lbsyun.baidu.com/index.php?title=open/poitags

地点检索api:
https://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference_3_0.html#a7b33
根据检索poi方法

// 在北京市范围内检索中关村
var map = new BMap.Map("container");    
map.centerAndZoom(new BMap.Point(116.404, 39.915), 14);  
var local = new BMap.LocalSearch("北京市",   
            {renderOptions: {map: map,autoViewport: true},pageCapacity: 8});      
local.search("中关村");

搜索时可用百度地图poi二级分类做检索,遍历poi关键词检索后差不多能把整个城市的数据保存下来
缺点:个人账号有调用次数和频率限制,企业账号价格过高,对仅需要离线数据来说,得不偿失

2. 从地图页面爬取,遍历二级poi分类,先搜索城市,将地图锁定在城市范围内,在输入poi关键字,搜索翻页后保存数据,最后导出到excel或数据库中,就可以根据数据来进行离线地图搜索

实现:此处使用node+puppeteer+node-xlsx,使用自动化测试爬虫的方式获取数据
代码

const puppeteer = require('puppeteer');
const axios = require('axios');

var xlsx = require('node-xlsx');
var fs = require('fs');

// 结果数组, 存储转码后存到excel或者数据库中
let data = []

// excel 一个工作表的一行,即表头行, 真实数据在data数组中push即可
let edata = [
  {
    name: 'sheet1',
    data: [
      [
        '名称',
        '地址',
        '经纬度未转码',
        '电话',
        '经度',
        '维度',
        'uid',
      ]
    ]
  }
]

async function run () {
  // 启动浏览器
    const browser = await puppeteer.launch({
        headless: false,  // 不配置则默认为true 启动无头浏览器, false则显式启动浏览器
        // executablePath: "C:\Users\90798\AppData\Local\Google\Chrome\Application\chrome.exe"
        args: ['--start-maximized'],  // 启动时浏览器最大化显示
        defaultViewport: null,
    });

    const page = await browser.newPage(); // 打开新页面
    page.setViewport({ width:0, height:0});

    await page.goto('https://map.baidu.com/', { timeout: 8000 }); // 跳转站点

    // await page.waitForTimeout(3000);

    let loginDia = await page.waitForSelector('#passport-login-pop') // 登录对话框

    console.log('--------> loginDia', loginDia)

    // Query for an element handle.
    // const element = await page.waitForSelector('div > .class-name'); // 查询页面元素
    const element = await page.waitForSelector('input#sole-input'); // 查询页面元素

    console.log('____element', element)

    // await page.click('#TANGRAM__PSP_39__closeBtn') // 登录对话框 关闭按钮

    let loginDiaCloseIcon = await page.waitForSelector('#TANGRAM__PSP_39__closeBtn')

    await loginDiaCloseIcon.click(); // Just an example.

    await page.type('input#sole-input', '白沙黎族自治县')  

    await page.click('#search-button')


    // await page.type(element, '白沙黎族自治县')

    // let btn = await page.waitForSelector('#search-button'); // 查询页面元素

    // Do something with element...
    // await btn.click(); // Just an example.

    await page.on('response', async response => {    
      console.log('response.url', response.url())
      try {
        // console.log('response.json', await response.json())
        let resData = await response.json()
        if(resData.content && Array.isArray(resData.content) && resData.place_info){
          resData.content.map(it => {
            data.push([ it.name, it.addr, it.geo.substring(it.geo.lastIndexOf('|')+1).replaceAll(';', ''), (it.tel || ''), it.uid ])
          })
        }
      } catch (error) {
        console.log('----------> error', error)
      }
      if (response.url() == "https://capuk.org/ajax_search/capmoneycourses"){
          console.log('XHR response received'); 
          console.log(response.json()); 
      } 

      const divHandle = await page.evaluateHandle(() => {
        let overflowDiv = document.querySelector('.poi-wrapper');
        overflowDiv && (overflowDiv.scrollTop  = 999)
        return overflowDiv;
      });
  }); 

  // await page.waitForTimeout(3000);

  await new Promise((res, rej) => { setTimeout(() => { res() }, 3000)})

    //清空输入框的值
  await page.$eval('input#sole-input',input => input.value='' );
  await page.type('input#sole-input', '酒店', {delay: 100})  

  await page.click('#search-button')

  // await page.waitForTimeout(3000);

  const poll = async () => {
    // let down = await page.$('.close-btn-download-banner')
    // try {
    //   down && down.click()
    // } catch (error) {
    //   console.log('----------> down.click error', error)
    // }
    // await page.waitForSelector('.leadDownloadCard', {hidden: true});
    // page.waitFor(() => !document.querySelector('#leadDownloadCard'));
    // page.$('.close-btn-download-banner').then(data => {
    //   if(data){
    //     data.click()
    //   }
    // })
    await page.$eval('body', () => {
      $('.close-btn-download-banner').click()
    })
    
    setTimeout(async () => {
      let nextPageBtn = await page.waitForSelector('[tid=toNextPage]')
      let hasNoNext = await page.$('.next.next-none')
      if(nextPageBtn && !hasNoNext){
        await nextPageBtn.click()
        poll()
      }else{
        console.log('分页查询完成 data', data)
        turn()
      }
    }, 3000)
  }

  poll()
};

// 保存到excel中
function turn(){
}

示例:

标签:地图,await,离线,搜索,poi,input,page
From: https://www.cnblogs.com/zhuyuesen/p/17080126.html

相关文章