链家小区数据爬取

这次爬取链家数据时爬取的链家北京区域的所有小区数据。
区域比较少,手动去把每个区的列表页面罗列了出来(所有分区全家起来288个)
没有去处理当前总共多少页,之类的数据,而是把这个数据导入到一张表里,表字段设计了页数和当前爬取的页码,这样方便重试,也不做无用功跑已经跑过的数据。
由于一开始只需要小区的名称,地址,当前均价等,这些信息都有了,所以也没有去爬详情。
列表页面的URL格式为:https://bj.lianjia.com/xiaoqu/guangqumen/
默认为第一页,首页之后的格式均为在当前URL后面添加 pg+pageNo+/ 。
String realUrl = baseUrl + “pg” + pageNo + “/”;
通过写好的可以使用代理的HttpClient发起请求,列表页还是很容易请求成功的。
然后使用Jsoup解析请求到的网页字符串(据大神说,用XPath更高端更牛皮,不过我用着Jsoup还很顺手,就暂时不换了 – 主要以前用jquery习惯,所以找起来也方便)
import org.jsoup.Jsoup;
Document doc = Jsoup.parse(html);
打开网页调试工具,找到翻页位置的元素,发现:翻页的所有链接都在li[class=house-lst-page-box]元素内的超链接标签<a>上,并且最后一个超链接标签就是最大页码的标签,标签上的属性 data-page 就是页码,也就是最大页数,正好提取出来
代码:
Elements pageList = doc.select(“li[class=house-lst-page-box]”).select(“a”);
Element a = Safes.first(Lists.reverse(pageList));
Integer pageCount = Integer.valueOf(a.attr(“data-page”));
至此最大页数和当前页都已经拿到了。接着是收集小区信息。
小区列表中每个小区的信息就在一堆class=xiaoquListItem的li元素里,包含了列表里需要的所有小区的信息,先把每个小区的块都拿到。(当时爬的时候,下面填充用的标签还用的是a标签,写文章时候已经改成div和a标签交叉的了,感觉链家也不是没有做反爬虫,只是做的比较简单,下面呈上原来的老代码)
ElementsxiaoquList=doc.select(“li[class=xiaoquListItem]”).select(“a”).select(“a[class=PageLink]”)
接下来看源码就比较清楚了,里面分了三大块,左侧是图片,中间是小区名称、最近的成交信息、地址信息、代理人信息和标签信息,放在class=info的div里,每一块信息是一个div,右侧是价格、在售信息等内容,放在class=xiaoquListItemRight的div里。
从里面分别取出来这些信息,并放到对应对象里
List<LianJiaXiaoquEntity> entityList = Lists.newArrayList();
Safes.of(xiaoquList).forEach(xiaoqu -> {
    LianJiaXiaoquEntity entity = new LianJiaXiaoquEntity();
    Element title = Safes.first(xiaoqu.select(“div[class=title]”)).selectFirst(“a”);
    entity.setName(title.text());
    entity.setUrl(title.attr(“href”));
    Optional.ofNullable(Safes.first(xiaoqu.select(“div[positionInfo]”))).ifPresent(positionInfo -> {
        positionInfo.text();// \r\n&nbsp;\r\n&nbsp;/板楼/塔板结合/r/n&nbsp;2002年建成
        entity.setNameDetail(StringUtils.join(positionInfo.select(“a”).stream().map(Element::text).collect(Collectors.toList()), “-“) + entity.getName());
    });
    Optional.ofNullable(Safes.first(xiaoqu.select(“div[class=xiaoquListItemRight]”))).ifPresent(price -> {
        entity.setAveaPrice(Safes.first(price.select(“span”)).text());
        entity.setPriceTime(Safes.first(price.select(“div[class=priceDesc]”)).text());
    });
    entityList.add(entity);
这样,就把列表里一些小区的基本信息保存下来了。
但是我需要的不只是这些,主要还需要小区的坐标,这个在列表里没有。找小区坐标的过程也是一波三折,接下来说。

爬取大众点评商家信息

老板安排了新的任务,需要爬取一些数据,然后进行机器学习,来给决策提供依据或者建议。

当前这一步,爬取相关的大众点评商家信息,并建立关系。

当前已有:选址名称,腹地名称,选址经纬度,腹地经纬度。

思路1:筛选点评上符合要求的商铺,然后全部爬下来,再与当前已有的数据建立联系(通过经纬度,地址等方式,需要商铺的经纬度、地址等信息)

思路2:根据当前已有信息,如地址,经纬度,去点评上搜索附近的商铺,然后爬下来,这要求知道点评根据经纬度筛选商铺的接口,经过观察发现点评的APP上有这个功能,但是抓包失败。

思路3:从点评的m站上搜索,关键词为地址,然后过滤美食。结果并不好用,经常查询的是具体地址,而非商铺。

思路4:直接从爬虫群里购买数据和代码,但是可能不靠谱。

思路5:从网上搜索爬取商铺的代码,改改自己用。这种方式多数都是从web版的网页上进行爬取的,自己执行爬取的时候,得注意使用代理切换ip,不然的话,可能数据会有问题。

尝试了一番之后,大概只有第五种方法比较可行。

从百度直接搜索点评爬虫,和在gitee上搜索点评的爬虫,发现绝大多数都是爬取的都是去爬的商铺的评论,但是这顺便会爬商铺。

从中甄别一下看是不是有坐标经纬度,如果有的话最好,可以通过经纬度的计算来筛选某些点附近的商铺,然后计算。

总结下来基本还是思路1的路子。OK,开始执行。

关于寻找目标市场的思考

最初是什么想法呢。。。。。。。。

多级市场划分。

划分的维度是多方面的,比如城市等级,大小,经济,人口等。任何一项事务,扩散总是有一个过程的。多数情况下,都是由大城市发起或者由国外流入国内一线大城市,然后逐渐再扩散到二线三线直至到四五线城市。

由于身处大城市,虽然不是说随时随地都是在关注最前沿的流行的东西,但是毕竟耳濡目染,身边环境所致,还是能够意识到一些东西。尤其是逢年过节什么的,从一线城市回到家里的时候,你会觉得家里的这份“土”,其实就是潮流扩展的过程所体现出来的现象之一。

所以节假日什么的,也是二三四线城市与大城市交流沟通和打通的手段了。通过这时候从大城市到小城市的人员流动,从而促进了二三四线城市的潮流推进。

反过来说,经常在一二线城市与三四五线城市之间走动,也应该会更容易发现不同级别城市之间的差异,发现二三四五线城市的发展趋向,预见其发展潮流,从而发现其中的商机。

想要利用这个过程,就是主动去发现,然后主动去学习,效仿大城市的内容、潮流,然后带到二三线城市里去。从中应该能赚到一些潮流红利。

降维打击

对,这就是降维打击。用一种几乎已知未来的方式来操控更低维度城市的发展过程。就跟使用互联网打击传统行业一样。

三四五线城市居民的特点

根据一些已经在这个市场上火起来的应用来分析一下吧。目前已经火到大城市也能看到、知道的产品和市场,有这么几个:

  • 抖音,快手
  • 拼多多
  • 趣头条
  • 今日头条

这几个是已经十分火爆的,并且在一线城市都已经有了相当知名度的产品。他们瞄准的基本都是二三四五线的用户。甚至比较火的一些小程序,公众号等,做的也是这方面的内容,但是因为整体平台并不是这个定位,所以先不放这部分。对于今日头条是否列入这里也稍微存在争议,不过因为头条使用的推荐算法,是你越看什么,就越给你推荐什么的。所以针对二三四线城市,就会针对他们推荐他们这个市场自己关注的内容,也算是一种吧。

其他几款就不一样了,基本就是专门针对这个市场做的。

大致总结一下面对人群的特点:

  • 空闲时间多
  • 看中小利益,容易被低额小利吸引
  • 传播成本低,喜欢噱头
  • 乐于扩散

目前还有哪些东西可以在这样的市场上搬运和投放呢?思考一下,回头写。