租房子看“肥学”⚡依托某地图和爬虫找房⚡(python知识学习)

Posted 肥学大师

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了租房子看“肥学”⚡依托某地图和爬虫找房⚡(python知识学习)相关的知识,希望对你有一定的参考价值。

导读

随着学业的增加和年纪的增加,我逐渐开始关注大学生毕业工作后找工作的经历。在我的了解过程中我就发现了一点。一些大城市的大学生在租房子的时候会遇到一些困难。现在又在秋招的季节然后我就想用我的知识来写点东西。下面我们进入主题。


最近整理了几个专栏欢迎大家订阅呀

⚜️肥学刚建了连个专栏一个适合小白练手:编程小白进阶
⚜️还有适合小白进阶的项目:练手项目
⚜️适合Java学习的进阶者:javaWeb进厂必刷为保证质量目前还在更新中
.
.
.

🗼开干

先来给大家看一下效果图:

解释:图中地图为上海市的地图(不局限于上海市),图上蓝色地标为可以租住房的位置和带有超链接的房源名字 点进去就会得到详细介绍

在选择好工作地点地点后还能为你从住的地方导航:

🗼详解调用地图API

🗼主题部分html

对于HTML部分都是基础知识。这里没有什么高深的大家不会也不要紧官方给的页面框架实例直接赋值就可以了链接


<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta
      name="viewport"
      content="initial-scale=1.0, user-scalable=no, width=device-width"
    />
    <title>肥学租房</title>
    <link
      rel="stylesheet"
      href="http://cache.amap.com/lbs/static/main1119.css"
    />
    <link
      rel="stylesheet"
      href="http://cache.amap.com/lbs/static/jquery.range.css"
    />
    <script src="http://cache.amap.com/lbs/static/jquery-1.9.1.js"></script>
    <script src="http://cache.amap.com/lbs/static/es5.min.js"></script>
    <script src="http://webapi.amap.com/maps?v=1.3&key=36aa77404a1c2f2fc922a569eaa49422&plugin=AMap.ArrivalRange,AMap.Scale,AMap.Geocoder,AMap.Transfer,AMap.Autocomplete"></script>
    <script src="http://cache.amap.com/lbs/static/jquery.range.js"></script>
    <style>
      /*面板控制样式*/
      .control-panel {
        position: absolute;
        top: 30px;
        right: 20px;
      }
      /*面板内容样式*/
      .control-entry {
        width: 280px;
        background-color: rgba(119, 136, 153, 0.8);
        font-family: fantasy, sans-serif;
        text-align: left;
        color: white;
        overflow: auto;
        padding: 10px;
        margin-bottom: 10px;
      }
      /*文字与右侧的距离*/
      .control-input {
        margin-left: 120px;
      }
      /*输入框宽度*/
      .control-input input[type='text'] {
        width: 160px;
      }
      /*文字样式*/
      .control-panel label {
        float: left;
        width: 120px;
      }
      /*路线规划信息窗体样式*/
      #transfer-panel {
        position: absolute;
        background-color: white;
        max-height: 80%;
        overflow-y: auto;
        top: 30px;
        left: 20px;
        width: 250px;
      }
    </style>
  </head>

  <body>
    <div id="container"></div>
    <!--显示输入地址面板-->
    <div class="control-panel">
      <div class="control-entry">
        <label>选择工作地点:</label>
        <div class="control-input">
          <input id="work-location" type="text" />
        </div>
      </div>
      <!--显示选择交通的面板-->
      <div class="control-entry">
        <label>选择通勤方式:</label>
        <div class="control-input">
          <input
            type="radio"
            name="vehicle"
            value="SUBWAY,BUS"
            onClick="takeBus(this)"
            checked
          />
          公交+地铁
          <input
            type="radio"
            name="vehicle"
            value="SUBWAY"
            onClick="takeSubway(this)"
          />
          地铁
        </div>
      </div>
      <!--显示导入房源的面板-->
      <div class="control-entry">
        <label>导入房源文件:</label>
        <div class="control-input">
          <input type="file" name="file" onChange="importRentInfo(this)" />
        </div>
      </div>
    </div>
    <div id="transfer-panel"></div>
    <script>
      //地图部分
      var map = new AMap.Map('container', {
        resizeEnable: true, //页面可调整大小
        zoomEnable: true, //可缩放
        center: [121.32, 30.965], //地图中心,这里使用的是上海的经纬度
        zoom: 11, //缩放等级,数字越大离地球越近
      });
    </script>
  </body>
</html>

上面有部分的代码已经给出了详细解释,不知道大家有没有看过csdn热销的那本书《开发者黄金十年》其中谈到三种运营模式攻入开发者壁垒中有一种讲的就是API它极大的方便了程序的开发。用过API的大佬肯定都知道API不可能让你白用的,哈哈。这种限制方式就是要从平台获取key值,这次也不例外

<script src="http://webapi.amap.com/maps?v=1.3&key=36aa77404a1c2f2fc922a569eaa49422&plugin=AMap.ArrivalRange,AMap.Scale,AMap.Geocoder,AMap.Transfer,AMap.Autocomplete"></script>

我们来说一下怎么获取,以免有大佬是第一次玩API

  • 🗼1·首先先注册账户链接
  • 🗼2·完成完善资料,包括开发者认证,邮箱认证,电话认证等,如实填写即可
  • 🗼3·点击右上角控制台,创建应用,应用信息根据自己的实际填写
    .
    .

    .
    .
  • 🗼4·创建完应用后点击右上角的“+”号就创建应用的 Key,使用地图是根据开发文档把相应位置的 key 值换成自己的

.

.

🗼小bug

其实这个时候是地图是加载不出来的,因为这是因为 https 页面里动态的引入 http 资源,比如引入一个 JS 文件,会被直接 block 掉的,在 https 页面里通过 AJAX 的方式请求 http 资源,也会被直接 block 掉的。解决办法是,在页面的 head 标签中加入:

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"/>

意思是自动将 http 的不安全请求升级为 https

🗼调用API

这套API其实已经解释的很清楚了,另外大家要是想多了解一点可以去看看参考手册:链接

var map = new AMap.Map('container', {
  resizeEnable: true,
  zoomEnable: true,
  center: [116.397428, 39.90923],
  zoom: 11,
});
//添加标尺
var scale = new AMap.Scale();
map.addControl(scale);
//经度、纬度、时间、通勤方式(默认是地铁+公交)
var arrivalRange = new AMap.ArrivalRange();
var x,
  y,
  t,
  vehicle = 'SUBWAY,BUS';
//工作地点,工作标记
var workAddress, workMarker;
//房源标记数组
var rentMarkerArray = [];
//多边形数组,存储到达范围的计算结果
var polygonArray = [];
//路线规划
var amapTransfer;
//信息窗体对象
var infoWindow = new AMap.InfoWindow({
  offset: new AMap.Pixel(0, -30),
});
//地址自动补全对象
var auto = new AMap.Autocomplete({
  input: 'work-location',
});
//添加事件监听,在选择完地址后调用workLocationSelected
AMap.event.addListener(auto, 'select', workLocationSelected);
function takeBus(radio) {
  vehicle = radio.value;
  loadWorkLocation();
}

function takeSubway(radio) {
  vehicle = radio.value;
  loadWorkLocation();
}
//导入房源信息触发的方法
function importRentInfo(fileInfo) {
  //获取房源文件名称
  var file = fileInfo.files[0].name;
  loadRentLocationByFile(file);
}
//选择工作地点后触发的方法
function workLocationSelected(e) {
  //更新工作地点,加载到达范围
  workAddress = e.poi.name;
  //调用加载1小时到达区域的方法
  loadWorkLocation();
}
//加载工作地点标记
function loadWorkMarker(x, y, locationName) {
  workMarker = new AMap.Marker({
    map: map,
    title: locationName,
    icon: 'http://webapi.amap.com/theme/v1.3/markers/n/mark_r.png',
    position: [x, y],
  });
}
//加载到达范围
function loadWorkRange(x, y, t, color, v) {
  arrivalRange.search(
    [x, y],
    t,
    function (status, result) {
      if (result.bounds) {
        for (var i = 0; i < result.bounds.length; i++) {
          //多边形对象
          var polygon = new AMap.Polygon({
            map: map,
            fillColor: color, //填充色
            fillOpacity: '0.4', //透明度
            strokeColor: color,
            strokeOpacity: '0.8',
            strokeWeight: 1, //线宽
          });
          //到达范围的多边形路径
          polygon.setPath(result.bounds[i]);
          //增加多边形
          polygonArray.push(polygon);
        }
      }
    },
    {
      policy: v,
    }
  );
}
//添加房源标记
function addMarkerByAddress(address) {
  //地理编码对象
  var geocoder = new AMap.Geocoder({
    city: '上海',
    radius: 1000,
  }); 
  //获取位置
  geocoder.getLocation(address, function (status, result) {
    if (status === 'complete' && result.info === 'OK') {
      //获取地理编码
      var geocode = result.geocodes[0];
      //标记对象
      rentMarker = new AMap.Marker({
        map: map, //显示标记的地图
        title: address, //鼠标移动至标记时所显示的文字
        //标记图标地址
        icon: 'http://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
        //位置
        position: [geocode.location.getLng(), geocode.location.getLat()],
      });
      rentMarkerArray.push(rentMarker);
      //相关房源网络地址
      rentMarker.content =
        "<div>房源:<a target = '_blank' href='https://bj.58.com/pinpaigongyu/?key=" +
        address +
        "'>" +
        address +
        '</a><div>';
      //标记的事件处理
      rentMarker.on('click', function (e) {
        //设置信息窗体显示的内容
        infoWindow.setContent(e.target.content);
        infoWindow.open(map, e.target.getPosition());
        //路线规划是否清除
        if (amapTransfer) amapTransfer.clear();
        //换乘对象
        amapTransfer = new AMap.Transfer({
          map: map,
          policy: AMap.TransferPolicy.LEAST_TIME,
          city: '上海市',
          panel: 'transfer-panel',
        });
        //根据起、终点坐标查询换乘路线
        amapTransfer.search(
          [
            {
              keyword: workAddress,
            },
            {
              keyword: address,
            },
          ],
          function (status, result) {}
        );
      });
    }
  });
}
//清除已有的到达区域
function delWorkLocation() {
  if (polygonArray) map.remove(polygonArray);
  if (workMarker) map.remove(workMarker);
  polygonArray = [];
}
//清除现有的房源标记
function delRentLocation() {
  if (rentMarkerArray) map.remove(rentMarkerArray);
  rentMarkerArray = [];
}
//加载1小时到达区域
function loadWorkLocation() {
  //清除已有的到达区域
  delWorkLocation();
  //创建地址坐标对象
  var geocoder = new AMap.Geocoder({
    city: '上海',
    radius: 1000,
  });
//获取位置
geocoder.getLocation(workAddress, function (status, result) {
  if (status === 'complete' && result.info === 'OK') {
    var geocode = result.geocodes[0]; //获取地址编码
    x = geocode.location.getLng(); //经度
    y = geocode.location.getLat(); //纬度
    //加载工作地点标记
    loadWorkMarker(x, y);
    //加载工作地点1小时内到达的范围
    loadWorkRange(x, y, 60, '#3f67a5', vehicle);
    //地图移动到工作地点的位置
    map.setZoomAndCenter(12, [x, y]);
  }
});
}
//加载房源位置
function loadRentLocationByFile(fileName) {
//清除现有的房源标记
delRentLocation();
//所有的地点都记录在集合中
var rent_locations = new Set();
//获取文件中的房源信息
$.get(fileName, function (data) {
  //分割信息
  data = data.split('\\n');
  //遍历房源位置
  data.forEach(function (item, index) {
    rent_locations.add(item.split(',')[1]);
  });
  rent_locations.forEach(function (element, index) {
    //加上房源标记
    addMarkerByAddress(element);
  });
});
}

其中有点我提一下

rentMarker.content =
  "<div>房源:<a target = '_blank' href='https://bj.58.com/pinpaigongyu/?key=" +
  address +
  "'>" +
  address +
  '</a><div>';

这一句会被显示在信息窗体上。链接指向 58 品牌公寓馆的搜索页面,搜索的地址就是点标记(房源)的地址。

🗼爬虫篇

有关爬虫以后在这个专栏会经产见到,因为确实有爬虫能做好多事情链接
主要用到的库

from bs4 import BeautifulSoup # 网页解析模块
import requests # 网络请求模块
import csv # csv 文件模块
import time
import lxml

都是爬虫常用库要是有什么不懂可以问我,关于Beautifuloup库我找了一篇不错的文:链接,博主也是个很不错的大佬专注于python爬虫领域以及web方向。

from bs4 import BeautifulSoup
import requests
import csv
import time
import lxml

url = "https://sh.58.com/pinpaigongyu/pn/{page}/?minprice=2000_4000"#上海公寓查询链接

header={
    'Referer': 'https://bj.58.com/',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36'
}
# 已完成的页数序号,初时为0
page = 0

csv_file = open("rent.csv", "w",encoding='utf-8')
csv_writer = csv.writer(csv_file, delimiter=',')#以,分割

while True:
    page += 1
    print("fetch: ", url.format(page=page))
    time.sleep(1)
    response = requests.get(url.format(page=page),headers=header)
    html = BeautifulSoup(response.text, features="lxml")
    house_list = html.select(".list > li")

    # 循环在读不到新的房源时结束
    if not house_list:
        break

    for house in house_list:
        house_title = house.select("h2")[0].string
        house_url = house.select("a")[0]["href"]
        house_info_list = house_title.split()

        # 如果第二列是公寓名则取第一列作为地址
        if "公寓" in house_info_list[1] or "青年社区" in house_info_list[1]:
            house_location = house_info_list[0]
        else:
            house_location = house_info_list[1]

        house_money = house.select(".money")[0].select("b")[0].string
        csv_writer.writerow([house_title, house_location, house_money, house_url])

csv_file.close()

我就不一步步解释了,上面有注释。有什么不明白可以随时问。要注意保存的.csv文件的用处是导入主页的选择文件的。

源码

<html>
<!--使用高德地图API-->
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
    <title>肥学租房</title>
    <link rel="stylesheet" href="http://cache.amap.com/lbs/static/main1119.css" />
    <link rel="stylesheet" href="http://cache.amap.com/lbs/static/jquery.range.css" />
    <script src="http://cache.amap.com/lbs/static/jquery-1.9.1.js"></script>
    <script src="http://cache.amap.com/lbs/static/es5.min.js"></script>
    <script src="http://webapi.amap.com/maps?v=1.3&key=36aa77404a1c2f2fc922a569eaa49422&plugin=AMap.ArrivalRange,AMap.Scale,AMap.Geocoder,AMap.Transfer,AMap.Autocomplete"></script>
    <script src="http://cache.amap.com/lbs/static/jquery.range.js"></script>
    <style>
    .control-panel {
        position: absolute;
        top: 30px;
        right: 20px;
    }

    .control-entry {
        width: 280px;
        background-color: rgba(119, 136, 153, 0.8);
        font-family: fantasy, sans-serif;
        text-align: left;
        color: black;
        overflow: auto;
        padding: 10px;
        margin-bottom: 10px;
    }

    .control-input {
        margin-left: 120px;
    }

    .control-input input[type="text"] {
        width: 160px;
    }

    .control-panel label {
        float: left;
        width: 120px;
    }

    #transfer-panel {
        position: absolute;
        background-color: white;
        max-height: 80%;
        overflow-y: auto;
        top: 30px;
        left: 20px;
        width成都58同城快速租房的爬虫,nodeJS爬虫

租房子

设计模式——租房子中的中介者模式

租房子练习

php租房子批量搜索例题

租房子查询练习