python爬取珠海二手房房价并生成热力分布图

                            想要生成热力分布图,首先要爬取房价的数据,所以第一步,我们先把爬虫写出来。

一 确定目标URL,实现爬虫,代码如下:

import urllib.request
from urllib.request import HTTPError
import json
from multiprocessing import Pool
import lxml
import csv
from bs4 import BeautifulSoup
import requests
#数据要放到execl里,所以先新建execl文件
file = open('dc.csv', 'w', newline='',encoding='utf-8')
headers = ['name', 'pattern','area','floor',"Heading",'time','Total price','price','loc']
writers = csv.DictWriter(file, headers)
writers.writeheader()
#该函数是调用百度地图APi接口,获取经纬度
def getlocation(name):#调用百度API查询位置
    bdurl='http://api.map.baidu.com/geocoder/v2/?address='
    output='json'
    ak=''#输入你刚才申请的密匙
    callback='showLocation'
    uri=bdurl+name+'&output=t'+output+'&ak='+ak+'&callback='+callback
    res=requests.get(uri)
    s=BeautifulSoup(res.text)
    lng=s.find('lng')
    lat=s.find('lat')
    if lng:
        return lng.get_text()+','+lat.get_text()
#该函数以模拟浏览器方式登陆,获取User-Agent
def Pretend():
    headers = ("User-Agent",
               "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0")
    openera = urllib.request.build_opener()
    openera.addheaders = [headers]
    urllib.request.build_opener(openera)

#因为功能为迭代的,所以我们把爬取一个网页的逻辑封装在一个函数里
def get_one_page(url):
    try:
        response = urllib.request.urlopen(url).read().decode('utf-8')
    except HTTPError as e:
        print(e)
    return response
#该函数用正则表达式来匹配我们想要的数据
def parse_esf_price(esful):
    html = get_one_page(esful)
    pattern = re.compile(
        '<p class="house-title">.*?<a.*?>(.*?)</a>.*?<span>(.*?)</span>.*?<span>(.*?)</span>.*?<span>(.*?)</span>.*?<span>(.*?)</span>'
        + '.*?''<span>(.*?)</span>.*?<div class="show-price">.*?<span.*?>(\d+)</span><span.*?>(.*?)</span>.*?<p>(.*?)</p>',
        re.S)
    info = re.findall(pattern, html)
    for infos in info:
        yield {
            'name': infos[0],
            'pattern': infos[1],
            'area': infos[2],
            'floor': str.strip(infos[3]),
            'Heading': infos[4],
            'time': infos[5],
            'Total price': infos[6],
            'price': infos[8],
            'loc':getlocation(infos[0])
        }

def main(offset):
    url = 'http://zhuhai.qfang.com/sale/' + 'f' + str(offset)
    html = get_one_page(url)
    for item in parse_esf_price(url):
        print(item)
        writers.writerow(item)

if __name__ == '__main__':
    url = "http://zhuhai.qfang.com/"
    pool = Pool()
    pool.map(main, [i for i in range(100)])

上述代码讲以下几点:

1 ,再写爬虫之时不建议用正则表达式,可以用bs4来抓取节点,也可以用xpath来获取,xpath更加的广泛。因为网页的html源码是要改的,如果用了正则表达式,那么就不好维护,因为博主的代码是刚学爬虫时写的,没写进类里面,也没用xpath,没有时间进行改良,但是还是好用的,可以拷过去运行,前提是该有的模块都有。

2,如果不用scrapy框架,在多数据爬取时,会显得很脆弱,会很卡,所以这里用了多进程来实现。也就是Pool类。

3,多网页爬取时,要总结网页偏移的规律。来构造URL地址。也可以在网页源码中提取,看个人习惯。

4,生成热力图,离不开百度地图API,我们实现这个其实就是把小区的名字转换成经纬度。进入百度地图API官网,注册开发者账号,申请密钥。这里注意,我们最后生成的其实是一个html文件。所以在选择平台时我们要选择浏览器端。refer白名单我们填写*,填写0.0.0.0不好使。

二 申请百度API流程如下:

     网址:http://lbsyun.baidu.com/

    进入首页后,点击功能与服务,接着点击地图,再点击左侧的获取密钥,这时进入了创建应用的界面。点击创建应用,名称随便写。但是应用类别要选择浏览器端。创建完成之后 AK便是我们的密钥。

随后进入http://lbsyun.baidu.com/index.php?title=jspopular这个网址。也就是webAPI,我们点击左侧的示例demo选项。在左侧的覆盖物示例中,点击添加热力图。这时可以看出,我们最后生成的HTML文件的源码就是这个,只不过AK要改成你申请的密钥,点击运行之后才可以复制下来,这里注意几点,第一点,百度地图默认北京天安门,你要在var point = new BMap.Point(113.5832319144, 22.2763968747);  map.centerAndZoom(point, 15);  这两句代码中改。这里我改成了珠海的经纬度和城市级别。

第二:

{"lng":113.572877701,"lat":22.2852944661,"count":105},

{"lng":113.541354798,"lat":22.2702942392,"count":320},{"lng":113.553078868,"lat":22.27334793,"count":1180},

我们通过最后爬取的经纬度就是要填写到这里才行,但是由于这个格式是json的,所以我们要把execl文件里的该数据按照json数据打印到控制台中,在进行复制粘贴。

二 经纬度转换。

import csv

reader=csv.reader(open('dc.csv',encoding='utf-8'))
for row in reader:
    loc=row[8]
    sloc=loc.split(',')
    lng=''
    lat=''
    if len(sloc)==2:#第一行是列名需要做判断
        lng=sloc[0]
        lat=sloc[1]
        count=row[6]
        out='{\"lng\":'+lng+',\"lat\":'+lat+',\"count\":'+count+'},'
        print(out)

我们可以把这段代码令写一个文件里。先运行爬虫里的,生成execl之后,在运行这个py文件,就可在控制台输出json数据格式的经纬度了,这里注意 count是最后热力分布的量,你可以用任何数值来标定,这里我用的是价格,你也可以用关注度,单平米的价格来标定,在复制粘贴到你的html文件里,再点击网页,就可以生成热力图了。

展示如下:


如有不懂留言评论。














猜你喜欢

转载自blog.csdn.net/qq_33324878/article/details/80303213