全局安装typescript:
npm install -g typescript
目前版本2.0.3,这个版本不再需要使用typings命令了。但是vscode捆绑的版本是1.8的,需要一些配置工作,看本文的处理办法。
 
测试tsc命令:
tsc
创建要写的程序项目文件夹:
mkdir test-typescript-spider
进入该文件夹:
cd test-typescript-spider
初始化项目:
npm init
安装superagent和cheerio模块:
npm i --save superagent cheerio
安装对应的类型声明模块:
npm i -s @types/superagent --save
npm i -s @types/cheerio --save
安装项目内的typescript(必须走这一步):
npm i --save typescript
用vscode打开项目文件夹。在该文件夹下创建tsconfig.json文件,并复制以下配置代码进去:
{
    "compilerOptions": {
        "target": "ES6",
        "module": "commonjs",
        "noEmitOnError": true,
        "noImplicitAny": true,
        "experimentalDecorators": true,
        "sourceMap": false,
     // "sourceRoot": "./",
        "outDir": "./out"
    },
    "exclude": [
        "node_modules"
    ]
}
在vscode打开“文件”-“首选项”-“工作区设置”
在settings.json中加入(如果不做这个配置,vscode会在打开项目的时候提示选择哪个版本的typescript):
{
"typescript.tsdk": "node_modules/typescript/lib"
}
 
创建api.ts文件,复制以下代码进去:
import superagent = require('superagent');
import cheerio = require('cheerio');

export const remote_get = function(url: string) {

const promise = new Promise<superagent.Response>(function (resolve, reject) {
        superagent.get(url)
            .end(function (err, res) {
                if (!err) {
                    resolve(res);
                } else {
                    console.log(err)
                    reject(err);
                }
            });
    });
    return promise;
}

创建app.ts文件,书写测试代码:
import api = require('./api');
const go = async () => {
    let res = await api.remote_get('http://www.baidu.com/');
    console.log(res.text);
}
go();
执行命令:
tsc
然后:
node out/app
观察输出是否正确。
 
现在尝试抓取http://cnodejs.org/的第一页文章链接。
修改app.ts文件,代码如下:
import api = require('./api');
import cheerio = require('cheerio');

const go = async () => {
    const res = await api.remote_get('http://cnodejs.org/');
    const $ = cheerio.load(res.text);
    let urls: string[] = [];
    let titles: string[] = [];
    $('.topic_title_wrapper').each((index, element) => {
        titles.push($(element).find('.topic_title').first().text().trim());
        urls.push('http://cnodejs.org/' + $(element).find('.topic_title').first().attr('href'));
    })
    console.log(titles, urls);
}
go();

观察输出,文章的标题和链接都已获取到了。
 
现在尝试深入抓取文章内容
import api = require('./api');
import cheerio = require('cheerio');

const go = async () => {
    const res = await api.remote_get('http://cnodejs.org/');
    const $ = cheerio.load(res.text);
    $('.topic_title_wrapper').each(async (index, element) => {
        let url = ('http://cnodejs.org' + $(element).find('.topic_title').first().attr('href'));
        const res_content = await api.remote_get(url);
        const $_content = cheerio.load(res_content.text);
        console.log($_content('.topic_content').first().text());
    })

}
go();

可以发现因为访问服务器太迅猛,导致出现很多次503错误。
解决:
添加helper.ts文件:
export const wait_seconds = function (senconds: number) {
    return new Promise(resolve => setTimeout(resolve, senconds * 1000));
}
修改api.ts文件为:
import superagent = require('superagent');
import cheerio = require('cheerio');

export const get_index_urls = function () {
    const res = await remote_get('http://cnodejs.org/');
    const $ = cheerio.load(res.text);
    let urls: string[] = [];
    $('.topic_title_wrapper').each(async (index, element) => {
        urls.push('http://cnodejs.org' + $(element).find('.topic_title').first().attr('href'));
    });
    return urls;
}
export const get_content = async function (url: string) {
    const res = await remote_get(url);
    const $ = cheerio.load(res.text);
    return $('.topic_content').first().text();
}

export const remote_get = function (url: string) {

const promise = new Promise<superagent.Response>(function (resolve, reject) {

superagent.get(url)
            .end(function (err, res) {
                if (!err) {
                    resolve(res);
                } else {
                    console.log(err)
                    reject(err);
                }
            });
    });
    return promise;
}

修改app.ts文件为:
import api = require('./api');
import helper = require('./helper');
import cheerio = require('cheerio');

const go = async () => {
    const res = await api.remote_get('http://cnodejs.org/');
    const $ = cheerio.load(res.text);
    let urls = await api.get_index_urls();
    for (let i = 0; i < urls.length; i++) {
        await helper.wait_seconds(1);
        let text = await api.get_content(urls[i]);
        console.log(text);
    }
}
go();

观察输出可以看到,程序实现了隔一秒再请求下一个内容页。
 
现在尝试把抓取到的东西存到数据库中。
安装mongoose模块:
npm i mongoose --save
npm i -s @types/mongoose --save
然后建立Scheme。先创建models文件夹:
mkdir models
在models文件夹下创建index.ts:
import * as mongoose from 'mongoose';

mongoose.connect('mongodb://127.0.0.1/cnodejs_data', {
    server: { poolSize: 20 }
}, function (err) {
    if (err) {
        process.exit(1);
    }
});

// models
export const Article = require('./article');

在models文件夹下创建IArticle.ts:
interface IArticle {
    title: String;
    url: String;
    text: String;
}
export = IArticle;
在models文件夹下创建Article.ts:
import mongoose = require('mongoose');
import IArticle = require('./IArticle');
interface IArticleModel extends IArticle, mongoose.Document { }

const ArticleSchema = new mongoose.Schema({
    title: { type: String },
    url: { type: String },
    text: { type: String },
});

const Article = mongoose.model<IArticleModel>("Article", ArticleSchema);
export = Article;

修改api.ts为:
import superagent = require('superagent');
import cheerio = require('cheerio');
import models = require('./models');
const Article = models.Article;

export const get_index_urls = async function () {
    const res = await remote_get('http://cnodejs.org/');

const $ = cheerio.load(res.text);
    let urls: string[] = [];
    $('.topic_title_wrapper').each((index, element) => {
        urls.push('http://cnodejs.org' + $(element).find('.topic_title').first().attr('href'));
    });
    return urls;

}
export const fetch_content = async function (url: string) {
    const res = await remote_get(url);

const $ = cheerio.load(res.text);
    let article = new Article();
    article.text = $('.topic_content').first().text();
    article.title = $('.topic_full_title').first().text().replace('置顶', '').replace('精华', '').trim();
    article.url = url;
    console.log('获取成功:' + article.title);
    article.save();

}
export const remote_get = function (url: string) {

return new Promise<superagent.Response>((resolve, reject) => {
        superagent.get(url)
            .end(function (err, res) {
                if (!err) {
                    resolve(res);
                } else {
                    reject(err);
                }
            });
    });
}

修改app.ts为:
import api = require('./api');
import helper = require('./helper');
import cheerio = require('cheerio');

(async () => {

try {
        let urls = await api.get_index_urls();
        for (let i = 0; i < urls.length; i++) {
            await helper.wait_seconds(1);
            await api.fetch_content(urls[i]);
        }
    } catch (err) {
        console.log(err);
    }

console.log('完毕!');

})();

执行tsc
node out/app
观察输出,并去数据库检查一下
可以发现入库成功了!

用TypeScript开发爬虫程序的更多相关文章

  1. 爬虫浅谈一:一个简单c#爬虫程序

    这篇文章只是简单展示一个基于HTTP请求如何抓取数据的文章,如觉得简单的朋友,后续我们再慢慢深入研究探讨. 图1: 如图1,我们工作过程中,无论平台网站还是企业官网,总少不了新闻展示.如某天产品经理跟 ...

  2. Scrapy:运行爬虫程序的方式

    Windows 10家庭中文版,Python 3.6.4,Scrapy 1.5.0, 在创建了爬虫程序后,就可以运行爬虫程序了.Scrapy中介绍了几种运行爬虫程序的方式,列举如下: -命令行工具之s ...

  3. c# 获取网页的爬虫程序

    转载于:https://www.cnblogs.com/wzk153/p/9145684.html HtmlAgilityPack相关详解: https://www.cnblogs.com/asxin ...

  4. 如何用TypeScript开发微信小程序

    微信小程序来了!这个号称干掉传统app的玩意儿虽然目前处于内测阶段,不过目前在应用号的官方文档里已经放出了没有内测号也能使用的模拟器了. 工具和文档可以参考官方文档:https://mp.weixin ...

  5. 开发记录_自学Python写爬虫程序爬取csdn个人博客信息

    每天刷开csdn的博客,看到一整个页面,其实对我而言,我只想看看访问量有没有上涨而已... 于是萌生了一个想法: 想写一个爬虫程序把csdn博客上边的访问量和评论数都爬下来. 打算通过网络各种搜集资料 ...

  6. TypeScript开发程序

    使用TypeScript开发程序 简介 TypeScript一直发展不错,我们公司在开发新功能时,考虑到程序的可维护性,使用了TypeScript编写浏览器上的程序,我们是从零开始使用TypeScri ...

  7. ASP.NET 5系列教程 (五):在Visual Studio 2015中使用Grunt、Bower开发Web程序

    基于Visual Studio 2015,你可以: 方便的管理前端包,如jQuery, Bootstrap, 或Angular. 自动运行任务,如LESS.JavaScript压缩.JSLint.Ja ...

  8. 使用Visual Studio Code搭建TypeScript开发环境

    使用Visual Studio Code搭建TypeScript开发环境 1.TypeScript是干什么的 ? TypeScript是由微软Anders Hejlsberg(安德斯·海尔斯伯格,也是 ...

  9. python爬虫__第一个爬虫程序

    前言 机缘巧合,最近在学习机器学习实战, 本来要用python来做实验和开发环境 得到一个需求,要爬取大众点评中的一些商户信息, 于是开启了我的第一个爬虫的编写,里面有好多心酸,主要是第一次. 我的文 ...

随机推荐

  1. leetcode 172

    172. Factorial Trailing Zeroes Given an integer n, return the number of trailing zeroes in n!. Note: ...

  2. <fmt:formatDate>标签的输出格式:

    <fmt:formatDate>标签的输出格式:  d   月中的某一天.一位数的日期没有前导零.      dd   月中的某一天.一位数的日期有一个前导零.      ddd   周中 ...

  3. Java web--Filter过滤器分IP统计访问次数

    分IP统计访问次数即网站统计每个IP地址访问本网站的次数. 分析 因为一个网站可能有多个页面,无论哪个页面被访问,都要统计访问次数,所以使用过滤器最为方便. 因为需要分IP统计,所以可以在过滤器中创建 ...

  4. 有WebService的项目中写applicationContex.xml文件时应注意!!!

    这是一个简单的WebService实例,来看下如下的applicationContex.xml文件: 1.有XFire的配置 <bean id="baseWebService" ...

  5. Spring urlMapping

    背景 某url性能测试表明,qps单机最高只有4000多,虽然靠堆机器可以解决问题,但是显然不是什么优雅的方案. 试着把controller里的所有的逻辑都屏蔽,只是简单的返回hello world, ...

  6. 深入理解JS异步编程五(脚本异步加载)

    异步脚本加载 阻塞性脚本 JavaScript在浏览器中被解析和执行时具有阻塞的特性,也就是说,当JavaScript代码执行时,页面的解析.渲染以及其他资源的下载都要停下来等待脚本执行完毕 浏览器是 ...

  7. jsp中两种include的区别【转】

    引用文章:http://www.ibm.com/developerworks/cn/java/j-jsp04293/ http://www.cnblogs.com/lazycoding/archive ...

  8. VUE 入门基础(2)

    二,起步 引用方式可以使用  vue-cli <script src="https://unpkg.com/vue/dist/vue.js"></script&g ...

  9. Jquery--动画

    动画: 1.show(),hide() 2..stop() .slideDown();  向下. .stop().slideUp();  向上 (可以做下拉)        .stop() 执行之前加 ...

  10. Ubuntu 命令大全

    一.文件目录类 1.建立目录:mkdir 目录名 2.删除空目录:rmdir 目录名 3.无条件删除子目录: rm -rf 目录名 4.改变当前目录:cd 目录名 (进入用户home目录:cd ~:进 ...