scrapy百度POI爬虫实战项目代码(二)

mapbar.py 爬虫文件--------------------------------
import scrapy
from mapbarSpider.items import AddressItem
from copy import deepcopy
from mapbarSpider.geocode_2 import BaiDuMercatorToWgs84
from mapbarSpider.geocode import Geocoding
import json
#全国各城市地名抓取,包含街道、村落、小区、商店、景点等等内容
class MapbarSpider(scrapy.Spider):
    name = 'mapbar'
    baidumecator_wgs84=BaiDuMercatorToWgs84()
    bd09_gcj02_wgs84=Geocoding("api_key")
    allowed_domains = ['poi.mapbar.com','map.baidu.com']
    start_urls = ['https://poi.mapbar.com/beijing/']
    #待修改?????? 改为爬虫程序启动时动态传入参数
    city_code="131"
    city_name="北京市"
    resp_items_list=[]#1000条批量插入缓存集合
    itemkeys=""#存放表行记录的字段名称
    #开启start_urls队列
    def parse(self, response):
        #返回的内容是个页面
        #获取大分类集合root_sort(如旅游景点)的标签
        root_sort=response.xpath('//div[@class="isortRow"]//h3')
        #获取大分类(如旅游景点)下的小分类(游乐园、植物园......等)的标签
        item_sort = response.xpath('//div[@class="isortRow"]//div[@class="isortBox"]')
        #print(len(root_sort))
        #print(len(item_sort))
        #大分类+大分类的小分类标签中的信息提取
        #print(root_sort[0].xpath('text()').extract()[1])
        for i in range(len(root_sort)):
            #大分类名称
            root_name=root_sort[i].xpath('text()').extract()[1].strip()
            #大分类下的小分类集合
            #print(item_sort[i])
            item_sort_infos=item_sort[i].xpath('./a')
            #print(len(item_sort_infos))
            for isinfo in item_sort_infos:
                item=AddressItem()
                item['city_code']=self.city_code
                item['city_name']=self.city_name
                item['root_sort']=root_name
                item['item_sort']=isinfo.xpath('@title').extract_first()
                item['item_href']=isinfo.xpath('@href').extract_first() #"https://poi.mapbar.com/beijing/110/"#isinfo.xpath('@href').extract_first()
                yield scrapy.Request(item['item_href'],callback=self.information_analysis,
                                        meta = {'item_info' :deepcopy(item),'page_next':2}, 
                                        dont_filter=True)
    #解析包含关键词的页面信息
    def information_analysis(self, response):
        #获取当前信息类AddressItem前部分信息
        #print("---------"+str(response.status))
        item_info = response.meta['item_info']
        page_next=response.meta['page_next']
        #print(page_next)
        #print(page_next is None)
        #解析当前小分类下的所有POI地址,补齐地址信息类AddressItem参数,并入库sqlite
        pois=response.xpath('//div[@class="sortC"]//dl//dd//a')
        #print(len(pois))
        for poi in pois:
            item_info['address_name']=poi.xpath('text()').extract_first()
            wd=item_info['item_sort']+item_info['address_name']
            #item_info['address_lon']="0.0"
            #item_info['address_lat']="0.0"
            poi_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="+wd+"&c="+item_info['city_code']+"&pn=0"
            yield scrapy.Request(poi_url,callback=self.baidupoi_analysis,
                                        meta = {'item_info' : deepcopy(item_info)}, 
                                        dont_filter=True)
        

    #是否还有下一页 如果页码超过了实际页码 则此次页码请求自动终止,不会再次进入information_analysis方法
    #如果当前有分页继续进行当前方法调用 js动态生成了页码 所以获取不到只能页码第加
    #pages=response.xpath('//div[@class="sortC"]//div[@id="pageDiv"]').extract()
    last_index_char=""
    if page_next ==2:
        last_index_char=item_info['item_href'].rindex('/')
        page_next_href=item_info['item_href'][:last_index_char]+'_'+str(page_next)
        #print(page_next_href)
    else:
        last_index_char=item_info['item_href'].index('_')
        page_next_href=item_info['item_href'][0:last_index_char+1]+str(page_next)
        #print("---"+page_next_href)
    item_info['item_href']=page_next_href
    yield scrapy.Request(page_next_href,callback=self.information_analysis,
                                    meta = {'item_info' : deepcopy(item_info),'page_next':deepcopy(page_next)+1},
                                    dont_filter=True)
    
#根据关键词和citycode进行百度关键词经纬度信息获取
def baidupoi_analysis(self, response):
    item_info=response.meta['item_info']
    body_to_json=json.loads(response.body)
    #place_info=body_to_json['place_info']
    #wd=place_info['search_ext'][0]['wd']
    wd=item_info['address_name']
    #判断返回数据是否包含content
    if  'content' in body_to_json:
        #完全找到  如果没有完全匹配的 待完善?????? 选取第一个信息的坐标作为最后结果
        content=body_to_json['content']
        for cnt in content:
            if cnt['name']==wd or wd in cnt['name']:
                item_info['address_name']=cnt['name']
                item_info['area_name']=cnt['area_name']
                item_info['uid']=cnt['uid']
                item_info['address_addr']=cnt['addr']
                #item_info['address_lon']=cnt['x']
                #item_info['address_lat']=cnt['y']
                #进行经纬度纠偏
                #百度墨卡托转百度经纬度
                lng,lat=self.baidumecator_wgs84.Mercator2BD09(cnt['x']/100,cnt['y']/100)
                # 百度坐标系->火星坐标系
                result2 = self.bd09_gcj02_wgs84.bd09_to_gcj02(lng, lat) 
                # 火星坐标系->WGS84坐标系 
                item_info['address_lon'],item_info['address_lat'] = self.bd09_gcj02_wgs84.gcj02_to_wgs84(result2[0], result2[1])
                if self.itemkeys is None or self.itemkeys == "":
                    self.itemkeys = item_info.keys()
                #
                self.resp_items_list.append(tuple(item_info.values()))
                yield deepcopy(item_info)
                break
            else:
                pass
                """ item_info['address_name']=cnt['name']
                item_info['area_name']=cnt['area_name']
                item_info['uid']=cnt['uid']
                item_info['address_addr']=cnt['addr']
                #item_info['address_lon']=cnt['x']
                #item_info['address_lat']=cnt['y']
                #进行经纬度纠偏
                #百度墨卡托转百度经纬度
                lng,lat=self.baidumecator_wgs84.Mercator2BD09(cnt['x']/100,cnt['y']/100)
                # 百度坐标系->火星坐标系
                result2 = self.bd09_gcj02_wgs84.bd09_to_gcj02(lng, lat) 
                # 火星坐标系->WGS84坐标系 
                item_info['address_lon'],item_info['address_lat'] = self.bd09_gcj02_wgs84.gcj02_to_wgs84(result2[0], result2[1])
                yield deepcopy(item_info) """
    else:
        pass
        #查不到任何数据则直接入库现有的字段信息
        #yield deepcopy(item_info)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值