描述文件的介绍
package.json 文件是 Node.js 项目中的核心配置文件,类似于项目的“心脏”,它描述了项目的基本信息、依赖项、脚本命令等内容,便于项目的管理与发布
{
"name": "x-crawl",
"version": "0.0.1",
"main": "index.mjs",//入口文件
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"x-crawl":"^10.0.2"
}
}
1. dependencies 依赖部分
在 package.json 中,dependencies 用于列出项目在运行时所需要的第三方模块。通常这些模块是你的应用程序在生产环境中必需的。
例如,在上面的 package.json 文件中:
"dependencies": {
"react": "^18.0.0",
"axios": "^0.21.1"
}
表示该项目依赖于 react 和 axios,这两者会被安装到 node_modules 文件夹中,并在项目运行时使用。
devDependencies 开发依赖部分
devDependencies 用于列出开发时需要的模块,例如构建工具、测试框架等。它们只在开发过程中使用,不会在生产环境中被安装。
2.scripts 部分
package.json 中的 scripts 部分定义了项目中常用的命令,用户可以通过 npm run <script> 来执行相应的操作。这一部分是 package.json 中的一个重要部分,因为它简化了常见任务的执行。
例如:
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production"
}
npm run dev会执行webpack --mode development,启动开发模式的构建。npm run build会执行webpack --mode production,启动生产模式的构建。
3.版本号
语义化版本号由三部分组成:主版本号(major)、次版本号(minor)、修订号(patch)。它们的格式为 MAJOR.MINOR.PATCH。
- 主版本号(MAJOR):当你做了不兼容的 API 修改时,增加主版本号。
- 次版本号(MINOR):当你在保持向后兼容的情况下添加功能时,增加次版本号。
- 修订号(PATCH):当你做了向后兼容的问题修正时,增加修订号。
2. 版本号示例
1.0.0 —— 正式版,商用成熟
1.0.0 是一个正式版,表示该版本功能完整、稳定并且已经可以用于商用。
2.0.0 —— 有本质的功能性改变
当你对项目进行了较大的功能性修改或重构,且可能导致使用者的学习成本增加时,可以发布 2.0.0 版本。例如,API 接口有大的变化,导致原有的用法无法再正常工作。
2.2.0 —— 添加了某项功能
2.2.0 版本通常表示该版本在原有功能的基础上新增了某项功能。这个版本是向后兼容的,即现有的功能仍然可以使用。
2.2.1 —— 修复了某项 bug
2.2.1 表示该版本主要修复了一个或多个 bug,并保持了现有功能的不变。这类更新通常是小范围的修复,主要针对用户反馈的错误进行调整。
x-crawl 爬虫AI工具的使用
1.导入一下我们要使用的x-crawl依赖。
{
"name": "x-crawl",
"version": "0.0.1",
"main": "index.mjs",//入口文件
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"x-crawl":"^10.0.2"
}
}
2.使用 npm i 命令下载依赖
3.创建入口文件 index.js,并引入要使用的x-crawl的两个函数
import {createCrawl //返回爬虫示例
,createCrawlOpenAI //OpenAI配置项
} from 'x-crawl';
在这里我使用了解构赋值,模块中导出的函数,通过解构赋值,我们可以直接将它们导入到当前模块中,并分别赋值给 createCrawl 和 createCrawlOpenAI 变量。解构是es6的一个新特性。文章的最后将会介绍一下解构的用法。
4.实例化爬虫应用
// 使用 createCrawl 函数创建一个爬虫应用实例
const cralwApp = createCrawl({
// 配置爬虫的最大重试次数为 3
maxRetry: 3,
// 配置爬虫的重试间隔时间,最小为 1000 毫秒,最大为 2000 毫秒
intervalTime: {
min: 1000,
max: 2000
},
});
5.创建爬虫AI的实例
const cralwAppOpenAI = createCrawlOpenAI({
clientOptions:{ apiKey:'api-key',
baseURL:'baseurl'
},
defaultModel:{
chatModel:'gpt-4-turbo-preview'
}
})
6.使用爬虫应用和爬虫AI进行爬取和处理数据
cralwApp.crawlPage('http://movie.douban.com/chart')
// 处理爬取结果
.then(async(res) =>{
// 从响应中提取 page 和 browser 对象
const{page,browser} = res.data;
console.log(res.data);
// 定义目标选择器
const targetSelector = '.indent';
// 等待目标选择器匹配的元素加载完成
await page.waitForSelector(targetSelector);
// 等待页面加载完成指定选择器的元素
await page.waitForSelector(targetSelector);
const highlyHTML = await page.$eval(// 使用 page.$eval 方法获取选择器匹配的第一个元素的内部 HTML 内容
targetSelector,
(el) => el.innerHTML // 这是一个回调函数,el 表示匹配到的元素
);
// 使用 cralwAppOpenAI 实例的 parseElements 方法解析 HTML 内容
const result = await cralwAppOpenAI.parseElements(
highlyHTML,
`get the image link`//让AI提取数据的prompt
)
// 关闭浏览器
browser.close();
// 使用 cralwApp 实例的 crawlFile 方法下载图片
cralwApp.crawlFile({
targets:result.elements[0].src,
storeDirs:'./download'
})
})
答疑:爬虫怎么获取得到ajax请求的数据呢?
首先我们了解一下页面获取数据的两种不同方式:
-
普通页面请求: 如果你访问一个普通的网页,它通常会返回 HTML 内容。在这些 HTML 页面中,有可能嵌入了 JavaScript,这个 JavaScript 会在浏览器端进一步发起 AJAX 请求,从后台 API 获取数据并动态渲染到页面中。这种情况下,你在浏览器中看到的是最终的页面内容,包括数据。
-
数据直接嵌入页面: 如果你通过 APIFox 直接访问某个页面 URL,而这个页面返回的就是包含数据的 HTML 内容,那就意味着数据是直接在页面渲染时就被注入到 HTML 中的。这通常发生在:
- 服务器端渲染(SSR):服务器直接将数据渲染到页面中,返回的是一个完整的、包含数据的 HTML 页面,而不是一个空的 HTML 页面等待客户端通过 JavaScript 获取数据。
- 服务端动态生成页面内容:页面本身可能是一个动态生成的页面,它的 HTML 内容本身就包含了需要的数据(比如以 JSON 或嵌套数据的格式)。
也就是说,假如页面是先返回结构,然后通过用户端的JS代码执行ajax请求去获取数据的话,这样一次请求是获取不到ajax请求中的数据的。
爬虫库通常能获取到后续的 AJAX 数据,是因为它们内置了一些模拟浏览器行为的机制,这样就能够发送与真实浏览器一样的请求,从而获取数据。
解构赋值
解构赋值(Destructuring Assignment)是一种从数组或对象中提取值并将其赋给变量的简洁方法。
刚刚我使用了import {createCrawl, createCrawlOpenAI} from 'x-crawl';
这行代码使用了 ES6 的解构赋值来从 x-crawl 模块中
导入 createCrawl 和 createCrawlOpenAI 函数。并赋值给变量
一、数组解构赋值
数组解构赋值允许你从数组中提取元素,并将它们赋给相应的变量。
1. 基本语法
let [a, b] = [1, 2];
console.log(a); // 输出 1
console.log(b); // 输出 2
a和b分别接收数组[1, 2]中的第一个和第二个元素。
2. 跳过元素
你可以使用逗号来跳过不需要的元素:
let [a, , c] = [1, 2, 3];
console.log(a); // 输出 1
console.log(c); // 输出 3
- 在这个例子中,第二个元素(
2)被跳过了。
3. 默认值
你可以为解构赋值中的变量设置默认值。如果数组中没有对应的值,则会使用默认值:
let [a = 10, b = 20] = [1];
console.log(a); // 输出 1
console.log(b); // 输出 20
a被赋值为1,而b由于没有值,使用默认值20。
4. 剩余元素
使用 ...(扩展运算符)来将剩余的元素收集到一个数组中:
let [a, ...rest] = [1, 2, 3, 4];
console.log(a); // 输出 1
console.log(rest); // 输出 [2, 3, 4]
- 这里,
a取第一个元素,剩下的元素被收集到rest数组中。
5. 嵌套解构
你还可以进行嵌套解构,提取嵌套数组中的值:
let [a, [b, c]] = [1, [2, 3]];
console.log(a); // 输出 1
console.log(b); // 输出 2
console.log(c); // 输出 3
二、对象解构赋值
对象解构赋值允许你从对象中提取属性并将它们赋值给变量。
1. 基本语法
let {a, b} = {a: 1, b: 2};
console.log(a); // 输出 1
console.log(b); // 输出 2
- 变量
a和b被赋予对象{a: 1, b: 2}中对应的属性值。
2. 给变量起别名
如果你想将对象属性赋给不同名称的变量,可以使用 : 来指定新名称:
let {a: x, b: y} = {a: 1, b: 2};
console.log(x); // 输出 1
console.log(y); // 输出 2
- 这里,
a被赋给变量x,b被赋给变量y。
3. 默认值
如果对象中没有某个属性,你可以为其设置默认值:
let {a = 10, b = 20} = {a: 1};
console.log(a); // 输出 1
console.log(b); // 输出 20
a的值是对象中的值1,而b没有在对象中,所以使用默认值20。
4. 嵌套解构
你还可以解构嵌套的对象:
let obj = {a: 1, b: {x: 2, y: 3}};
let {a, b: {x, y}} = obj;
console.log(a); // 输出 1
console.log(x); // 输出 2
console.log(y); // 输出 3
- 这里,
b是一个嵌套对象,你可以通过解构直接提取x和y的值。
5. 剩余属性
你可以使用剩余属性(...)收集对象中剩余的属性:
let {a, ...rest} = {a: 1, b: 2, c: 3};
console.log(a); // 输出 1
console.log(rest); // 输出 {b: 2, c: 3}
a取值为1,剩余的属性被收集到rest对象中。