登录 注册

【设计】拉勾职位地图分布工具

基于拉勾职位的职位分布工具的设计思路和相关内容
时间:2016-04-02 23:49:14 作者:Mr.d

前好一段时间了,某一天在拉勾上看职位,想找一个钱多、离家近、工作轻松的工作,结果发现,这些职位只能找到钱多的,离家近的就优点困难了,而且具体的公司在哪里都得点进去看职位的详细信息里的工作地点,好吧....我突发奇想,能不能,我吧这个职位的信息抓下来,然后根据之歌工作地点将这些职位在地图上进行标记呢?好吧,搞一搞吧.....



功能介绍


1、职位分布

通过将拉勾上的职位数据抓取下来,根据每个职位中的工作地点(Address),再通过百度地图API获取地址对应的坐标(Position),最后将职位从百度地图上标记出来,进行显示。

单个坐标点点击都可以显示相应的职位,薪资,公司,工作地点等信息。

左侧单个职位名称,公司都是可以点击进入的,进入拉勾相应的介绍页面,在列表的右侧小地图点击,可以将地图的缩放到该职位的工作地点附近,并在地图上显示工作地点。



2、范围搜索

范围搜索首先需要从地图上标记出一个点,通过选取搜索的范围根据已有的职位坐标进行计算,选取离坐标点最近的100条数据进行保存,并以列表的形式进行显示,搜索坐标,搜索结果,进行存储,搜索结果保留2个小时



相关设计思路


职位数据抓取:

1、职位数据:

用chrome的开发者工具发现,在拉勾的职位中每次翻页都是以异步的请求来进行的,返回的json数据就是翻页后的相关内容,通过httpclient模拟请求,即可获得每页的职位信息,每页数量为15条,这个请求中有两个关键的参数 pn:页码  kd:关键字(例如:java)

    public String getJSONString(int pn,String key){
		String url = "http://www.lagou.com/jobs/positionAjax.json?city=%E5%8C%97%E4%BA%AC";
		Map params = new HashMap();
		params.put("first", "false");
		params.put("pn", pn+"");
		params.put("kd", key);
		String json = HttpClientUtils.getJsonByPost(url, params);
		return json;
	}

2、工作地址

工作地点在请求职位列表中是没有的,于是我从每个职位的详细信息中去抓取页面显示的数据,通过jsoup,发起请求,并获取其中的dom元素进行抓取

String url = "http://www.lagou.com/jobs/"+职位id+".html";


3、坐标

我用百度地图的api工具搜索了一下从页面上抓取过来的工作地点发现,其实拉勾职位信息页面上地图中的坐标点,其实就是百度地图API请求后,返回结果中的第一条...相关如何使用,请参考百度地图API


这里我使用了一种简单的生产者—消费者模式,因为一次抓取的职位数量是15条,而抓取工作地址、坐标的话,只能逐条的去请求,这样的话如果顺序完成一条数据的整个职位、地址、坐标请求,是很慢的,并且这样的方式一直属于“供大于求”的,所以我建立了两个数据队列,并且以异步多线程的方式去获取地址、坐标


1、单线程将获取到的职位信息存入数据库中,以获取的顺序存储,保证页面显示的时候顺序与拉勾页面的一直,并且将获得的数据存储后放进“地址队列”

2、两个线程循环poll“地址队列”,如果获取到职位信息,则根据职位信息进行地址信息的抓取,抓取结束后将地址update到数据库中相应的职位信息后,将该职位放入到“坐标队列”

3、两个线程循环pool“坐标队列”,果果获取到职位信息,根据地址信息去请求百度API,获取相应的坐标


我的阿里云服务器是单核1G的配置,而且跑了不少东西,所以为了减轻服务器的压力,每个任务只开启了两个线程执行。


4、范围搜索:已有的职位信息已经通过百度地图的API获取到坐标了,那么根据从地图上标记的点位坐标和每个职位相应的职位坐标进行距离的计算,则可以得到点位和职位的距离,再根据选择的范围进行匹配,则可以确定该职位是否在选定的范围内。

 1)、拉勾的Java职位大概有5000条左右,我用了定时线程去抓取,在进行搜索计算时,第一次搜索会从数据库直接读取全部的数据进行计算(尝试使用多线程去并发获取5000条数据,结果发现跟单线程获取,区别不是很大,所以就用了单线程的获取方式),将获取到的数据进行简单处理后,将简化过的数据放入到Memcached缓存中,后续的操作和计算都不用再次去读取数据库,直接缓存操作即可。

 2)、拉勾职位信息是2小时获取一次,那么在2小时抓取数据前,会先将缓存数据进行清空,并且暂停搜索功能,保证搜索信息的准确性和正确性,并且也会存在一个线程去专门监控存储的搜索结果数据,在2个小时后进行一次清空,保证点击历史搜索记录时,都是最新的数据

 3)、搜索结束后,再内存中根据计算出的距离信息进行排序,Collection.sort ....  不多说了,并且截取最近的100条进行存储....


那么问题来了,这么好用的工具哪里能用的到呐~~~

点击这里


好吧,这个工具我用着还是可以的,但是,悲催的是,可能前两天出了个错误一直循环去请求拉勾的某个数据,结果...貌似...IP地址被封了,请求不到了...好吧,本来还是有个链接的,结果木有了,不过,我有两台服务器, 换个服务器部署一下,重新开始吧


写个文章,纪念一下我简单的小设计吧....



注:该工具为个人使用,有想了解相关代码和具体实现的,可以联系我 qq:2410508062 请说明来意







评论


暂无评论