Demo(爬取halihali的电影标题和图片)
分析:需要爬取http://halihali28.com/mov/地址的图片,可以获取img标签里面的图片地址和alt属性标题;
了解:fs,cheerio,superagent,ts入门
步骤:
1、设置工作空间,使用npm init -y命令(注意父目录不能有中文);由于练习的是ts,我们在执行tsc --init,生成tsconfig.json文件;最后执行npm install typescript -D。
2、手动创建src目录(这里就是我们主要的工作区),在src目录下创建index.ts目录
3、设计一个类(命名随意:News),设置私有属性:爬取的网页地址url,数据保存的地址path;
class News{
//爬取的网站地址
private url:string = "http://halihali28.com/mov/";
//文件保存的地址(在src同级目录创建一个data目录)
private path:string = "./data/data.json"
}
4、设置方法
初始化方法
async init(){
// 获取网页内容
const html = await this.getHtml();
// 为获取到的数据加上一个时间属性
const timeContent = this.getTimeContent(JSON.stringify(html));
// 写入文件(整理已经存在的数据和本次获取的数据)
this.writeFile( this.setFileContent(timeContent) )
}
构造函数内调用初始化方法
constructor(){
this.init()
}
· 获取网页信息
执行npm i superagent -D,导入
import superagent from "superagent";
// 获取网页信息
async getHtml(){
const result =await superagent.get(this.url);
return result;
}
分析和设置数据的结构
执行npm i cheerio -D,导入
import * as cheerio from "cheerio";
图片地址和标题的数据接口
interface Content{
url:string;
title:string;
}
获取时间和获取数组的接口
interface TimeContent{
time:number,
content:Content[]
}
// 分析和结构数据
getTimeContent(html:string){
// 将获取的网页内容调用cheerio.load方法并返回
const $ = cheerio.load(html)
// 这里用法和jQuery有点像,获取所有img标签
const elements = $('img')
// 获取img标签里面的data-original属性值(图片地址)和
// alt属性值(标题)
let content:Content[] = []
for (let index = 0; index < elements.length; index++) {
content.push({
url: $(elements[index]).attr('data-original') as string,
title:$(elements[index]).attr('alt') as string
})
}
// 对上面获取到的数据再添加一个时间属性
const TimeContent:TimeContent = {
time: (new Date()).getTime(),
content:content
}
return TimeContent;
}
整理已经存在的数据和本次获取的数据
导入fs
import fs from "fs";
写入文件数据类型的接口
interface FileContent{
[propName:number] : Content[]
}
// 读取已经存在的文件
setFileContent(timeContent:TimeContent):FileContent{
// 定义写入文件数据的格式
let fileContent: FileContent = {}
// 同步判断该文件是否存在
if(fs.existsSync(this.path)){
// 若是存在获取文件内之前的数据内容,(文件若是空的话,先删除掉,否则这里会有一个小错误)
fileContent = JSON.parse(fs.readFileSync(this.path,"utf8"))
}
// 加入本次获取的数据其中属性名为获取时间,属性值为获取数组
fileContent[timeContent.time] = timeContent.content;
return fileContent;
}
写入文件
writeFile(fileContent:FileContent){
// 若是该文件不存在,这里会自动创建
fs.writeFileSync(this.path,JSON.stringify(fileContent),"utf8")
}
执行
实例化
new News();
package.json中添加npm run dev执行代码
执行npm run dev即可
5、完整代码index.ts
import superagent from "superagent";
import * as cheerio from "cheerio";
import fs from "fs";
interface Content{
url:string;
title:string;
}
interface TimeContent{
time:number,
content:Content[]
}
interface FileContent{
[propName:number] : Content[]
}
class News{
private url:string = "http://halihali28.com/mov/";
private path:string = "./data/data.json"
// 获取网页信息
async getHtml(){
const result =await superagent.get(this.url);
return result;
}
// 分析和结构数据
getTimeContent(html:string){
// 将获取的网页内容调用cheerio.load方法并返回
const $ = cheerio.load(html)
// 这里用法和jQuery有点像,获取所有img标签
const elements = $('img')
// 获取img标签里面的data-original属性值(图片地址)和
// alt属性值(标题)
let content:Content[] = []
for (let index = 0; index < elements.length; index++) {
content.push({
url: $(elements[index]).attr('data-original') as string,
title:$(elements[index]).attr('alt') as string
})
}
// 对上面获取到的数据再添加一个时间属性
const TimeContent:TimeContent = {
time: (new Date()).getTime(),
content:content
}
return TimeContent;
}
// 读取已经存在的文件
setFileContent(timeContent:TimeContent):FileContent{
// 定义写入文件数据的格式
let fileContent: FileContent = {}
// 同步判断该文件是否存在
if(fs.existsSync(this.path)){
// 若是存在获取文件内之前的数据内容,(文件若是空的话,先删除掉,否则这里会有一个小错误)
fileContent = JSON.parse(fs.readFileSync(this.path,"utf8"))
}
// 加入本次获取的数据其中属性名为获取时间,属性值为获取数组
fileContent[timeContent.time] = timeContent.content;
return fileContent;
}
writeFile(fileContent:FileContent){
// 若是该文件不存在,这里会自动创建
fs.writeFileSync(this.path,JSON.stringify(fileContent),"utf8")
}
async init(){
// 获取网页内容
const html = await this.getHtml();
// 为获取到的数据加上一个时间属性
const timeContent = this.getTimeContent(JSON.stringify(html));
// 写入文件(整理已经存在的数据和本次获取的数据)
this.writeFile( this.setFileContent(timeContent) )
}
constructor(){
this.init()
}
}
new News();
// superagent cheerio