增加数据库
Docker Build and Push / build-image (push) Failing after 6m27s

This commit is contained in:
cheney
2026-04-09 22:07:23 +08:00
parent 982519e701
commit 4c7f600a6b
25 changed files with 9739 additions and 1 deletions
+62
View File
@@ -0,0 +1,62 @@
# 数据爬取脚本
本目录包含用于从各种数据源爬取经济数据的脚本。
## 目录结构
- `sow-inventory-scraper.js` - 爬取能繁母猪数量数据
- `template-scraper.js` - 通用爬取脚本模板
## 依赖
- axios - 用于发送HTTP请求
- cheerio - 用于解析HTML内容
- csv-parser - 用于解析CSV格式数据
## 安装依赖
```bash
npm install
```
## 使用方法
1. **修改脚本配置**:
- 打开相应的爬取脚本
- 修改数据源URL和数据提取逻辑
2. **运行爬取脚本**:
```bash
node scripts/scraper/sow-inventory-scraper.js
```
## 注意事项
1. **数据来源合规性**:确保爬取的数据来源符合相关法律法规
2. **爬虫礼仪**:设置合理的请求间隔,避免对目标网站造成压力
3. **数据验证**:爬取后对数据进行验证,确保数据准确性
4. **错误处理**:脚本包含基本的错误处理,但可能需要根据实际情况进行调整
## 扩展指南
1. **添加新的爬取脚本**:
- 复制 `template-scraper.js` 模板
- 修改数据源URL和数据提取逻辑
- 更新数据库存储逻辑
2. **修改数据提取逻辑**:
- 使用Cheerio选择器提取HTML中的数据
- 对于CSV数据,使用csv-parser解析
- 对于JSON数据,直接处理响应数据
3. **数据存储**:
- 脚本会自动将数据存储到数据库
- 会检查数据是否已存在,存在则更新,不存在则创建
## 示例
爬取浙江省能繁母猪数量数据:
```bash
node scripts/scraper/sow-inventory-scraper.js
```
+95
View File
@@ -0,0 +1,95 @@
const axios = require('axios');
const cheerio = require('cheerio');
const fs = require('fs');
const path = require('path');
const { PrismaClient } = require('../../generated/prisma');
const prisma = new PrismaClient();
// 浙江数据开放网站URL(示例,实际需要根据真实网站修改)
const ZHEJIANG_OPEN_DATA_URL = 'https://data.zj.gov.cn/';
// 能繁母猪数量数据爬取函数
async function scrapeSowInventory() {
try {
console.log('开始爬取浙江省能繁母猪数量数据...');
// 1. 发送HTTP请求获取页面内容
const response = await axios.get(ZHEJIANG_OPEN_DATA_URL, {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
});
// 2. 解析HTML内容
const $ = cheerio.load(response.data);
// 3. 提取数据(这里需要根据实际网站结构修改选择器)
// 示例:假设数据在表格中
const data = [];
$('table').each((tableIndex, table) => {
$(table).find('tr').each((rowIndex, row) => {
if (rowIndex > 0) { // 跳过表头
const cells = $(row).find('td');
if (cells.length >= 2) {
const month = $(cells[0]).text().trim();
const inventory = parseInt($(cells[1]).text().trim());
if (month && !isNaN(inventory)) {
data.push({
month,
inventory
});
}
}
}
});
});
console.log(`爬取到 ${data.length} 条数据`);
// 4. 存储数据到数据库
for (const item of data) {
try {
// 检查数据是否已存在
const existing = await prisma.econ_SowInventory.findUnique({
where: { month: item.month }
});
if (existing) {
// 更新现有数据
await prisma.econ_SowInventory.update({
where: { month: item.month },
data: { inventory: item.inventory }
});
console.log(`更新数据: ${item.month} - ${item.inventory}`);
} else {
// 创建新数据
await prisma.econ_SowInventory.create({
data: item
});
console.log(`新增数据: ${item.month} - ${item.inventory}`);
}
} catch (error) {
console.error(`处理数据 ${item.month} 时出错:`, error.message);
}
}
console.log('数据爬取和存储完成!');
} catch (error) {
console.error('爬取数据时出错:', error.message);
} finally {
// 关闭Prisma连接
await prisma.$disconnect();
}
}
// 导出函数
module.exports = { scrapeSowInventory };
// 如果直接运行此文件
if (require.main === module) {
scrapeSowInventory();
}
+100
View File
@@ -0,0 +1,100 @@
const axios = require('axios');
const cheerio = require('cheerio');
const fs = require('fs');
const path = require('path');
const { PrismaClient } = require('../../generated/prisma');
const prisma = new PrismaClient();
// 数据源URL(需要根据实际情况修改)
const DATA_SOURCE_URL = 'https://example.com/data';
// 通用数据爬取函数
async function scrapeData() {
try {
console.log('开始爬取数据...');
// 1. 发送HTTP请求获取页面内容
const response = await axios.get(DATA_SOURCE_URL, {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
});
// 2. 解析HTML内容
const $ = cheerio.load(response.data);
// 3. 提取数据(需要根据实际网站结构修改)
const data = [];
// 示例:从表格中提取数据
$('table').each((tableIndex, table) => {
$(table).find('tr').each((rowIndex, row) => {
if (rowIndex > 0) { // 跳过表头
const cells = $(row).find('td');
// 根据实际表格结构提取数据
// 示例:假设第一列是日期,第二列是数值
if (cells.length >= 2) {
const date = $(cells[0]).text().trim();
const value = parseFloat($(cells[1]).text().trim());
if (date && !isNaN(value)) {
data.push({
date,
value
});
}
}
}
});
});
console.log(`爬取到 ${data.length} 条数据`);
// 4. 存储数据到数据库(需要根据实际表结构修改)
for (const item of data) {
try {
// 这里需要根据实际表结构修改
// 示例:存储到某个表
/*
const existing = await prisma.someTable.findUnique({
where: { date: item.date }
});
if (existing) {
// 更新现有数据
await prisma.someTable.update({
where: { date: item.date },
data: { value: item.value }
});
console.log(`更新数据: ${item.date} - ${item.value}`);
} else {
// 创建新数据
await prisma.someTable.create({
data: item
});
console.log(`新增数据: ${item.date} - ${item.value}`);
}
*/
} catch (error) {
console.error(`处理数据时出错:`, error.message);
}
}
console.log('数据爬取和存储完成!');
} catch (error) {
console.error('爬取数据时出错:', error.message);
} finally {
// 关闭Prisma连接
await prisma.$disconnect();
}
}
// 导出函数
module.exports = { scrapeData };
// 如果直接运行此文件
if (require.main === module) {
scrapeData();
}