Gaode POI 관심 지점에 대한 자세한 정보 얻기


아이디어 소개:

AutoNavi POI 관심지점 획득은 크게 두 부분으로 나뉘는데, 먼저 특정 도시의 모든 교량 정보를 획득하는 등 AutoNavi 지도에서 검색하고자 하는 관심지점의 데이터를 크롤링합니다. 도시 지역 내의 모든 다리 정보를 얻을 수 있습니다., 둘째, 획득한 디렉토리를 Baidu Encyclopedia로 사용하여 항목의 상세 데이터를 크롤링합니다.

1. Gaode 지도의 POI 데이터 획득

검색 POI 개발 문서 에서 데이터 정보를 얻는 방법을 볼 수 있습니다 .

첫 번째 단계는 "웹 서비스 API" 키(Key)를 신청하는 것입니다.

먼저 다양한 클라이언트에 적용할 수 있는 POI의 개방형 방식을 제공하는 AutoNavi Open Platform 에서 제공 하는 API 인터페이스를 찾아보세요.
응용 프로그램 관리를 찾아 나중에 요청을 보내는 데 사용할 키를 추가합니다.
여기에 이미지 설명 삽입

두 번째 단계는 HTTP 요청 URL을 연결하는 것으로 첫 번째 단계에서 적용한 Key를 필수 매개변수로 함께 보내야 합니다.

요청 전송 URL:
https://restapi.amap.com/v3/place/text?keywords=Keywords enter &city=beijing&output=xml&offset=20&page=1&key=<user's key>&extensions=all 키워드 및 유형을 지정할 수 있습니다
. 영역 또는 어떤 유형의 POI.
다른 도시 지역 및 건물 유형의 코드는 문서에서 얻을 수 있습니다.
여기에 이미지 설명 삽입

URL을 연결하는 코드는 다음과 같습니다.

# 各下级行政区的代码,不要选择市区的代码,否则会出现问题
arr = [
    '540102', '540103', '540104', '540121', '540122', '540123', '540124', '540127',
    '540202', '540221', '540222', '540223', '540224', '540225', '540226', '540227', '540228', '540229', '540230',
    '540231', '540232', '540233', '540234', '540235', '540236', '540237',
    '540302', '540321', '540322', '540323', '540324', '540325', '540326', '540327', '540328', '540329', '540330',
    '540402', '540421', '540422', '540423', '540424', '540425', '540426',
    '540502', '540521', '540522', '540523', '540524', '540525', '540526', '540527', '540528', '540529', '540530',
    '540531',
    '540602', '540621', '540622', '540623', '540624', '540625', '540626', '540627', '540628', '540629', '540630',
    '542521', '542522', '542523', '542524', '542525', '542526', '542527'
]
# API的URL,在这里进行了结构化处理
url1 = "https://restapi.amap.com/v3/place/text?keywords=桥&types=190307&city="
url2 = "&output=JSON&offset=20&key=4f981956ab23875a4636f9418832e54f&extensions=all&page="

# 用于储存数据
x = []
# 用于计数
num = 0
# 190307	地名地址信息	交通地名	桥

세 번째 단계는 HTTP 요청에서 반환된 데이터(JSON 또는 XML 형식)를 수신하고 데이터를 구문 분석하는 것입니다.

관계자는 반환되는 POI 데이터의 수를 제한하며 최대 900개까지만 얻을 수 있습니다. 따라서 논리는 판단을 추가합니다.

# 循环各下级行政区进行POI检索
for i in range(0, len(arr)):
    # 当前行政区
    city = arr[i]
    # 因为官方对API检索进行了45页限制,所以只要检索到45页即可
    for page in range(1, 46):
        # 若该下级行政区的POI数量达到了限制,则警告使用者,之后考虑进行POI类型切分
        if page == 45:
            print("警告!!POI检索可能受到限制!!")
        # 构造URL
        thisUrl = url1 + city + url2 + str(page)
        # 获取POI数据
        data = requests.get(thisUrl)
        sleep(1)
        # 转为JSON格式
        s = data.json()
        # 解析JSON
        aa = s["pois"]
        # 若解析的JSON为空,即当前行政区的数据不够45页(即没有达到限制),返回
        if len(aa) == 0:
            break
        # 对每条POI进行存储
        for k in range(0, len(aa)):
            s1 = aa[k]["name"]
            s2 = aa[k]["type"]
            s3 = aa[k]["adname"]
            x.append([s1, s2, s3])
            num += 1
            print("爬取了 " + str(num) + " 条数据")

# 将数据结构化存储至规定目录的xls文件中
c = pd.DataFrame(x)
c.to_csv('./getEXCELS/西藏桥梁汇总.xls', encoding='utf-8-sig')

둘째, 획득한 모든 POI 데이터를 디렉토리로 사용하여 상세 정보 크롤링

첫 번째 단계는 Excel 파일의 데이터를 읽는 것입니다.

여기서는 xlrd 플러그인이 사용되며, 획득한 데이터는 목록으로 반환됩니다.

import xlrd
# 从Excel中获取名字,组装URL
def getBridgeNames():
	# 打开一个excel
    book = xlrd.open_workbook("getEXCELS/西藏桥梁汇总.xls")
    # 打开excel中的哪一个sheet页
    sheet = book.sheet_by_index(0)
    # 获取名字的一列数据
    bridge_names = sheet.col_values(1)
    return bridge_names

두 번째 단계는 요청 헤더 정보를 캡슐화하는 것입니다.

목록에서 요청 헤더를 무작위로 가져옵니다.

import random
user_agents = ['Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
               'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
               'Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11',
               'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/1.0.154.50 Safari/525.19',
               'Mozilla/5.0 (Windows; U; Windows NT 6.0; de) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13']
def get_header():
    header = {
    
    'User-Agent': random.choice(user_agents)}
    return header

3단계, 세부 정보 요청 보내기

여기에 문제가 있습니다 . (아직 해결되지 않음)
Baidu Encyclopedia는 다른 키워드에 대한 검색 항목에 대해 다른 형식을 가질 수 있습니다. 예를 들어 Liuwu Bridge 및 Lhasa Bridge에 대한 검색 항목의 형식이 다를 수 있거나 Baidu Encyclopedia를 충족합니다. 데이터에 대한 키워드가 없습니다.
그러나 페이지를 얻을 때 형식을 통일할 수 있는 방법이 없기 때문에 일부 정보를 얻을 수 없다.예를 들어 그림의 일부 속성은 다리 길이라고 하지만 다른 속성은 길이이다.
여기에 이미지 설명 삽입
여기에 이미지 설명 삽입

여기에 이미지 설명 삽입
항목을 구문 분석하는 코드는 다음과 같으며 최종적으로 모든 데이터를 목록으로 반환합니다.

def getInfo(url, bridge_name):
    # 获取代理ip
    # proxies = ipGetter.ipGet()
    # 拿到网页text数据
    html_text = requests.get(url, headers=getHeaders.get_header()).text
    # print(html_text)
    # 加载进内存用来解析网页html数据
    html_data = etree.HTML(html_text)
    # 获取词条属性信息
    base_title = html_data.xpath('//dl[contains(@class,"basicInfo")]/dt//text()')
    base_info = html_data.xpath('//dl[contains(@class,"basicInfo")]/dd')
    # 存放基础信息的列表
    info = []
    for element in base_info:
        info.append(''.join(str.strip() for str in element.xpath('.//text()')))
    # 将基础信息存放到字典里
    info_dict = dict(zip(base_title, info))

    # 创建一个列表 存放本次url的获取到的信息
    # 加入中文名
    tmp_info = [bridge_name]
    # 英文名
    english_name = info_dict.get("外文名", "")
    tmp_info.append(english_name)
    # 始建时间
    build_time = info_dict.get("始建时间", "")
    tmp_info.append(build_time)
    # 投用时间
    use_time = info_dict.get("投用时间", "")
    tmp_info.append(use_time)
    # 所属地区
    address = info_dict.get("所属地区", "")
    tmp_info.append(address)
    # 类型
    bridge_type = info_dict.get("类\xa0\xa0\xa0\xa0型", "")
    tmp_info.append(bridge_type)
    # 长度
    length = info_dict.get("长\xa0\xa0\xa0\xa0度", "")
    tmp_info.append(length)
    # 宽度
    width = info_dict.get("宽\xa0\xa0\xa0\xa0度", "")
    tmp_info.append(width)
    # 车道规模
    lane_size = info_dict.get("车道规模", "")
    tmp_info.append(lane_size)
    # 设计速度
    speed = info_dict.get("设计速度", "")
    tmp_info.append(speed)
    # 起止位置
    start_stop_position = info_dict.get("起止位置", "")
    tmp_info.append(start_stop_position)
    # 途径线路
    route = info_dict.get("途经线路", "")
    tmp_info.append(route)
    # 管理机构
    manage_org = info_dict.get("管理机构", "")
    tmp_info.append(manage_org)

    # 获取简介

    content_text = html_data.xpath('//div[@class="lemma-summary"]//text()')
    if len(content_text) == 0 :
        tmp_info.append("")
    else:
        content = ''.join([con.strip() for con in content_text])
        tmp_info.append(content)

    # 获取img图片信息
    try:
        img = "https://baike.baidu.com" + html_data.xpath('//a[@class="more-link"]/@href')[0]
        tmp_info.append(img)
    except Exception as e:
        tmp_info.append("")

    # 加入到列表汇总
    bridge_info.append(tmp_info)

네 번째 단계, 데이터 저장

취득한 데이터를 엑셀로 저장

# 保存数据
def saveData(dataList, savePath):
    # 建立一个excel文档
    book = xlwt.Workbook(encoding='utf-8', style_compression=0)
    # 建立一个sheet页
    sheet = book.add_sheet("西藏桥梁汇总", cell_overwrite_ok=True)
    cols = ["中文名", "英文名", "始建时间", "投用时间", "所属地区", "类型", "长度", "宽度", "车道规模", "设计速度", "起止位置", "途径线路", "管理机构", "简介", "图片链接"]
    # 写入标题行
    for i in range(15):
        sheet.write(0, i, cols[i])

    # 写入数据
    for i in range(0, len(dataList)):
        data = dataList[i]
        for j in range(15):
            sheet.write(i+1, j, data[j])
    book.save(savePath)

효과 표시 및 요약

최종 엑셀 문서의 스타일:
여기에 이미지 설명 삽입
null 값 원인:
1. 항목이 Baidu 백과사전에 존재하지 않습니다.
2. 이 속성은 항목에 존재하지 않습니다.
3. 항목의 속성 이름이 다릅니다.

기존 문제는 주로 다음과 같습니다.
1. 항목에 존재하지 않는 키워드 정보를 얻는 방법.
2. 항목의 속성 형식이 일정하지 않아 동일한 정보 형식을 얻을 수 없습니다.

Supongo que te gusta

Origin blog.csdn.net/qq_40745994/article/details/124284804
Recomendado
Clasificación