最近刚学typescript,想着能用来作点什么,顺便也练练手,加之最近也有个想法,前提是须要解决数据来源的问题,因此尝试一下能不能用ts来写一个爬虫,而后存到数据库里面为我所用,下面就是个人实践过程html
全局安装typescriptnode
npm install -g typescript
复制代码
建立项目文件夹mysql
mkdir ts-spider
复制代码
进入该文件夹之后初始化项目ios
npm init -y
复制代码
下面要安装一下项目中用到的模块git
npm i --save axios cheerio mysql
复制代码
相应的,要安装一下对应的类型声明模块github
npm i -s @types/axios --save
npm i -s @types/cheerio --save
npm i -s @types/mysql --save
复制代码
其实axios已经自带类型声明,因此不安装也是能够的sql
下面安装一下项目内的typescript(必须走这一步)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"
]
}
复制代码
到这里咱们的环境搭建算基本完成了,下面咱们来测试下npm
在项目根目录下建立一个api.ts文件,写入如下代码
import axios from 'axios'
/**网络请求 */
export const remote_get = function(url: string) {
const promise = new Promise(function (resolve, reject) {
axios.get(url).then((res: any) => {
resolve(res.data);
}, (err: any) => {
reject(err);
});
});
return promise;
}
复制代码
建立一个app.ts文件,写入如下代码
import { remote_get } from './api'
const go = async () => {
let res = await remote_get('http://www.baidu.com/');
console.log(`获取到的数据为: ${res}`);
}
go();
复制代码
执行一下命令
tsc
复制代码
咱们发现项目根目录想多了一个/out文件夹,里面是转换后的js文件
咱们执行一下
node out/app
复制代码
输出相似这样,就表明咱们的爬虫已经爬到了这个网页,环境测试已经经过了!接下来咱们尝试一下抓取其中的数据
咱们将app.ts重构一下,引入cheerio,开始抓取咱们须要的数据,固然了,此次咱们换一下目标,咱们抓取一下豆瓣上面的的数据
前面也提到了cheerio提供了jQuery Selector的解析能力,关于它的具体用法,能够点击这里查看
import { remote_get } from './api'
import * as cheerio from 'cheerio'
const go = async () => {
const res: any = await remote_get('https://www.douban.com/group/szsh/discussion?start=0');
// 加载网页
const $ = cheerio.load(res);
let urls: string[] = [];
let titles: string[] = [];
// 获取网页中的数据,分别写到两个数组里面
$('.olt').find('tr').find('.title').find('a').each((index, element) => {
titles.push($(element).attr('title').trim());
urls.push($(element).attr('href').trim());
})
// 打印数组
console.log(titles, urls);
}
go();
复制代码
这段代码是获取豆瓣上小组话题和对应的连接,而后写入数组里面,分别打印出来。咱们跑一下代码,看看输出
能够看到已经获取到咱们想要的数据了。接下来咱们尝试把这些数据写入到数据库里面
开始的时候实际上是想把数据写到MongoDB里面,可是考虑到本身对这个还不太熟,和本身手头的体验版服务器那一点点可怜的空间,最后仍是放弃了,仍是决定先尝试写到mysql数据库里面
咱们先本地安装一个mysql数据库,安装过程就不详细说了,安装完后在本地数据库中新建一个表
在项目根目录下添加util.ts文件,写入一下代码
import * as mysql from 'mysql'
/* 延时函数 */
export function sleep(msec: number) {
return new Promise<void>(resolve => setTimeout(resolve, msec));
}
/**
* 封装一个数据库链接的方法
* @param {string} sql SQL语句
* @param arg SQL语句插入语句的数据
* @param callback SQL语句的回调
*/
export function db(sql: string, arg: any, callback?: any) {
// 1.建立链接
const config = mysql.createConnection({
host: 'localhost', // 数据库地址
user: 'root', // 数据库名
password: '', // 数据库密码
port: 3306, // 端口号
database: 'zhufang' // 使用数据库名字
});
// 2.开始链接数据库
config.connect();
// 3.封装对数据库的增删改查操做
config.query(sql, arg, (err:any, data:any) => {
callback(err, data);
});
// 4.关闭数据库
config.end();
}
复制代码
以上咱们已经封装好了一个数据库链接的方法,其中包含了数据库的配置信息,下面咱们修改app.ts文件,引入咱们封装好的db模块,并写入数据的操做代码
import { remote_get } from './api'
import * as cheerio from 'cheerio'
import { sleep, db } from './util'
const go = async () => {
const res: any = await remote_get('https://www.douban.com/group/szsh/discussion?start=0');
// 加载网页
const $ = cheerio.load(res);
let urls: string[] = [];
let titles: string[] = [];
// 获取网页中的数据,分别写到两个数组里面
$('.olt').find('tr').find('.title').find('a').each((index, element) => {
titles.push($(element).attr('title').trim());
urls.push($(element).attr('href').trim());
})
// 打印数组
console.log(titles, urls);
// 往数据库里面写入数据
titles.map((item, index) => {
db('insert into info_list(title,url) values(?,?)', [item, urls[index]], (err: any, data: any) => {
if(data){
console.log('提交数据成功!!')
}
if (err) {
console.log('提交数据失败')
}
})
})
}
go();
复制代码
这里咱们往数据库中插入title数组和urls数组的数据。跑一下代码,看了输出没有问题,咱们看下数据库
数据已经写入了!到这里咱们的此次实践就告一段落
下面考虑的是爬取数据过快的延时机制,和如何分页获取数据,如何获取爬到的连接对应的详细信息,功能模块化等等,这里就不细说了
参考文档
https://cloud.tencent.com/info/d0dd52a4a2b1f90055afe4fac4dcd76b.html https://hpdell.github.io/%E7%88%AC%E8%99%AB/crawler-cheerio-ts/