nodejs抓取别人家的页面的始末
2015-09-24 02:30
591 查看
内容:分析并获取页面调取数据的API(接口),并跨域获取数据保存在文档中(nodejs做代理-CORS)
事由以及动机
2015年9月份全国研究生数学建模竞赛的F题,旅游线路规划问题。其中需要自己去查很多数据。例如所给201个5A级景区的位置,以及景区距离所在省会距离等等~开始队友小伙伴准备从百度手动去一个一个查询,但是效率极低,在这么短的时间内,需要收集这么多数据是多么的耗时,并且也不能把大把时间花费在查资料上,虽然说查资料是必须的,题目也鼓励我们从网上查询相关数据,因此在团队中的我就想到了让计算机帮我们去做这件事。
第一步,确定想要抓取的信息,获取数据服务api
以查询个两地的行车时间为例,我们以百度地图为例,见下图
事由以及动机
2015年9月份全国研究生数学建模竞赛的F题,旅游线路规划问题。其中需要自己去查很多数据。例如所给201个5A级景区的位置,以及景区距离所在省会距离等等~开始队友小伙伴准备从百度手动去一个一个查询,但是效率极低,在这么短的时间内,需要收集这么多数据是多么的耗时,并且也不能把大把时间花费在查资料上,虽然说查资料是必须的,题目也鼓励我们从网上查询相关数据,因此在团队中的我就想到了让计算机帮我们去做这件事。
第一步,确定想要抓取的信息,获取数据服务api
以查询个两地的行车时间为例,我们以百度地图为例,见下图
var http = require('http'); var request_ = require('request'); var urlencode2=require("urlencode2"); var url=require('url') http.createServer(function (request, response) { var arg1 = url.parse(request.url, true).query; var sn=arg1.sn; var en=arg1.en; var req_url="http://api.map.baidu.com/?qt=nav&c=131&sn=2%24%24%24%24%24%24%20"+ urlencode2(sn,'gbk')+"%24%240%24%24%24%24&en=2%24%24%24%24%24%24"+ urlencode2(en,'gbk')+"%24%240%24%24%24%24&sy=0&ie=utf-8&oue=1&fromproduct=jsapi&res=api&callback=BMap._rd._cbk54249"; request_.get({ url:req_url, json:true }, function(error, response_, body) { if (!error && response_.statusCode == 200) { var res=-1; if(body){ res=body.split(',"toll":')[0];//time s res=res.split('"time":')[2]; console.log(res) if(!res){ res=-1; } else{ res=res/60; } } response.writeHead(200, { "Content-Type": "text/html; charset=UTF-8", 'Access-Control-Allow-Origin':request.headers.origin }); response.end(res+'\n'); } else{ // console.log(error) } } ) }).listen(8888); // 终端打印如下信息 console.log('Server running at ' target='_blank'>http://127.0.0.1:8888/');[/code]
nodejs
其中,本文用到了request(用于发起http请求)模块和urlencode2(主要用于URLEncode)模块
request安装:
npm install request
详见:https://github.com/request/request
urlencode2安装:
详见:https://github.com/node-modules/urlencodevar http = require('http'); http.createServer(function (request, response) { //... response.end('welcome baby'); }).listen(8888);
这几句简单的代码就搭建了一个web服务,端口号是8888
$ node 文件名.js
在终端输入以上指令即可允许该服务。var arg1 = url.parse(request.url, true).query; var sn=arg1.sn; var en=arg1.en; var req_url="http://api.map.baidu.com/?qt=nav&c=131&sn=2%24%24%24%24%24%24%20"+ urlencode2(sn,'gbk')+"%24%240%24%24%24%24&en=2%24%24%24%24%24%24"+ urlencode2(en,'gbk')+"%24%240%24%24%24%24&sy=0&ie=utf-8&oue=1&fromproduct=jsapi&res=api&callback=BMap._rd._cbk54249";
以上是获取查询参数并拼接请求字符串
然后利用request向目标服务器发送请求,并解析出需要的信息
最重要的是以下代码:response.writeHead(200, { "Content-Type": "text/html; charset=UTF-8", 'Access-Control-Allow-Origin':request.headers.origin }); response.end(res+'\n');
允许所有用户跨域访问,因此我们就能访问自己搭建的web服务了。
我在前端页面只需,请求我们的地址http://localhost:8888
并且指定sn(start node)与 en(end node)一并发送到服务器即可。
相关代码:https://github.com/AlvinWei1024/blog-resources/tree/master/20150923
作者:AlvinWei 文章出处:韦躐晟的博客 http://www.cnblogs.com/alvinwei1024/p/4834045.html
本文版权归作者和博客园共有,欢迎转载
转载请说明原文章出处
总结:
本文所用实例的百度地图api无需这么费劲去解析,可以使用其公布的公共API接口,但是每天的访问次数有10w次的限制。
相关文章推荐
- Node-red catch节点
- nodejs、npm、grunt——名词解释
- node.js基础教程
- LeetCode(49) Populating Next Right Pointers in Each Node I II
- mac使用nvm安装node进行多版本管理
- LintCode Remove Node in Binary Search Tree
- Node.js Cluster多进程负载测试
- [LeetCode]#19 Remove Nth Node From the End of list
- Node.js知识点详解(一)基础部分
- node.js框架express入门模板
- [LeetCode]Delete Node in a Linked List
- Grunt学习笔记之开发环境的搭建与创建一个基本的项目
- nodejs+express 初级安装测试
- 快速搭建 Node.js 开发环境
- nodejs爬虫简易实现和jquery的each方法
- nodejs显现events.js:72抛出错误
- LeetCode(38) Delete Node in a Linked List
- 执行start-dfs.sh后,datenode没有启动
- Node.js中的DNS模块
- 从零开始nodejs系列文章