百度POI数据抓取-BeautifulSoup

来源:互联网 发布:同福3队吊打棒子知乎 编辑:程序博客网 时间:2024/05/21 18:30

因为实验室项目需要上海市POI数据,百度了一圈也没有找到下载资源。于是参考了这个博客,自己手动爬取。
比较熟悉Python,所以这里分享自己写的Python版本实现过程。

获取百度POI数据的方法是构建关键词搜索url,请求url获取返回的json数据。
http://map.baidu.com/?newmap=1&reqflag=pcmap&biz=1&from=webmap&da_par=direct&pcevaname=pc4.1&qt=s&da_src=searchBox.button&wd=人民广场&c=289&pn=0
wd:搜索关键词
c:城市编码
pn:页码(返回结果可能有多页)
这种请求数据方法的好处是貌似不会有次数限制。
分两个步骤:

1、准备搜索关键词

关键词来源网站: http://poi.mapbar.com/
1)选择城市:上海
2)POI有很多分类:
这里写图片描述

我的目标是获取详细的POI关键字。
先获取每个分类的url,保存在keyword-1.txt文件中:

import urllib2import urllibfrom bs4 import BeautifulSoupimport numpy as npimport jsondef write2txt(data,filepath):    with open(filepath,'a') as f:        for d in data:            f.write(d.encode('gbk'))def example3_bs4():    request = urllib2.Request('http://poi.mapbar.com/shanghai/')    page = urllib2.urlopen(request)    data = page.read()    data = data.decode('utf-8')    soup = BeautifulSoup(data,'html.parser')    tags = soup.select('a')    res = [ t['href']+'|'+t.get_text()+'\n' for t in tags]    #print res    write2txt(res,'keyword-1.txt')

3)获取每个分类下详细的POI关键字
每个分类下有更详细的POI数据:
这里写图片描述
关键字保存在keyword-2.txt文件中

def getKeyWords():    with open('keyword-1.txt') as f:        for line in f:            url,wd=line.decode('gbk').split('|')            print url,wd            request = urllib2.Request(url)            page = urllib2.urlopen(request)            data = page.read().decode('utf-8')            soup = BeautifulSoup(data,'html.parser')            tags = soup.select('dd a')            res = [wd[:-1]+'|'+t['href']+'|'+t.get_text()+'\n' for t in tags]            print len(res)            write2txt(res,'keyword-2.txt')

2、模拟关键词搜索

构造类似这样:
http://map.baidu.com/?newmap=1&reqflag=pcmap&biz=1&from=webmap&da_par=direct&pcevaname=pc4.1&qt=s&da_src=searchBox.button&wd=人民广场&c=289&pn=0
的url。
可以在浏览器查看这个url返回的结果,并用在www.json.com查看json串的结构:
这里写图片描述
我需要的信息在content中,可以看到content里面是一个数组,里面的每一个object都是一个poi信息,10个object为1页。如果需要多页的话,可以在url中令pn=页码。
我这里只用了第一页。

def getPOI():    with open('keyword-2.txt') as f:        for line in f:            data = []            Type,url,wd = line[:-1].split(',')            #print Type,url,wd            url = 'http://map.baidu.com/?newmap=1&reqflag=pcmap&biz=1&from=webmap&da_par=direct&pcevaname=pc4.1&qt=s&da_src=searchBox.button&wd=%s&c=289&pn=0'%urllib.quote(wd)            request = urllib2.Request(url)            try:                page = urllib2.urlopen(request)                res = json.load(page)                if 'content' in res:                    contents = res['content']                    if 'acc_flag' in contents[0]:                        for d in contents:                            x, y = float(d['diPointX']), float(d['diPointY'])                            ss = "http://api.map.baidu.com/geoconv/v1/?coords=%s,%s&from=6&to=5&ak=你的开发者秘钥"%(x/100.0,y/100.0)                            pos = json.load(urllib2.urlopen(ss))                            if pos['status']==0:                                x, y = pos['result'][0]['x'], pos['result'][0]['y']                            tel = ''                            if 'tel' in d:                                tel = d['tel']                            data.append(d['addr']+'|'+d['area_name']+'|'+d['di_tag']+'|'+d['std_tag']+'|'+tel+'|'+d['name']+'|'+str(x)+'|'+str(y)+'\n')                if data:                    write2txt(data,'poi_info.txt')            except:                print 'http error'

需要注意的是,这里的坐标转换api,需要申请百度开发者秘钥,而且每天转换次数限额10万。

我最后只抓取了18万条POI数据,项目也够用啦。

参考博客:
获取百度地图POI数据:http://www.cnblogs.com/yumubaime/p/7258796.html

原创粉丝点击