dukDukz
[블록체인] 데몬에 http로 요청하기, 크롤링 [수업내용] 본문
오늘의 목표
→ 데몬을 http 통신으로
데몬의 내용을 볼때 cli 라는걸 활용했었다.
cli API 들을 배웠고...
데몬과 인터넷을 연결하고,
인터넷에서는 우리가 볼 수 있는 화면 (거래소) 를 만든다.
브라우저에 뭔가를 띄우고 한다는 뜻...
간단하게 말해서.. 이 데몬으로 요청을 보낼때, cli 로 하는게 아니라 http 통신으로 해보겠다는 것이다.
cli 도 PRC 통신..
거의 http 와 흡사하다.
그래서 http 로 요청했을 때 응답을 받을 수 있다.
그리고 응답을 받은것을 터미널에서 보여주는게 아니라 브라우저에 띄울 것이다.
# 단계
1. http 요청 - 응답이 잘 오는가?
2. node js 환경(express)에서 http 요청을 한 것을 코드로 옮겨서 테스트를 해본다.
(어떻게 처리하는지도 알아볼 것이다.) - 응답 받는것까지.
express 로 다른 곳(다른 서버)에 요청을 보내서 값을 가져오는.. 그런느낌으로..
API 를 쓴다는 뜻.
코드 구성을 이해해보고...
그 쪽에 포커스를 맞춰서 해보자
http 로 한다는 것은 curl 로 데몬에게 요청을 보내야 함.
curl 을 쓰기 위해서 어떤 환경을 구축해야 할까?
- 데몬이 잘 돌아가는지 확인하기 위해서 cli 로 테스트 해보고 그 다음에 curl 로 되는지 해보자
[getnewaddress]
1. cli 로 요청
데몬 1 켜고
클라 1에
.\juncoin-cli.exe -conf="C:\Users\USER\juncoin\bin\juncoin1.conf" getnewaddress ingoo4
하면
jRj1TuXBSfQCG6becMBmXWaS9KsZ5wZWMH
이렇게 나온다.
2. http 로 요청해본다.
curl 은 윈도우 터미널이 아닌 wsl 에서 가능한 녀석이다. (쉘)
탭을 하나 열어서 wsl 로 들어가자
# curl 요청 형식
-H : header
-d : data
-X : Request method
curl [option][도메인]
curl -X POST -H "" -d "data~" http://naver.com
이렇게 썼었는데
RPC 통신에는 user와 pw 가 들어간다.
1) 도메인
[도메인]=RPCUSER:RPCPASSWORD@IPADDRESS:RPCPORT
데몬1
RPCUSER = ingoo
RPCPASSWORD = 1234
IPADDRESS = 127.0.0.1
RPCPORT = 3000
[도메인] = ingoo:1234@127.0.0.1:3000
이게 주소(도메인)이 되는 것이다.
2) Header
curl -X POST -H "Content-type:application/json" -d "{}" ingoo:1234@127.0.0.1:3000
H 는 컨텐츠 타입... json 형태로 데이터를 주고 받기 때문에
data 는 객체 형태로 들어가게 된다.
클라에서 요청 할때,
getnewaddress 를 했는데
curl 형태에서는 body 영역에 들어가게 된다.
3) data
data 부분
method : 데몬 API 명
params : 인자값, 인자값이 많은경우를 대비해서 배열을 사용함
{
"method":"getnewaddress","params":["ingoo5"]
}
curl 요청
curl -X POST -H "Content-type:application/json" -d '{"method":"getnewaddress","params":["ingoo5"]}' ingoo:1234@127.0.0.1:3000
이렇게 쓰게 된다. - wsl 에서 이걸 입력해보자 (/mnt/c/Users/USER 여기에서 요청하면 된다.)
그러면 결과가
{"result":"jXcGe7mXeqdxcYjKvezNrLGWWvqrBf7gJy","error":null,"id":null}
이렇게 나오게 된다.
getnewaddress 도 http 로 요청할 수 있다는 것을 확인했다.
# Node JS 환경 구축
curl 을 node js 환경에서 express 에서 만든다면 브라우저에서 보여줄 수 있겠다..!!!
기본적으로 nodejs express 구축하고
express 에서 http 요청을 할 수 있게끔 하면 된다
vs code 키고
# 1. server.js 만들기
# 2. 터미널 켜고 npm init 해서 nodejs 환경 만들기
# 3. npm install express
# 4. npm install request
# express 의 역할?
- 얘가 하는 역할은 무엇인가?
요청이 들어오면 응답을 주는 녀석이다.
(http 로 요청, http 에 대한 응답)
express 로 요청이 들어오면
express 가 응답을 줄텐데,
응답 코드가 res.send('hello') 이런식으로 주었다.
그런데 응답을 주기 전에 또 요청이 하나 끼게 된다.
즉 요청이 들어오면 또 new 요청을 보냄 new 요청에 대한 응답을 받으면,
그때 처음 요청에 대한 응답을 준다. (서버가 두대가 있다고 생각)
브라우저 = 클라이언트
new 요청은 데몬에 대한 요청이다.
이런 형식은 db를 쓸 때 써봤다. db 도 어떤 하나의 서버라고 생각하면 이와 비슷하다고 볼 수 있다.
그래서 express 는 최종 응답만 주는 녀석
나중에는 db 도 추가해서 할거임
브라우저--------------> express -----------------------> daemon
requset 패키지 사용
[server.js]
요청 -> 응답
// url 127.0.0.1:3800 -> hello ingcoin! 출력을 해보자
const express = require('express')
const app = express()
app.get('/',(req,res)=>{
res.send('hello ingcoin!')
})
app.listen(3800,()=>{
console.log('server open');
})
실행 해보고 브라우저에서 주소 쳐보기 [사진2]
-> 여기까지는 요청- 응답 바로 준거임
# 요청 속의 요청
기본적인 http 요청을 해보자
naver 에 대한 body 영역을 가져오는것을 해보자
const request = require('request')
// 기본적으로 함수이다.
//node js 환경에서 요청을 보내는 녀석
// 요청A - 요청B - 응답B - 응답A
app.get('/naver',(req,res)=>{
// 요청 B - request 라는 패키지를 사용할거임
request('https://naver.com',(err,response,body)=>{
console.log(body);
})
res.send('naver')
})
requeset 안에는,
두가지 인자값 존재
1. url 값 (string) or object => 어디로 보낼지
2. callback 에 대한 값 - 요청에 대한 결과물이 떨어지고 나면 콜백이 실행된다.
콜백함수에는 3가지 인자값 err,response,body 가 존재함
response
: body에 있는 영역..body
: body 에 있는 내용을 그대로 string 값으로 가져오는 것.
서버 껐다가 켠 다음
http://127.0.0.1:3800/naver
로 요청을 보내면 vs code 터미널에 naver body 에 대한 내용이 쫘르륵 뜨게 되면 성공이다.
console.log(response);
하면 뭔가 내용이 뜸..
에러
console.log(err);
성공 : null
실패 :
일부러 에러를 만들어보았다.
err 가 찍혀도
res.send('naver')
가 브라우져가 찍힌다.
왜 그럴까?
싱글 스레드이기 때문에 request (비동기 처리 되어서)가 다른 곳(테스트큐)으로 빠지고
결과 여부와 상관없이
res.send('naver') 가 실행된다.
# 코드를 어떻게 수정해야 할까?
요청A 는 응답A 를 주는데
요청B 가 응답B 까지 다 떨어지고 난 다음에 주려고 한다면
이 코드를 어떻게 수정하면 될까??
res.send('naver') 를 콜백함수 안에서 실행하면 된다!!
그 처리가 안에서 되기 때문에
request('https://naver.cm',(err,response,body)=>{
console.log(err)
res.send('naver')
})
이렇게 바꾸면
console.log(err) 얘가 실행이 되는걸 기다리고
그 다음에 res.send('naver') 얘가 뜬다.
이제는 순서가 맞게 된거임
여기서 응용을 하자면
err 체크 하는 부분을 만들면 된다.
let msg = "naver"
if(err != null){
msg="error"
}
res.send('error')
이런식으로...
혹은
if(err == null){
res.send('naver')
}else{
res.send('error')
}
이렇게
두번째 인자값 처리
app.get('/naver2', (req, res) => {
// header 내용 넣고 method 값도 넣어보자
// 1. url 또는 object 2.콜백
request({url:"http://naver.com"},(err, response, data)=>{
console.log(data); //body 영역을 가져옴
res.send('naver2')
})
})
객체 안에 url 속성값을 넣어서 써도 된다는 것.
왜 굳이 객체로 받았지??
url 말고 또 넣을 값들이 존재하기 때문에.
app.get('/naver2', (req, res) => {
request(
{
url: "http://naver.com",
method: "POST",
headers: { "Content-type": "application/json" },
body: "{msg:'hello world!'}"
},
(err,response, data) => {
console.log(data)
console.log(response.statusCode) // 상태코드를 볼 수 있다
res.send('naver2')
})
})
그냥 모양이 그렇다는 거임
결과물이 나오지는 않을거임 post 로 받는 naver 는 없기 때문
console.log(response.statusCode)
상태 코드를 봤을 때 성공(200)
인데 301 이 떴다 - 실패라는 뜻
즉 성공이라는 조건이라면 상태코드가 200이고 err==null 값이어야 한다.
그래서 둘 중에 하나라도 안되면 실패라고 간주해야 한다.
if (err == null && response.statusCode==200) {
res.send('naver2')
} else {
res.send('error')
}
이런식으로 해주면 된다.
전체코드)
app.get('/naver2', (req, res) => {
request(
{
url: "http://naver.com",
method: "POST",
headers: { "Content-type": "application/json" },
body: "{msg:'hello world!'}"
},
(err, response, data) => {
console.log(data)
console.log(response.statusCode);
if (err == null && response.statusCode==200) {
res.send('naver2')
} else {
res.send('error')
}
})
})
curl 로 데몬에 요청 보내기
이제 본격적으로
cli 로 데몬에 요청을 보냈던 것을
express 환경에서 요청해보는 것을 해보자
curl
-X POST
-H "Content-type:application/json"
-d '{"method":"getnewaddress","params":["ingoo5"]}'
ingoo:1234@127.0.0.1:3000
const headers = {"Content-type": "application/json"}
const USER = process.env.RPC_USER || 'ingoo'
const PASS = process.env.RPC_PASSWORD || '1234'
const RPCPORT = process.env.RPC_PORT || 3000
app.get('/newaddress/:account', (req, res) => {
const {account} = req.params
const body = `{"method":"getnewaddress","params":["${account}"]}`
const options = {
url: `http://${USER}:${PASS}@127.0.0.1:${RPCPORT}`,
method: "POST",
headers,
body
}
const callback = (err, response, data) => {
if (err == null && response.statusCode == 200) {
const body = JSON.parse(data) // 결과물이 json 형태로 오지만 string 이므로 이렇게 parse 해주고
res.send(body)
} else {
res.send('error')
}
}
request(options, callback)
})
요청할때마다 주소가 계속 생기고
wsl 에서 확인 가능
.\juncoin-cli.exe -conf="C:\Users\USER\juncoin\bin\juncoin1.conf" getaddressesbyaccount ingoo6
[
"jFjPqNC32T8a2TDCmPNQJtXbDYoCx9qJFR",
"jTVJ13fjd1PRJdta9AqNBjiGPFYAU1B6J4",
"jWYVSmqQcbVLh5KVFDjB1rfNcFgXZhoofw",
"jZvDCjuvan3YL3CVdpEUDnAA2dYj4fk156",
"jc6SUpx14QucBS3vCzKbrGaT1F9L3LSftc"
]
번외) 크롤링
저 request 랑 항상 같이 쓰는 애가 있다.
바로 크롤링!!!!
블록체인이랑 별개의 내용이긴 함.
알아두면 유용함!
사이트에 있는 body 영역에서 내가 필요한 부분만 뽑아오는게 크롤링이다.
naver html 이 존재할텐데
가변적으로 내용이 변하는 곳이 있다면,
그 부분을 자동적으로 하는걸 만들었으면 좋겠다 싶어서
크롤링을 사용하면 된다.
div 안에 텍스트내용만 갖고 오고 싶다면..??
innerHTML 내용들만?
우리가 body 전체를 가져오는 건 했다.
특정 부분만 가져오는게 있다.
cheerio 패키지 사용
const cheerio = require('cheerio')
// npm install cheerio
// 이 텍스트 형태로 읽어서 html element 형태로 만들어줘서 data 저장하는 녀석이라고 보면 된다.
app.get('/crawling',(req,res)=>{
request('http://naver.com',(err,response,data)=>{
let $ = cheerio.load(data) // 얘를 선택자로 쓸거임
// 뽑아낼 영역. css 에서 선택하듯이 뽑아서 결과물이 여러개니까 each 로 반복문 돌림
$('.partner_box_wrap > .partner_box:nth-child(3) > a').each((index,item)=>{
// console.log(typeof(item)) // 이렇게 찍어서 어떤 형태인지 알수 있음 object
// console.log(item.children[0].data) // 하나씩 찍어보면서 안으로 들어가면 된다.
let {data} = item.children[0]
console.log(data);
})
})
})
copy select 사용하면 선택자 쉽게 사용가능
'웹 개발 > 블록체인' 카테고리의 다른 글
[블록체인] 프로젝트를 위해 기본 틀 잡기 part 1 (0) | 2021.09.28 |
---|---|
[블록체인] 데몬에 http로 요청하기, 크롤링 [실습] (0) | 2021.09.27 |
[블록체인] 트랜젝션 transaction [실습] (0) | 2021.09.24 |
[블록체인] 데몬 서버와 클라이언트 연결 (0) | 2021.09.17 |
[블록체인] 라이트 코인 빌드 (0) | 2021.09.15 |