使用node.js通过request+cheerio模块来实现一个网络爬虫

一、网络爬虫的一般原理

  • 1、使用网络库或函数获取某个或某些网页的内容(如curl函数)

  • 2、对抓取的内容根据DOM结构获取需要的数据(如正则表达式)

  • 3、将分析后的数据进行存储(数据库或文件)

二、node.js实现网络爬虫的工具

  • 1、request:发起网络请求的模块

  • 2、cheerio:一个兼容jquery选择器用法的DOM解析工具

  • 3、fs模块:用于文件读写

三、实现过程

实例:我们以抓取京东商城的商品列表信息为做一个实验(以电脑这个分类为例)

1、过程
  • (1)、通过request模块抓取列表页第一页的内容,并获取它的分页数

  • (2)、通过cheerio解析抓取的内容,获取详情页的链接地址和分页数,将该分类下面的详情链接存储到一个文件中

  • (3)、通过详情页的链接地址,抓取详情页的内容(这一部先不做)

2、实现
  • (1)先安装request、cheerio模块
  1. npm install request --save
  2. npm install cheerio --save

(2)编辑app.js文件:

  1. var request = require('request'); //加载request模块(相当于一个HTTP请求模拟器,类curl)
  2. var parser = require('cheerio'); //加载cheerio模块(相当于一个html的DOM解析器)
  3. var fs = require('fs');
  4. //第一页的地址
  5. var listUrl = 'http://search.jd.com/Search?keyword=%E7%94%B5%E8%84%91&enc=utf-8&wq=%E7%94%B5%E8%84%91&pvid=7qrk3vni.f7898u#keyword=%E7%94%B5%E8%84%91&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&offset=5&page=1&s=1&click=0';
  6. //每一页的地址(其中{{page}}为页码)
  7. var pageUrl = 'http://search.jd.com/Search?keyword=%E7%94%B5%E8%84%91&enc=utf-8&wq=%E7%94%B5%E8%84%91&pvid=7qrk3vni.f7898u#keyword=%E7%94%B5%E8%84%91&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&offset=5&page={{page}}&s=1&click=0';
  8. var urlArr = [];
  9. /**
  10. * 获取列表信息的函数
  11. * @param string url 请求url
  12. * @param function cb 回调函数
  13. */
  14. function getListPage(url, cb)
  15. {
  16. request({
  17. url: url,
  18. headers: {
  19. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36'
  20. }
  21. }, function(err, res, body){
  22. if (err) {
  23. console.log('request error:'+err);
  24. return cb(err, null);
  25. }
  26. var $ = parser.load(body);
  27. var data = {};
  28. var obj = [];
  29. pageCount = $('#J_topPage span i').text();
  30. var urls = '';
  31. $('#J_goodsList ul li').each(function(i, ele){
  32. var tmp = {};
  33. tmp.id = $(this).attr('data-sku');
  34. tmp.url = $(this).find('.p-img a').attr('href');
  35. if (tmp.url) {
  36. urls += tmp.url+'
  37. ';
  38. obj.push(tmp);
  39. }
  40. });
  41. data.pageCount = pageCount;
  42. data.data = obj;
  43. //将url地址保存到文件中,如果要抓取详情页内容,可以通过读取这个地址来操作
  44. fs.appendFile('./data.txt', urls);
  45. cb(null, data);
  46. })
  47. }
  48. getListPage(listUrl, function(err, data){
  49. if (err) {
  50. console.log(err);
  51. return;
  52. }
  53. for (var p = 2; p<=data.pageCount ; p++) {
  54. var url = pageUrl.replace('{{page}}', p);
  55. getListPage(url, function(err, res){
  56. if (err) {
  57. console.log(err);
  58. return;
  59. }
  60. //其他操作,比如抓取详情页的内容等
  61. });
  62. }
  63. });

注:要抓取更细致的信息,需要对DOM结构非常熟悉