当前位置: 首页 > news >正文

建筑兔零基础自学记录49|python爬取百度地图POI实战-3

    本次利用python进行爬取,目前暂时只能实现全市信息的部分爬取,信息不全。有待继续补充其他方式建筑兔零基础自学记录45|获取高德/百度POI-1-CSDN博客但之前查到的工具POIKIT又对搜索分类有限制,不知道大家有没有什么更好的方式?
  本次是基于一个现有代码的改造,省略了获取不同区域的经纬度坐标的步骤,仅以地名来限制范围,不知是否会造成获取数据不全或者超出范围的问题。
   原始代码是还需导入一个不同区域的经纬度坐标这样的文件:

以下为尝试代码:

import urllib.request
import urllib.error
from urllib.parse import quote
import json
import time
import math

baseURL = 'https://api.map.baidu.com/place/v2/search?query=&output=json&'
ak = 'XXXXXXXXXXXXXXXXXXXXXXXX'#申请的码
query = quote('烧烤店')
scope = '2'
region = quote('北京')  # 对 region 进行 URL 编码
path = 'M:/python/workspace/PythonProject2_POI/json output/'
outputFile = path + 'BaiduPOI_1.txt'


def fetch(url):
    try:
        feedback = urllib.request.urlopen(url)
        data = feedback.read()
        response = json.loads(data)
        time.sleep(2)
        return response
    except (urllib.error.URLError, ValueError) as e:
        print(f"请求失败: {e}")
        return None


poiList = []

# 构建基于地区的初始请求URL
initialURL = f"{baseURL}ak={ak}&query={query}&scope={scope}&region={region}&page_size=20&page_num=0"
response = fetch(initialURL)
if not response or 'total' not in response:
    print("未获取到有效数据")
else:
    totalNum = response['total']
    numPages = math.ceil(totalNum / 20.0)  # 修正页码计算
    print(f"{numPages} pages in Total")

    for i in range(numPages):
        print(f"Fetching page {i}")
        URL = f"{baseURL}ak={ak}&query={query}&scope={scope}&region={region}&page_size=20&page_num={i}"
        page_response = fetch(URL)
        if not page_response or 'results' not in page_response:
            continue

        for content in page_response['results']:
            # 爬取店名,经纬度,uid,地址
            name = content.get('name', '')
            location = content.get('location', {})
            lat = location.get('lat', '')
            lng = location.get('lng', '')
            uid = content.get('uid', '')
            address = content.get('address', '')  # 提取地址信息
            poiInfo = f"{name};{lat};{lng};{uid};{address}"  # 更新 poiInfo 字符串
            poiList.append(poiInfo)

# 统一写入文件
try:
    with open(outputFile, 'w', encoding='utf-8') as f:
        for poiInfo in poiList:
            f.write(poiInfo + '\n')
except Exception as e:
    print(f"写入文件时出错: {e}")

注:在content部分可以根据自己的需求增添字段。其中的uid是 Unique Identifier(唯一标识符) 的缩写,用于唯一标识每个 POI(兴趣点)。每个 POI 在百度地图中都有唯一的uid,可避免重复记录或混淆相同名称的不同地点。在数据清洗或合并时,uid可作为主键用于去重或关联其他数据集。

获得的POI数据是这样的:

 全市只获得了84条数据,肯定不全。
原始代码如下:

import urllib.request
import urllib.error
from urllib.parse import quote
import json
import time
import math

baseURL = 'https://api.map.baidu.com/place/v2/search?query=&output=json&'
ak = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
query = quote('车')
scope = '2'
region = quote('北京')  # 对 region 进行 URL 编码
path = 'M:/python/workspace/PythonProject2_POI/json output/'
outputFile = path + 'BaiduPOI_1.txt'


def fetch(url):
    try:
        feedback = urllib.request.urlopen(url)
        data = feedback.read()
        response = json.loads(data)
        time.sleep(2)
        return response
    except (urllib.error.URLError, ValueError) as e:
        print(f"请求失败: {e}")
        return None


# 读取坐标文件
poiList = []
try:
    with open(path + 'BaiduCoord.txt', 'r') as coordinateFile:
        coordinates = coordinateFile.readlines()
except FileNotFoundError:
    print(f"未找到文件: {path + 'BaiduCoord.txt'}")#这里的BaiduCoord.txt就是坐标范围
else:
    for c in range(0, 10):
        # for c in range(len(coordinates)):
        coord_parts = coordinates[c].split(',')
        if len(coord_parts) < 3:
            continue  # 跳过无效行
        current_lat = coord_parts[1].strip()
        current_lng = coord_parts[2].strip()
        locator = coord_parts[0]
        print(f"This is {locator} of {len(coordinates)}")

        initialURL = f"{baseURL}ak={ak}&query={query}&scope={scope}&location={current_lat},{current_lng}&radius=700&page_size=20&page_num=0"  # 半径取700,一页返回20个数据
        # print(initialURL)
        response = fetch(initialURL)
        if not response or 'total' not in response:
            continue

        totalNum = response['total']
        numPages = math.ceil(totalNum / 20.0)  # 修正页码计算
        print(f"{numPages} pages in Total")

        for i in range(numPages):
            print(f"Fetching page {i}")
            URL = f"{baseURL}ak={ak}&query={query}&scope={scope}&location={current_lat},{current_lng}&radius=70&page_size=20&page_num={i}"
            page_response = fetch(URL)
            if not page_response or 'results' not in page_response:
                continue

            for content in page_response['results']:
                # 爬取店名,经纬度,uid,地址
                name = content.get('name', '')
                location = content.get('location', {})
                lat = location.get('lat', '')
                lng = location.get('lng', '')
                uid = content.get('uid', '')
                address = content.get('address', '')  # 提取地址信息
                poiInfo = f"{name};{lat};{lng};{uid};{address}"  # 更新 poiInfo 字符串
                poiList.append(poiInfo)

# 统一写入文件
try:
    with open(outputFile, 'w', encoding='utf-8') as f:
        for poiInfo in poiList:
            f.write(poiInfo + '\n')
except Exception as e:
    print(f"写入文件时出错: {e}")

哎头秃如何获取完整数据呢o(╥﹏╥)o

相关文章:

  • 康谋方案 | AVM合成数据仿真验证方案
  • 优选算法系列(2.滑动窗口_下)
  • Java+Html实现前后端客服聊天
  • anythingLLM之stream-chat传参
  • HttpServletRequest 获取 JSESSIONID
  • 3、数据库的事务隔离级别有哪些?【高频】
  • AOP切入点表达式
  • acwing1233.全球变暖
  • 【sgAutocomplete_v2】自定义组件:基于elementUI的el-input组件开发的搜索输入框(支持本地保存历史搜索关键词、后台获取匹配项)
  • linux-----------------指令下集
  • python中mysql操作整理
  • 基于TCN-BiLSTM-Attention的序列数据预测(功率预测、故障诊断)模型及代码详解
  • Spring Boot 整合 Elasticsearch 实践:从入门到上手
  • Leetcode——28. 找出字符串中第一个匹配项的下标
  • 使用 PIC 微控制器和 Adafruit IO 的基于 IoT 的 Web 控制家庭自动化
  • 在大数据开发中ETL是指什么?
  • 网络编程-实现客户端通信
  • conda相关总结
  • 基于Spring Boot的图书管理系统的设计与实现(LW+源码+讲解)
  • 蓝桥杯真题——洛谷Day13 找规律(修建灌木)、字符串(乘法表)、队列(球票)
  • 侧记|青年为何来沪创新创业?从这一天寻找答案
  • 巴基斯坦外长:印巴停火
  • 综艺还有怎样的新可能?挖掘小众文化领域
  • 上海“电子支付费率成本为0”背后:金融服务不仅“快”和“省”,更有“稳”和“准”
  • 昆明阳宗海风景名胜区19口井违规抽取地热水,整改后用自来水代替温泉
  • 国家卫健委:有条件的二级及以上综合医院要开设老年医学科