用nodejs抓取并存储网页内容

原文:

前端乱炖 http://www.html-js.com/article/2558

说明:
原文中的API可能比较旧,最新版的superagent会有执行错误,在原文基础上代码修改了一些

目标

  1. 获取http://segmentfault.com/blogs/recommend?page=3页面的文章列表postList

  2. 根据postList,逐个获取具体的文章页面

  3. 用文章标题作为文件名,如:{{ title }}.txt;将文章内容储存在txt文件

工具或库的选择

  1. superagent可以便捷的发送网络请求,并得到其响应的结果

  2. cheerio让我们可以用熟悉的jQuery风格处理html字符串

  3. observe.js可以侦听对象的属性,被侦听的属性的值发生改变时,会自动调用指定回调函数,方便运用观察者模式

准备工作

  1. 分别加载需要的模块:

npm install superagent
npm install cheerio
npm install observe.js

  1. 新建文件app.js,引入模块:
    var superagent = require('superagent')
    var observe = require('observe.js')
    var cheerio = require('cheerio')
    var path = require('path')
    var url = require('url')
    var fs = require('fs')
     

具体实现

  1. 创建文件夹postList,用来储存txt文件
    //以同步的方式:判断是否存在这个文件夹,不存在才创建
    if (!fs.existsSync('postList')) {
        fs.mkdirSync('postList')
    }
    //获取当前路径,方便读写目录跟文件
    var cwd = process.cwd()
     
  1. 创建单例
    //reptile 的意思是爬行动物、卑鄙的人。
    //爬别人的内容,有点卑鄙的意味
    var reptile = observe({})
     
  1. 侦听属性
    //observe过的对象,有on off once hold collect tie等方法
    //这里只用了on,根据属性名添加侦听函数
    //用法跟jQuery.on类似,可以是对象批量侦听,可以逐个侦听reptile.on('url', callback)
    reptile.on({
        //根据 url ,获取 text
        url: function(url) {
            var that = this
            //get方法发出请求,query方法为url添加query字段(url问号背后的)
            //end方法接受回调参数,html一般在res.text中
            superagent
                .get(url)
                .query(this.query)
                .end(function(err, res) {
                    if (err || !res.ok){
    					console.log('ERROR!!!!')
    				}
    				else{
    					//赋值给reptile.text,就会触发回调
    					that.text = res.text
    				}
                })
        },
        //触发的回调函数在这里
        text: function(text) {
            var that = this
            //cheerio 的 load 方法返回的对象,拥有与jQuery相似的API
            var $ = cheerio.load(text)
            var postList = []
            //根据html结构,筛选所需部分
            //这个页面我们只要标题跟对应的url。这里Blog_table1和Blog_td1是class属性名,a指的是a标签
            $(".Blog_table1").find('.Blog_td1 a').each(function(i, e) {
                    postList.push({
                        title: $(this).text(),
                        url: path.join(url.parse(that.url).hostname, $(this).attr('href'))
                    })
                })
            //赋值就触发回调
            this.postList = postList
            this.postItem = postList.shift()
        },
        //在这个回调里发出每一篇文章的请求
        postItem: function(postItem) {
            console.log(postItem.url)
            var that = this
            superagent
                .get(postItem.url)
                .end(function(err, res) {
                    if (err || !res.ok) {
                       console.log(res)
                    } else {
    					 //我们在这里构造filename,指定了具体路径
                        that.content = {
                            filename: path.join(cwd, 'postList', postItem.title + '.txt'),
                            title: postItem.title,
                            text: res.text
                        }
                    }
                })
        },
        //在这里处理每篇文章的具体内容
        content: function(content) {
            var that = this
            var $ = cheerio.load(content.text)
            var data = ''
            //根据html结构选取正文,只要text部分,去掉html标签
            $('.article *').each(function() {
                    data += $(this).text() + '\n'
                })
            //前面已经构造好了文件路径,直接写入即可
            fs.writeFile(content.filename, data, function(err) {
                if (err) {
                    console.log(err)
                } else if (that.postList.length) {
                    //写入完毕后,检查postList还有没有剩余
                    //若有,取出来赋值给postItem,又goto到请求文章的步骤
                    that.postItem = that.postList.shift()
                }
            })
        }
    })
     
  1. 初始化爬虫单例
    reptile.url = 'http://segmentfault.com/blogs/recommend'
    reptile.query = 'page=3'
     

以上,全部逻辑都写完.

运行app.js

在当前目录打开命令行,window系统下快捷方式为:按住shift键,点击鼠标右键,菜单栏会多出在此处打开命令窗口

node app.js

等待结果,查看postList目录下有无新增txt文件

生成网站的 sitemap.xml 文件可以帮助搜索引擎更好地抓取和索引您的网站内容,从而提高您的 SEO 优化效果。下面是使用 Node.js 动态生成网站 sitemap.xml 的方法: 1. 安装依赖 首先,您需要安装 `xmlbuilder` 模块,它是一个轻量级的 XML 创建器,可以用于动态生成 XML 文件。 ``` npm install xmlbuilder --save ``` 2. 生成 sitemap.xml 文件 在您的 Node.js 项目中创建一个生成 sitemap.xml 文件的脚本文件,并编写以下代码: ```javascript const fs = require('fs'); const xmlbuilder = require('xmlbuilder'); const baseUrl = 'https://www.example.com'; // 网站页面的 URL 列表 const urls = [ '/', '/about', '/services', '/blog', '/contact' ]; // 创建 sitemap.xml 文件 const root = xmlbuilder.create('urlset', { version: '1.0', encoding: 'UTF-8' }); root.att('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9'); urls.forEach(url => { const loc = baseUrl + url; const urlNode = root.ele('url'); urlNode.ele('loc', {}, loc); }); const xml = root.end({ pretty: true }); fs.writeFileSync('sitemap.xml', xml, 'utf8'); console.log('Sitemap generated successfully!'); ``` 在上面的代码中,我们首先定义了一个 `baseUrl` 变量,用于存储网站的基础 URL,然后定义了一个 `urls` 数组,用于存储网站页面的 URL 列表。 接着,我们使用 `xmlbuilder` 模块创建了一个 XML 文件的根节点 `urlset`,并设置了其命名空间。然后,我们遍历 `urls` 数组,为每个页面创建一个 `url` 节点,并添加一个 `loc` 子节点,用于存储页面的 URL。 最后,我们使用 `fs` 模块将生成的 XML 内容写入到 `sitemap.xml` 文件中,并在控制台输出成功信息。 3. 集成到网站 生成 sitemap.xml 文件后,您需要将其添加到您的网站根目录下,并在网站的 robots.txt 文件中添加以下代码: ``` Sitemap: https://www.example.com/sitemap.xml ``` 这将告诉搜索引擎您网站的 sitemap.xml 文件的位置,以便更好地抓取和索引您的网站内容。 通过以上几步,您就可以使用 Node.js 动态生成网站 sitemap.xml 文件,并优化您的 SEO 效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值