V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
answershuto
V2EX  ›  分享创造

爬虫租房

  •  
  •   answershuto ·
    answershuto · 2017-04-02 22:28:18 +08:00 · 3200 次点击
    这是一个创建于 2789 天前的主题,其中的信息可能已经有所发展或是发生改变。

    先上一个源代码吧。

    https://github.com/answershuto/Rental

    欢迎指导交流。


    效果图

    img

    img

    img

    img

    搭建 Node.js 环境及启动服务

    安装 node 以及 npm ,用 express 模块启动服务,加入自己所需要的中间件即可,这个不是本文所要讨论的重点,可以参考网上的一些教程搭建环境。


    获取导航页 URL 以及数据

    打开 58 同城主页,我主要针对杭州的二手房进行了爬取分析,所以进入杭州租房。

    http://hz.58.com/chuzu/pn1/?key=%E6%9D%AD%E5%B7%9E%E7%A7%9F%E6%88%BF%E5%AD%90&cmcskey=%E7%A7%9F%E6%88%BF%E5%AD%90&final=1&PGTID=0d3090a7-0004-f43c-ee04-95c2ea3d031f&ClickID=6

    可以得到这一串 URL ,上下页查看后就不难发现, pn 后面的数字就是页面的页码,?后面的是一些 get 请求带带参数。用一个函数即可通过页码得到正确的 URL 。

    function getUrl(page = 1){
    	return  'http://hz.58.com/chuzu/pn'+page+'/?key=%E6%9D%AD%E5%B7%9E%E7%A7%9F%E6%88%BF%E5%AD%90&cmcskey=%E7%A7%9F%E6%88%BF%E5%AD%90&final=1&PGTID=0d3090a7-0004-f43c-ee04-95c2ea3d031f&ClickID=6';
    }
    

    根据上面的 URL 我们就可以访问到每一页的所有租房信息

    img


    用 cheerio 模块解析 dom

    安装 cheerio 模块,使用 cheerio 模块解析 dom ,然后就可以类似 jquery 一样访问 dom 了。

    var cheerio = require('cheerio');
    let $ = cheerio.load(html);
    

    获取每个租房信息的 URL

    打开开发者模式, osX ( option + command + I ), windows ( F12 ),然后就可以在 elements 中看到文档结构了。(这里以 chrome 为例)

    img

    可以看到对应的 a 标签,我们只需要提取出该 url 即可,及对应的 href ,就是它点击跳转的 URL 。

    <a href="http://jump.jinpai.58.com/service?target=INKicKZPP1UEhIHuBQyP3HVk6MOpffA1WNsEqTYuc2Gxa8zCQdEBOnSPwy7LRseGN-7sgB3XvvZTQ9JsSXvXBXOVP5s7-iWzO-jZ_WBRroCl_ZiBHb5v6-MxytthrUmoPF7B-ffISZByBLAX8fznJUcUsuV6KVKc9zyglbYlX_Ws57NkdXRy7vg4euiIN6TsyENc8bJRhqs&amp;local=79&amp;pubid=4204776&amp;version=A&amp;psid=179352405193657452887456131&amp;entinfo=27800613387971_0&amp;apptype=0 " target="_blank" class="t" onclick="clickLog('from=fcpc_zflist_gzcount');">[单间]支持月付 文一路梧桐公寓 耀江文萃苑 中豪晴元</a>
    

    该 a 标签的 class 为 t ,用$('a.t')即可得到所有的 a 标签的对象,得到的是一个数组,遍历取出 href 属性即可。

    for(let i = 0; i < $('a.t').length; i++){
    	rentalObj.add($('a.t')[i].attribs.href)
    }
    

    得到了这些 URL ,接下来就可以用这些 URL 访问具体的租房信息了,每个 URL 对应一个租房页面。

    根据租房信息的 URL 访问相应页面,爬取数据

    还是先进入页面打开开发者模式。

    这次我们需要解析房屋所在地信息,用来可视化显示。

    img

    $('td.house-xqxq-content a.ablue')
    

    加上父标签可以过滤出更有针对性的 dom ,此时过滤出的是小区名称、本月均价、所在商圈等信息的 dom ,我们现在只需要第一个 dom 里面的数据,所以访问数组的[0]即可。

    除此之外为还需要页面里面的一张展示房屋信息的一张图片,找到对应 dom 可以发现 id 为 smainPic 。

    $('#smainPic')['0'].attribs.src
    

    这样访问即可得到图片的 URL 。

    其他我们还可以用同样的方法获取很多相关数据,比如$('.house-price').text()得到价格数据,$('span.tel-num.tel-font').text()可以得到房东的联系方式。

    通过百度地图进行可视化展示

    这里使用百度地图 api http://lbsyun.baidu.com/index.php?title=jspopular

    var map = new BMap.Map("container");          // 创建地图实例  
    map.centerAndZoom("杭州", 12);
    var localSearch = new BMap.LocalSearch(map);
    localSearch.setSearchCompleteCallback(function(searchResult){
    	var poi = searchResult.getPoi(0);/*地理位置信息*/
    })
    ocalSearch.search(params[url].location);
    

    获取经纬度以后再掉用相应的 api 在地图上显示即可,显示后再做什么效果,可自行发挥想象了。

    关于反爬虫

    在爬取过程中发现 58 同城的反爬虫策略,快速访问会让你输入验证码来验证是人在操作而不是代码访问。只要是人可以正常访问并不影响用户正常体验的网站都有办法绕过反爬虫策略。

    先采用较慢的方式发送 http 请求访问,此外每隔一段时间最好停一下,然后再继续访问。除此之外用 User-Agent 字段伪装成浏览器。最保险的方法就是购买代理,让代理用不同的 ip 地址去访问网站,即可绕过反爬虫机制。

    具体做法可以参照相关反爬虫策略的文章。

    8 条回复    2017-04-30 13:56:32 +08:00
    awolfly9
        1
    awolfly9  
       2017-04-03 09:48:58 +08:00   ❤️ 2
    分享一个我写的免费代理工具,目前来说有用不完的代理
    https://github.com/awolfly9/IPProxyTool
    answershuto
        2
    answershuto  
    OP
       2017-04-03 10:47:05 +08:00
    @awolfly9 挺不错的,我下次用用~
    yuedingwangji
        3
    yuedingwangji  
       2017-04-03 11:23:15 +08:00
    LZ 早发几天我就拿去广州找房了,可惜已经找到了..
    saxon
        4
    saxon  
       2017-04-05 08:49:57 +08:00
    有同类型 Python 版本么 2333
    answershuto
        5
    answershuto  
    OP
       2017-04-05 09:28:32 +08:00
    @yuedingwangji 哈哈,其实 url 修改一下就完全可以变成广州租房了。
    answershuto
        6
    answershuto  
    OP
       2017-04-05 09:28:56 +08:00
    @saxon 木有 python 版本,原理都一样的,可以尝试做一个呀。。
    yuedingwangji
        7
    yuedingwangji  
       2017-04-07 01:06:31 +08:00
    @answershuto 我的意思是你发表的时候我已经找好房子了
    guchengyehai1
        8
    guchengyehai1  
       2017-04-30 13:56:32 +08:00 via Android
    我用 python 写了一个同样的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2799 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 15:31 · PVG 23:31 · LAX 07:31 · JFK 10:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.