【爬虫】AOI

这篇具有很好参考价值的文章主要介绍了【爬虫】AOI。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目前几个大厂,高德百度腾讯,都支持POI爬取,而AOI是需要自己找接口的。
换言之,爬虫需谨慎


1 百度AOI

参考链接是:
这两个链接是选定范围爬取范围内选定类别的AOI
黑科技 | 百度地图抓取地块功能(上)
黑科技 | 百度地图获取地块功能属性(下)

而这个链接是用名称爬取。我参考的是这个:利用名称爬取百度AOI
https://www.cnblogs.com/zhangqinglan/p/13301425.html

跟Amap一样,其实是找到了一个接口:
https://map.baidu.com/?newmap=1&qt=s&da_src=searchBox.button&wd=‘+Name+’&c=XXX

其中Name为要搜索的名称。c=XXX的XXX为城市的city_id。这个之前爬风向标的时候已经看过了。

比如我输入朝阳大悦城和c=131
【爬虫】AOI,Python,爬虫

1.1 获得AOI ID

第一步是先从https://map.baidu.com/?newmap=1&qt=s&da_src=searchBox.button&wd='+Name+'&c=XXX这个接口里找打aoi的id。
跟参考链接不一样的是,我的名字是上一篇爬虫博客中爬好的csv文件。所以这里改动了下,方便读取我的格式。
另外参考博客这个层层嵌套的for和try-except,乍一看挺唬人。

在测试时还有个问题,就是try-except有时候会报错,返回false,因此我没用它。
以及我开代理爬取时有时成功有时不成功,不知道会不会被锁ip

还有就是在request语句中,参考博客是用 verify=False。后续调试代码时多爬几次就服务器报错了。所以也删掉了。gpt显示这个错误是跟SSH证书有关
【爬虫】AOI,Python,爬虫

import requests
import pandas as pd
from urllib.parse import quote
import time
import random
import json

HEADERS = {'Accept':'*/*',
        'Accept-Encoding':'gzip, deflate, sdch, br',
        'Accept-Language':'zh-CN,zh;q=0.8',
        'Connection':'keep-alive',
        'Cookie':'BAIDUID=C4D08149D7EE627DC037119413418CA3:FG=1;'\
               'BIDUPSID=C4D08149D7EE627DC037119413418CA3; PSTM=1540284487;'\
               'pgv_pvi=9789244416; BDUSS=GF-S3Y5c1MybnhoTkhwMUxyWEhHM3ZreW1'\
               'UTURiQk1TUFllMWc5V1ZWeUVHNGhkRVFBQUFBJCQAAAAAAAAAAAEAAAA~7j4'\
               '5ztLKx8DtuaTIyzMyMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'\
               'AAAAAAAAAAAAAAAAAAAAAAAAAAISOYF2EjmBdV; session_id=1567581077599;'\
               'session_name=; validate=31187; MCITY=-%3A; M_LG_UID=960425535;'\
               'M_LG_SALT=2cf3bbbbd3e5466b66a2529c037b982b',
        'Host':'map.baidu.com',
        'Referer':'https://map.baidu.com/search/%E9%83%91%E5%B7%9E%E5%B8%82%E4'\
               '%BA%8C%E4%B8%83%E4%B8%87%E8%BE%BE%E4%B8%89%E5%8F%B7%E9%99%A2/@'\
               '12650489.832882352,4101769.7450000006,18.35z/maptype%3DB_EARTH_'\
               'MAP?querytype=s&da_src=shareurl&wd=%E9%83%91%E5%B7%9E%E5%B8%82%'\
               'E4%BA%8C%E4%B8%83%E4%B8%87%E8%BE%BE%E4%B8%89%E5%8F%B7%E9%99%A2&c'\
               '=268&src=0&pn=0&sug=0&l=18&b=(12650755.24571287,4101867.11178217'\
               '83;12651854.04020792,4102020.4126732675)&from=webmap&biz_forward='\
               '%7B%22scaler%22:1,%22styles%22:%22pl%22%7D&device_ratio=1',
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) '
                    'AppleWebKit/537.36 (KHTML, like Gecko)'
                    'Chrome/55.0.2883.87 Safari/537.36',}


table=pd.read_csv(r"文件")
result_df = pd.DataFrame()
# 依次读取每个城市的名称和内容
for city in table.columns:
    city_name = city
    if city_name=='XXX':
        code=aaa;
    elif city_name=='XXX':
        code=aaa

    city_content = table[city].values.tolist()
    city_content = list(filter(lambda x: str(x) != "nan", city_content))
    
    list_aoiid=[]
    for mall in city_content:
        encoded_mall = quote(mall)
        url = "https://map.baidu.com/?newmap=1&qt=s&da_src=searchBox.button&wd={}&c={}".format(
                encoded_mall, code)
        print(url)
        
        delay = random.randint(2, 5)  # 生成1到2之间的随机整数
        time.sleep(delay)  # 延时随机秒数

        r = requests.get(url,headers=HEADERS, allow_redirects=True)
        data = r.content
        data=data.decode('utf-8')
        data = json.loads(data)
        aoi_id = data['result']['profile_uid']
        print(aoi_id)
        list_aoiid.append(aoi_id)
        
    city_data = pd.DataFrame({
        city_name: city_content,
        'aoiid': list_aoiid})
    
    result_df = pd.concat([result_df, city_data], ignore_index=True, axis=1)
    print(result_df)

可以看见最后获得的dataframe结果是这样的。是的我个人很喜欢搞完一步就存dataframe。
没有表头自己加一下就好。然后我们随机挑选几个进行验证。
【爬虫】AOI,Python,爬虫

验证链接就是前面代码print(url)输出的链接,或者自己按照前面的方法,设置name和city id,也行。
也是很佩服参考链接的博主怎么找到这个是aoi id 的,以及发现aoi的接口

1.2 AOI获取

不知道博主从哪里找到的接口:
https://map.baidu.com/?newmap=1&qt=ext&uid=‘+AOI ID+’&ext_ver=new&ie=utf-8&l=1
更改里面的AOI ID就行。下图中的Geo就是我们需要的
【爬虫】AOI,Python,爬虫
根据黑科技 | 百度地图获取地块功能属性(下)链接中的讲解,
aoi抓取到的数据是百度米制坐标,也就是百度墨卡托投影坐标系。而我们一般使用的都是wgs84大地坐标系。
需要转换【百度米制】到【百度经纬度坐标】再到【wgs84】。也就是【bd09mc】到【bd09】到【wgs84】
也就是要将下图中右边各个点的坐标进行转换
【爬虫】AOI,Python,爬虫
这里的转换跟黑科技 | 百度地图获取地块功能属性(下)提供的下载包中的转换代码做了对比,【bd09mc】到【bd09】没有差别,是一样的,而【bd09】到【wgs84】有出入。看想要哪种吧。我懒得换了。

#from station import stations
import warnings
import  xdrlib ,sys
import xlrd
import time
import socket

#bd墨卡托转BD-09
import math
pi = 3.1415926535897932384626
def Yr(lnglat,b):
    if b!='':
        c=b[0]+b[1]*abs(lnglat[0])
        d=abs(lnglat[1]/b[9])
        d=b[2]+b[3]*d+b[4]*d*d+b[5]*d*d*d+b[6]*d*d*d*d+b[7]*d*d*d*d*d+b[8]*d*d*d*d*d*d
        if 0>lnglat[0]:
            bd=-1*c
        else:
            bd=c
        lnglat[0]=bd
        if 0 > lnglat[0]:
            bd2 = -1 * d
        else:
            bd2 = d
        lnglat[1] = bd2
        return lnglat
    return
def Mecator2BD09(lng,lat):
    lnglat=[0,0]
    Au=[[1.410526172116255E-8, 8.98305509648872E-6, -1.9939833816331, 200.9824383106796, -187.2403703815547,
          91.6087516669843, -23.38765649603339, 2.57121317296198, -0.03801003308653, 1.73379812E7],
         [- 7.435856389565537E-9, 8.983055097726239E-6, -0.78625201886289, 96.32687599759846, -1.85204757529826,
          -59.36935905485877, 47.40033549296737, -16.50741931063887, 2.28786674699375, 1.026014486E7],
         [- 3.030883460898826E-8, 8.98305509983578E-6, 0.30071316287616, 59.74293618442277, 7.357984074871,
          -25.38371002664745, 13.45380521110908, -3.29883767235584, 0.32710905363475, 6856817.37],
         [- 1.981981304930552E-8, 8.983055099779535E-6, 0.03278182852591, 40.31678527705744, 0.65659298677277,
          -4.44255534477492, 0.85341911805263, 0.12923347998204, -0.04625736007561, 4482777.06],
         [3.09191371068437E-9, 8.983055096812155E-6, 6.995724062E-5, 23.10934304144901, -2.3663490511E-4,
          -0.6321817810242, -0.00663494467273, 0.03430082397953, -0.00466043876332, 2555164.4],
         [2.890871144776878E-9, 8.983055095805407E-6, -3.068298E-8, 7.47137025468032, -3.53937994E-6, -0.02145144861037,
          -1.234426596E-5, 1.0322952773E-4, -3.23890364E-6, 826088.5]]
    Sp=[1.289059486E7, 8362377.87, 5591021, 3481989.83, 1678043.12, 0 ]
    lnglat[0]=math.fabs(lng)
    lnglat[1] =abs(lat)
    for d in range(0,6):
        if lnglat[1]>=Sp[d]:
            c=Au[d]
            break
    lnglat=Yr(lnglat,c)
    return lnglat
def BD092WGS84(lnglat):
    #bd09-gcj

    x_pi = 3.14159265358979324 * 3000.0 / 180.0
    pi = 3.1415926535897932384626  # π
    a = 6378245.0  # 长半轴
    ee = 0.00669342162296594323  # 扁率
    x = lnglat[0] - 0.0065
    y = lnglat[1] - 0.006
    z = math.sqrt(x * x + y * y) - 0.00002 * math.sin(y * x_pi)
    theta = math.atan2(y, x) - 0.000003 * math.cos(x * x_pi)
    lnglat[0] = z * math.cos(theta)
    lnglat[1] = z * math.sin(theta)

    dlat = tranlat1(lnglat[0] - 105.0, lnglat[1] - 35.0)
    dlng = tranlng1(lnglat[0] - 105.0, lnglat[1] - 35.0)
    radlat = lnglat[1] / 180.0 * pi
    magic = math.sin(radlat)
    magic = 1 - ee * magic * magic
    sqrtmagic = math.sqrt(magic)
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
    dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)
    mglat = lnglat[1] + dlat
    mglng = lnglat[0] + dlng
    return [lnglat[0]* 2 - mglng, lnglat[1] * 2 - mglat]
def tranlat1(lng, lat):
    ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(lng))
    ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *
            math.sin(2.0 * lng * pi)) * 2.0 / 3.0
    ret += (20.0 * math.sin(lat * pi) + 40.0 *
            math.sin(lat / 3.0 * pi)) * 2.0 / 3.0
    ret += (160.0 * math.sin(lat / 12.0 * pi) + 320 *
            math.sin(lat * pi / 30.0)) * 2.0 / 3.0
    return ret
def tranlng1(lng, lat):
    ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + \
          0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(lng))
    ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *
            math.sin(2.0 * lng * pi)) * 2.0 / 3.0
    ret += (20.0 * math.sin(lng * pi) + 40.0 *
            math.sin(lng / 3.0 * pi)) * 2.0 / 3.0
    ret += (150.0 * math.sin(lng / 12.0 * pi) + 300.0 *
            math.sin(lng / 30.0 * pi)) * 2.0 / 3.0
    return ret

大体跟按照名称进行aoi提取的代码是一样的,没怎么改动。只不过原代码因为是id和aoi坐标嵌套的,所以最后输入坐标时可以直接用名称。我这里还需要自己再改改。

import requests
import pandas as pd
from urllib.parse import quote
import time
import random
import json

table=pd.read_csv(r"XXXXX")
none_aoiid=[]
with open(r"XXXXX", 
          'a',newline='') as f:
    for z in range(0,4):
        print('现在的数字是',z)
        city_mall=table.iloc[:,2*z]
        id_mall=table.iloc[:,2*z+1] 
        id_content = id_mall.values.tolist()
        id_content = list(filter(lambda x: str(x) != "nan", id_content))

        for aoiid in id_content:
            url_AOI = 'https://map.baidu.com/?newmap=1&qt=ext&uid={}'\
                        '&ext_ver=new&ie=utf-8&l=11'.format(aoiid)
            print('处理链接',url_AOI)
            r_AOI = requests.get(url_AOI,headers=HEADERS, allow_redirects=True)
            data = r_AOI.content.decode('utf-8')
            data = json.loads(data)

            if 'geo' in data['content']:
                geo_AOI = data['content']['geo']
                geo_AOI = geo_AOI.split('|')
                point = geo_AOI[2].split(",")

                point_transform=[]
                for i in range(int(len(point)/2)):#全部点的坐标,分别是x,y,的形式
                    if i==0: #[2:]的作用:删除第一个坐标的‘1-’字符
                        point[2*i] = point[2*i][2:] 
                    if i==int((len(point)/2)-1):  #删除最后一个坐标的‘;’字符
                        point[2*i+1] = point[2*i+1][:-1]
#                     print('第'+str(i)+'个点的坐标',float(point[2*i]),float(point[2*i+1]))#打印出各点的坐标
                    point_Mecator2BD09 = Mecator2BD09(float(point[2*i]),float(point[2*i+1]))
                    point_BD092WGS84 = BD092WGS84(point_Mecator2BD09)
                    point_transform.append(point_BD092WGS84)
                    point_str = '' #这是创建一个文本存储
                for j in range(len(point_transform)):
                    point_str = point_str+(str(point_transform[j])).replace(' ','')[1:-1]+';'
                print(str(aoiid)+' 处理完毕。开始写入')
                line=aoiid+' '+point_str+'\n'
                f.write(line)
            else:
                print(aoiid+'没有找到坐标')
                none_aoiid.append(aoiid)
    print('没有信息的aoi',str(none_aoiid))

将txt的iaoiid和csv文件进行匹配替换,最后结果是下面这样
【爬虫】AOI,Python,爬虫

1.3 小结

Amap的爬虫是我之前就做过的,用到就是下面的链接方法。需要一个个自己输入,比较麻烦。
但是抓包工具比自己的代码更强大,能搞定Amap的反扒机制。很强。

由于信息做过筛选所以百度这里只有坐标,最后生成AOI的shapefile的话也没有什么信息。这个还需要改进其实。毕竟信息都爬下来了。

1.4 误差原因

1.2的代码中最后有输出一个没有爬取到的aoi_id信息。而在对上一篇爬虫文里获得的百度风向标结果进行分析时看见,有一些地方的id是重复的。一开始我以为是触发了反扒机制,所以有些返回错误。刚刚对AOI生成的shapefile进行校验时发现,是百度地图的AOI有些不准确,有的范围太大了把其他区域也包括进去了。所以可能返回的商场是相同的id。

经过我自己在高德和百度的实验,百度aoi的位置更准确,也就是前面的代码获得最后转wgs84的aoi在arcgis pro的底图中很贴合。而高德使用下面的链接POI的体量 - AOI数据获取脚本分享获得不太准确,偏移较大。
所以下面链接的半自动化代码其实也是需要改进的。

Amap AOI

这个是一个半自动化的抓取方式。用抓包工具Fiddler
POI的体量 - AOI数据获取脚本分享
这个链接现在会触发高德反扒滑动条,如果躲不了就无法用:Python批量爬取高德AOI边界数据+GIS可视化(超详细)文章来源地址https://www.toymoban.com/news/detail-537016.html

到了这里,关于【爬虫】AOI的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python爬虫系列(二)——Python爬虫批量下载百度图片

    1. 前言 先贴代码 如果要使用上述程序的话,需要修改两个地方 : self.directory 这是本地存储地址,修改为自己电脑的地址,另外,**{}**不要删 spider.json_count = 10 这是下载的图像组数,一组有30张图像,10组就是三百张,根据需求下载 也可以去gitee仓库直接下载程序。 关于 py

    2023年04月08日
    浏览(53)
  • Python 爬虫(一):爬虫伪装

    对于一些有一定规模或盈利性质比较强的网站,几乎都会做一些防爬措施,防爬措施一般来说有两种:一种是做身份验证,直接把虫子挡在了门口,另一种是在网站设置各种反爬机制,让虫子知难而返。 我们知道即使是一些规模很小的网站通常也会对来访者的身份做一下检查

    2024年02月05日
    浏览(47)
  • Python小知识 - Python爬虫进阶:如何克服反爬虫技术

    Python爬虫进阶:如何克服反爬虫技术 爬虫是一种按照一定的规则,自动抓取网页信息的程序。爬虫也叫网页蜘蛛、蚂蚁、小水滴,是一种基于特定算法的自动化程序,能够按照一定的规则自动的抓取网页中的信息。爬虫程序的主要作用就是从一个网站或者一个网页中抓取所需

    2024年02月09日
    浏览(42)
  • python实现网络爬虫代码_python如何实现网络爬虫

    python实现网络爬虫的方法:1、使用request库中的get方法,请求url的网页内容;2、【find()】和【find_all()】方法可以遍历这个html文件,提取指定信息。 python实现网络爬虫的方法: 第一步:爬取 使用request库中的get方法,请求url的网页内容 编写代码[root@localhost demo]# touch demo.py [

    2024年01月20日
    浏览(46)
  • 【爬虫系列】Python 爬虫入门(2)

    接上篇,继续梳理 Python 爬虫入门的知识点。这里将重点说明,如何识别网站反爬虫机制及应对策略,使用 Selenium 模拟浏览器操作等内容,干货满满,一起学习和成长吧。 1.1 测试网站是否开启了反爬虫 随着互联网技术的日益革新,大多数的网站都会使用反爬虫机制。我们在

    2024年01月17日
    浏览(39)
  • 【python爬虫一】爬虫基础操作

    概念:是一种按照一定的规则,自动地抓取互联网上网页中相应信息(文本、图片等)的程序或脚本,然后把抓取的信息存储下来。 通用爬虫:把一整张页面源码数据进行爬取 聚焦爬虫:把页面中指定的数据进行爬取 增量式爬虫:监测网站数据更新的情况。 分布式爬虫:基

    2024年02月09日
    浏览(41)
  • 【Python】什么是爬虫,爬虫实例

     有s表示加密的访问方式 什么是爬虫 网络爬虫,是一种按照一定规则,自动抓取互联网信息的程序或者脚本。由于互联网数据的多样性和资源的有限性,根据用户需求定向抓取相关网页并分析已成为如今主流的爬取策略 爬虫可以做什么 你可以爬取图片,爬取自己想看的视频

    2024年02月02日
    浏览(86)
  • python爬虫入门教程(非常详细):如何快速入门Python爬虫?

    示例示例Python爬虫入门教程什么是爬虫爬虫(又称网络爬虫)是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。它可以自动地抓取网页内容,并从中提取有用的数据,存储到本地文件或数据库中。 Python爬虫入门教程 1. 什么是爬虫爬虫(又称网络爬虫)是一种

    2024年02月10日
    浏览(47)
  • 手机Python爬虫教程:利用手机学习Python爬虫的终极指南

    在数字化时代,手机已经成为人们生活中不可或缺的一部分。而Python爬虫作为一种强大的数据获取工具,也受到越来越多人的关注。但是,是否可以利用手机进行Python爬虫学习呢?本文将介绍如何通过手机学习Python爬虫,为你打开一扇全新的学习之门。 1. 《Python爬虫入门教程

    2024年02月07日
    浏览(52)
  • Python爬虫项目70例,附源码!70个Python爬虫练手实例

    今天博主给大家带来了一份大礼,Python爬虫70例!!!以及完整的项目源码!!! 本文下面所有的爬虫项目都有详细的配套教程以及源码,都已经打包好上传到百度云了,链接在文章结尾处! Python爬虫项目100例(一):入门级 1. CentOS环境安装 2. 和谐图网站爬取 3. 美空网数据

    2024年02月07日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包