Cheerio로 스크레이퍼를 만드는 방법
node.js
과 함께 사용할 수 있는 frontend
으로 스크랩한 데이터로 API를 생성합니다.이 예에서 사용할 웹사이트는 pricecharting입니다.
You can contact me by telegram if you need to hire a Full Stack developer.
discord Appu#9136으로 저에게 연락할 수도 있습니다.
You can clone the repo if you want.
이 예제는 학습 목적으로만 사용됩니다.
프로젝트 생성
종속성
종속성을 설치하려면 프로젝트 폴더로 이동하여 터미널을 열고 다음을 입력하십시오.
npm i axios cheerio express mongoose
그리고 dev 종속성 유형의 경우
npm i -D nodemon
프로젝트 파일 구조:
node-cheerio-tut/
├── node_modules/
├── 공개/
├── 소스/
│ ├── 노선/
│ ├── 데이터베이스.js
│ └── index.js
└── 패키지.json
목차
먼저
package.json
으로 이동하여 다음 행을 추가하십시오. "scripts": {
"start": "node ./src index.js",
"dev": "nodemon ./src index.js"
},
코딩하자
1. 프로젝트 설정
lets go to index.js inside the src folder and set up our basic server with express.
const expres = require('express')
const app = express()
//server
app.listen(3000, () => {
console.log('listening on port 3000')
})
now let's run this command npm run dev
and we should get this message:
listening on port 3000
Now in our index.js lets import axios and cheerio, then i''ll explain the code below.
- we're going to add a const url with the url value, in this case
https://www.pricecharting.com/search-products?q=
. (when you do a search in this web, you will be redirected to a new page, with a new route and a parameter with the value of the name you searched for.)
따라서 우리는 해당 URL을 사용할 것입니다. 또한 웹사이트에는 두 가지 유형의 검색이 있습니다. 하나는 가격 기준이고 다른 하나는 시장 기준입니다. URL에 유형을 지정하지 않으면 기본적으로 시장 유형이 설정됩니다. 시장에서 게임 커버와 시스템을 반환하기 때문에 이렇게 둡니다(나중에 사용하겠습니다).
app.use(express.json())
을 얻고 싶지 않기 때문에 이 미들웨어 undefined
을 추가할 것입니다. test.http
POST http://localhost:3000
Content-Type: application/json
{
"game": "final fantasy"
}
final fantasy
보시다시피 우리는 응답을 받고 있습니다. 이 경우 속성 게임의 이름을 지정했습니다.
const axios = require("axios");
const cheerio = require("cheerio");
const express = require('express')
//initializations
const app = express()
const url = "https://www.pricecharting.com/search-products?q="
//middlwares
app.use(express.json())
app.post('/', async (req, res) => {
// console.log(req.body.game)
const game = req.body.game.trim().replace(/\s+/g, '+')
})
//server
app.listen(3000, () => {
console.log('listening on port 3000')
})
req.body.game
의 값을 저장할 게임이라는 상수를 만들 것입니다. 몇 가지 방법을 사용하여 final+fantasy
과 같은 결과를 얻을 것입니다. trim()
을 사용하여 문자열의 시작과 끝에서 공백 문자를 제거합니다. +
기호로 replace(/\s+/g, '+')
으로 바꿉니다. REST 클라이언트 2. Cheerio를 사용하여 데이터 스크랩하기
Finally we're going to use cheerio.
Now that we have our game constant we're going to use axios to make a request to our url + the game title.
We are going to use a
try catch block
, if we get a response then we will store it in a constant namedhtml
then we will use cherrio to load that data.We are going to create a constant named games that will store this value
$(".offer", html)
.
- If you open your developer tools and go to the elements tab you will that .offer class belongs to a table like the image below.
.find(".product_name")
, .find(".a")
을 사용하여 수행할 수 있습니다. 그런 다음 a 태그에서 text()
을 원합니다..
.
.
app.post('/', async (req, res) => {
const game = req.body.game.trim().replace(/\s+/g, '+')
await axios(url + game)
try {
const response = await axios.get(url + game)
const html = response.data;
const $ = cheerio.load(html)
const games = $(".offer", html)
games.each((i, el) => {
const gameTitle = $(el)
.find(".product_name")
.find("a")
.text()
.replace(/\s+/g, ' ')
.trim()
console.log(gameTitle)
})
} catch (error) {
console.log(error)
}
})
.
.
.
console.log(title)
으로 시도하면 다음과 같은 메시지가 표시됩니다.Final Fantasy VII
Final Fantasy III
Final Fantasy
Final Fantasy VIII
Final Fantasy II
.
.
.
.
.
.
app.post('/', async (req, res) => {
const game = req.body.game.trim().replace(/\s+/g, '+')
await axios(url + game)
try {
const response = await axios.get(url + game)
const html = response.data;
const $ = cheerio.load(html)
const games = $(".offer", html)
games.each((i, el) => {
const gameTitle = $(el)
.find(".product_name")
.find("a")
.text()
.replace(/\s+/g, ' ')
.trim()
const id = $(el).attr('id').slice(8);
//cover image
const coverImage = $(el).find(".photo").find("img").attr("src");
const system = $(el)
.find("br")
.get(0)
.nextSibling.nodeValue.replace(/\n/g, "")
.trim();
})
} catch (error) {
console.log(error)
}
})
.
.
.
3. 응답 보내기
Let's store this data in an array, so in order to do this, lets create an array named videoGames
.
.
.
const url = "https://www.pricecharting.com/search-products?q=";
let videoGames = []
app.post('/', async (req, res) => {
const game = req.body.game.trim().replace(/\s+/g, '+')
await axios(url + game)
try {
const response = await axios.get(url + game)
const html = response.data;
const $ = cheerio.load(html)
const games = $(".offer", html)
games.each((i, el) => {
const gameTitle = $(el)
.find(".product_name")
.find("a")
.text()
.replace(/\s+/g, ' ')
.trim()
const id = $(el).attr('id').slice(8);
//cover image
const coverImage = $(el).find(".photo").find("img").attr("src");
const gameSystem = $(el)
.find("br")
.get(0)
.nextSibling.nodeValue.replace(/\n/g, "")
.trim();
})
videoGames.push({
id,
gameTitle,
coverImage,
gameSystem
})
res.json(videoGames)
} catch (error) {
console.log(error)
}
})
.
.
.
if you try the route again you will get a result similar to the image below
선택적으로 나는 PAL과 NTSC 시스템과 같은 타이틀을 받고 싶지 않았기 때문에 특정 시스템만 가져오도록 배열을 만들었기 때문에 기본 시스템(NTSC)을 그대로 두었습니다.
.
.
.
const consoles = [
"Nintendo DS",
"Nintendo 64",
"Nintendo NES",
"Nintendo Switch",
"Super Nintendo",
"Gamecube",
"Wii",
"Wii U",
"Switch",
"GameBoy",
"GameBoy Color",
"GameBoy Advance",
"Nintendo 3DS",
"Playstation",
"Playstation 2",
"Playstation 3",
"Playstation 4",
"Playstation 5",
"PSP",
"Playstation Vita",
"PC Games",
]
.
.
.
app.post('/', async (req, res) => {
.
.
.
if (!system.includes(gameSystem)) return;
videoGames.push({
id,
gameTitle,
coverImage,
gameSystem,
});
.
.
.
})
.
.
.
4. 코드 구성
조금 정리하자면, route라는 이름의 src에 폴더를 만든 다음 index.js라는 파일을 만듭니다. 아래 코드를 복사하여 붙여넣으세요. const {라우터} = 요구('익스프레스') const cheerio = require("cheerio"); const axios = require("축"); const 라우터 = 라우터() const URL = "https://www.pricecharting.com/search-products?q=" let videoGames = [] 상수 시스템 = [ "닌텐도 DS", "닌텐도 64", "닌텐도 NES", "닌텐도 스위치", "슈퍼 닌텐도", "게임 큐브", "위", "위 유", "스위치", "게임 보이", "게임보이 컬러", "게임보이 어드밴스", "닌텐도 3DS", "플레이 스테이션", "플레이 스테이션 2", "플레이 스테이션 3", "플레이 스테이션 4", "플레이스테이션 5", "PSP", "플레이스테이션 비타", "PC 게임", ] router.post('/', async (req, res) => { const 게임 = req.body.game.trim().replace(/\s+/g, '+') await axios(url + 게임) 노력하다 { const 응답 = await axios.get(url + 게임) const html = 응답.데이터; const $ = cheerio.load(html) const 게임 = $(".offer", html) games.each((i, 엘) => { const gameTitle = $(el) .find(".제품_이름") .을 찾다") .텍스트() .replace(/\s+/g, ' ') .손질() const id = $(el).attr('id').slice(8); const coverImage = $(el).find(".photo").find("img").attr("src"); const gameSystem = $(el) .find("br") .get(0) .nextSibling.nodeValue.replace(/\n/g, "") .손질(); if (!system.includes(gameSystem)) 반환; videoGames.push({ ID, 게임 제목, 표지 이미지, 게임 시스템, 백로그: 거짓 }); }) res.json(비디오게임) } 잡기(오류) { 콘솔.로그(오류) } }) module.exports = 라우터 이제 src index.js의 기본 파일로 돌아가서 코드를 다음과 같이 남겨둡니다. const 익스프레스 = 요구('익스프레스') //경로 const main = 요구('./routes/index') const 앱 = 익스프레스() //미들웨어 app.use(express.json()) //경로 app.use(메인) app.listen(3000, () => { console.log('포트 3000에서 실행 중인 서버') }) 사용해보시면 별 문제 없이 잘 작동하는 것을 확인하실 수 있습니다. 5. 결론
We learned how to make a simple scraper with cheerio.
I really hope you have been able to follow the post without any trouble, otherwise i apologize, please leave me your doubts or comments.
I plan to make a next post extending this code, adding more routes, mongodb, and a front end.
discord Appu#9136으로 저에게 연락할 수도 있습니다.
You can contact me by telegram if you need to hire a Full Stack developer.
시간 내 줘서 고마워.
Reference
이 문제에 관하여(Cheerio로 스크레이퍼를 만드는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/rtagliavia/how-to-scrap-data-with-cheerio-cdc텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)