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)
scrapy百度POI爬虫实战项目代码(二)
最新推荐文章于 2021-01-20 20:21:01 发布