【nodejs爬虫】使用async控制并发写一个小说爬虫
最近在做一个书城项目,数据用爬虫爬取,百度了一下找到这个网站,以择天记这本小说为例。
爬虫用到了几个模块,cheerio,superagent,async。
superagent是一个http请求模块,详情可参考链接。
cheerio是一个有着jQuery类似语法的文档解析模块,你可以简单理解为nodejs中的jQuery。
async是一个异步流程控制模块,在这里我们主要用到async的mapLimit(coll, limit, iteratee, callback)
async.mapLimit(urls, 10, function (url, callback) {fetchUrl(url, callback, id)}, function (err, results) {//TODO})
第一个参数coll是一个数组,保存了小说的章节url,第二个参数limit是控制并发数,第三个参数iteratee接受一个回调函数,该回调函数的第一个参数就是单独某一章的url,第二个参数也是一个回调函数,这个回调函数执行后会把结果(在这里就是每一章的内容)保存到第四个参数callback的results中,results是一个数组,保存了所有章节的内容。
我们在fetchUrl获取章节数据。
首先我们要根据小说的主页url获取所有章节的url保存到数组urls中:
superagent.get(url).charset('gbk') //该网站编码为gbk,用到了superagent-charset.end(function (err, res) {var $ = cheerio.load(res.text); //res.text为获取的网页内容,通过cheerio的load方法处理后,之后就是jQuery的语法了let urls = []total = $('#list dd').lengthconsole.log(`共${$('#list dd').length}章`)$('#list dd').each(function (i, v) {if (i < chapters) {urls.push('http://www.zwdu.com' + $(v).find('a').attr('href'))}})
fetchUrl函数
function fetchUrl(url, callback, id) {superagent.get(url).charset('gbk').end(function (err, res) {let $ = cheerio.load(res.text)//obj为构建的包含章节信息的对象callback(null, obj) //将obj传递给第四个参数中的results }) }
完整代码:
/*** Created by tgxh on 2017/7/4.*/ const cheerio = require('cheerio') const express = require('express') const app = express() const superagent = require('superagent') require('superagent-charset')(superagent) const async = require('async');let total = 0 //总章节数 let id = 0 //计数器 const chapters = 10 //爬取多少章 const url = 'http://www.zwdu.com/book/8634/'//去除前后空格和 转义字符 function trim(str) {return str.replace(/(^\s*)|(\s*$)/g, '').replace(/ /g, '') }//将Unicode转汉字 function reconvert(str) {str = str.replace(/(&#x)(\w{1,4});/gi, function ($0) {return String.fromCharCode(parseInt(escape($0).replace(/(%26%23x)(\w{1,4})(%3B)/g, "$2"), 16));});return str }function fetchUrl(url, callback, id) {superagent.get(url).charset('gbk').end(function (err, res) {let $ = cheerio.load(res.text)const arr = []const content = reconvert($("#content").html())//分析结构后分割htmlconst contentArr = content.split('<br><br>')contentArr.forEach(elem => {const data = trim(elem.toString())arr.push(data)})const obj = {id: id,err: 0,bookName: $('.footer_cont a').text(),title: $('.bookname h1').text(),content: arr.join('-') //由于需要保存至mysql中,不支持直接保存数组,所以将数组拼接成字符串,取出时再分割字符串即可}callback(null, obj) }) }app.get('/', function (req, response, next) {superagent.get(url).charset('gbk').end(function (err, res) {var $ = cheerio.load(res.text);let urls = []total = $('#list dd').lengthconsole.log(`共${$('#list dd').length}章`)$('#list dd').each(function (i, v) {if (i < chapters) {urls.push('http://www.zwdu.com' + $(v).find('a').attr('href'))}})async.mapLimit(urls, 10, function (url, callback) {id++fetchUrl(url, callback, id) //需要对章节编号,所以通过变量id来计数}, function (err, results) {response.send(results)})}) })app.listen(3378, function () {console.log('server listening on 3378') })
结果如下:
转载于:https://www.cnblogs.com/tgxh/p/7124202.html
【nodejs爬虫】使用async控制并发写一个小说爬虫相关推荐
- 用python写一个简单的爬虫_用Python从零开始写一个简单爬虫
import requests from bs4 import BeautifulSoup url = "https://tieba.baidu.com/f?kw=王者荣耀&fr=h ...
- Node爬虫之使用 async 控制并发
上文 <Node爬虫之使用 eventproxy 控制并发>我们说到用 node 爬了csdn首页数据,但是这些请求完全是并发的,如果某些网站有 "反爬" 机制,就很有 ...
- 从0开始写一个多线程爬虫(2)
上一篇文章: 从0开始写一个多线程爬虫(1) 我们用继承Thread类的方式来改造多线程爬虫,其实主要就是把上一篇文章的代码写到线程类的run方法中,代码如下: import re import re ...
- python爬虫都能干什么用_5 行代码就能写一个 Python 爬虫
欢迎关注我的公众号:第2大脑,或者博客:高级农民工,阅读体验更好. 摘要:5 行代码就能写一个 Python 爬虫. 如果你是比较早关注我的话,会发现我此前的大部分文章都是在写 Python 爬虫,前 ...
- 用c语言写一个网络爬虫
(同步个人博客 http://sxysxy.org/blogs/28 到csdn 写一个网络爬虫 写一个网络爬虫,来获取一个网站上感兴趣的信息. 最基本的模型 就是图.每个页面看作一个节点,若页面A有 ...
- 用爬虫写一个,小说下载程序
用爬虫写一个,小说下载程序 环境:python 3.7.3 没啥难度和技术含量,随便写写.本来程序有部分可用format进行优化,但又想了想小说名可能还会 有一些奇奇怪怪的符号,就没弄了. impor ...
- 【直播】手把手带你 5 分钟写一个小爬虫,从入门到超神!
在程序员界流传着这么一个顺口溜:爬虫玩得好,监狱进得早.数据玩得溜,牢饭吃个够--时不时还有 "XX 公司做违法爬虫,程序员坐牢" 的新闻爆出. 在看热闹的同时,很多人都会提出疑问 ...
- 用Python写一个网络爬虫爬取网页中的图片
写一个爬虫爬取百度贴吧中一个帖子图片 网址:壁纸 用谷歌浏览器的开发工具检查网页,可以发现其每一张图片都有如下格式 <img class="BDE_Image" src=&q ...
- 五分钟写一个小爬虫,爬取小说并写入txt文件
先上代码: #-*- coding:UTF-8 -*- import requests from lxml import html url='http://www.shuge.net/html/111 ...
最新文章
- python代码通过日期获得星期信息(根据日期获取星期day of the week)
- linux查找日期目录,详解Linux查找目录下的按时间过滤的文件
- 快速创建包快捷键大全_99个CAD插件大全,各种工具箱和超实用辅助插件,绘图从此不卡顿...
- 无法嵌入互操作类型 请改用适用的接口_机器视觉可用的不同电缆和连接器类型以及相关利弊分析...
- 利用计算机程序解决问题的基本过程,第四章第一节编制计算机程序解决问题
- esper_Twitter4j和Esper:在Twitter上跟踪用户情绪
- 网管交换机怎么设置?网管交换机设置方法
- python3所支持的整数进制_Python3快速入门(三)——Python3标准数据类型
- 秒懂文件路径 / 和 ./ 和 ../ 和 ../../
- 操作系统重装或还原后Domino 8 无法启动解决方法
- 如何修改bt tracker服务器,bt tracker服务器
- P1589 - 【NOI2009】植物大战僵尸
- css模拟title和alt的提示效果[转]
- Echart地图的省级,以及所有地市级下载与使用
- MySQL数据分析-(12)表操作补充:字段属性
- [已解决]Notepad++ 无法安装HexEditor
- JdbcTemplate数据库连接耗尽问题排查
- [UVa 1646] Edge Case
- 关于背单词的一点个人体会 (好文章)
- python生成随机的测验试卷_python生成随机的测验试卷文件