카카오맵에서 식당정보를 스크래핑해서 몽고DB 컬렉션에 저장하는데 성공했다👀
나중에 상호명이나 평점이 바뀔 수 있기 때문에 주소에 unique를 주고 주소가 중복돼서 에러가 나면 그때 최신 데이터로 업데이트하도록 하면 됐다(덮어쓰기).
1. 최초에 크롤링 데이터를 수집해서 db에 저장
└ 크롤링 하면서 주소가 중복되면 에러(E11000) 발생하고 저장이 안됨
2. 이후 크롤링에서 데이터를 저장할 때 고려사항
└ 주소가 중복되면 새롭게 크롤링한 내용 덮어쓰기
address를 고유하게 설정해서 동일한 식당인지 구별할 수 있도록 했다. certicied는 인증된 채식식당인지 여부이고, certicifation은 인증되었다면 그 인증정보를 담도록 했다.
import mongoose, { Schema } from 'mongoose';
const restaurantSchema = new Schema({
title: {
type: String,
},
category: {
type: String,
},
rating: {
type: String,
},
address: {
type: String,
unique: 1,
},
certified: {
type: Boolean,
default: false,
},
certification: {
type: String,
},
});
const Restaurant = mongoose.model('Restaurant', restaurantSchema);
export default Restaurant;
// puppeteer에서 saveScrapped로 데이터 전달
if (typeof category === 'string') {
if (!excludeCategory.includes(category)) { // 제외하고 싶은 키워드 필터링
saveScrapped({
title: ...,
category: ...,
rating: ...,
address: ...,
certified: false,
certification: null,
});
}
}
// saveScrapped.ts
import type { scrappedData } from '../scrapper';
import fetch from 'node-fetch';
export async function saveScrapped(item: scrappedData) {
try {
const res = await fetch(`http://localhost:3000/api/scrappers/save`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(item),
});
const data: any = await res.json();
if (data.saveSuccess) {
console.log('저장완료--');
} else {
console.log('❌❌❌', data.errorMessage);
}
} catch (err) {
console.error(err);
}
}
save()
를 사용하여 문서를 업데이트하는 경우, findOne()
을 사용하여 문서를 로드할 때와 save()
를 사용하여 문서를 저장할 때 사이에 MongoDB에서 문서가 변경될 수 있다. 이 문제를 findOneAndUpdate
가 해결할 수 있다고 설명되어 있다(mongoose docs에서 예제확인).app.post('/api/scrappers/save', (req, res) => {
const restaurant = new Restaurant(req.body);
restaurant.save(async (err, restaurantInfo) => {
if (err) { // 주소가 같으면 err가 발생
if (err.message.includes('E11000')) { // 중복 에러면
const filter = { address: req.body.address };
const update = { ...req.body };
// filter에 해당하는 문서를 update 변수에 담긴 내용으로 변경하기
await Restaurant.findOneAndUpdate(filter, update);
}
}
return res.status(200).json({ saveSuccess: true });
});
});
postman으로 요청한 후 몽고DB의 Restaurants 컬렉션에서 잘 업데이트 된 것을 확인할 수 있다. 주소를 그대로 유지하고 나머지 값을 변경하면 잘 바뀐다.