관리자 글쓰기
[Node.js] express 라이브러리
2021. 10. 14. 23:40 - 프론트맨

express.js는 Node.js를 위한 웹 프레임워크이다.

오늘은 express로 서버를 돌릴 때 필요한

request와 response 개념에 대해 정리해보았다.

 

우선 express 사용 방법이다.

babel을 사용하면 아래와 같이 최신 자바스크립트 문법을 사용할 수 있다.

 

import express from "express";

const app = express()

 

이렇게 하면 "express" 패키지를 express라는 이름으로 import 하겠다는 뜻이 된다.

npm이 알아서 찾아주기 때문에 express의 상세주소는 적지 않아도 된다.

 

그리고 app 변수에 express 패키지를 실행시킨다.

 

 

클라이언트(사용자)가 브라우저에 요청(request)을 보내면

브라우저는 그 요청을 서버에 전달한다. 

 

서버는 그 요청에 응답(response)을 해야 하기 때문에

항상 listen을 하고 있어야 한다.

 

javascript의 addEventListener와 비슷하다고 보면 된다.

 

app.listen(4000, () =>
  console.log("app is listening port 4000")
);

 

app.listen 메서드의 첫번째 매개변수에는 Port 번호가 들어가고

두 번째 매개변수에는 실행할 함수가 들어간다.

 

여기서 포트(Port)에 대한 이해가 필요하다.

Port는 항구라는 뜻으로 네트워크 상의 문을 뜻한다.

 

Port는 숫자로 구성되어 있는데,

예를 들어 0 ~ 1023의 숫자는

국제 도메인 관리기구의 통제를 받고 있기 때문에

일반 사용자가 사용할 수 없다.

 

 

숫자가 높을수록 사용자가 적어서

공부가 목적이면 높은 숫자를 사용하는 것이 좋다.

 

 

app.listen 메서드가 실행되면 서버는 browser의 요청을

항상 Listening 하고 있게 된다.

 

 

Port 번호를 4000으로 설정했으므로

사용자는 http://localhost:4000 의 주소로 서버에 접근할 수 있다.

 

 

여기서 짚고 넘어가야 할 게 있다.

 

사용자가 브라우저를 통해 request를 보내고 서버가 응답을 하게 되면

사용자는 제자리에서 서버의 정보를 다운받는다.

사용자가 서버로 들어가는 게 아니다.

 

 

이제 사용자가 http://localhost:4000 서버에 요청을 보내면 

응답을 할 코드를 작성해야 한다.

 

서버 주소에 '/'를 붙이면 그 서버의 home을 뜻한다.

즉, 가장 먼저 보여줄 메인 페이지가 되는 것이다.

 

코드는 다음과 같다.

 

const Home = (req, res) => {
  console.log(`${req.method}${req.url}`); // get/
  return res.send("<h1>hahaha<h1>");
};

app.get("/", Home);

 

app.get 메서드로 요청받은 페이지를 보여줄 수 있다.

첫 번째 매개변수는 요청받은 주소를 의미한다.

 

만약 '/' 대신 'login' 이라고 적으면

사용자가 http://localhost:4000/login 의 주소로 요청을 보낼 때

응답할 수 있게 된다.

 

두 번째 매개변수로는 콜백 함수가 들어간다.

이 함수에는 express 라이브러리가 제공하는 매개변수를 사용할 수 있다.

바로 request와 response 그리고 next이다.

(next에 대한 정리는 다음에 하도록 하겠다.)

 

request에는 요청받은 정보가 들어있고

response에는 응답할 정보가 들어있다.

 

return을 하지 않으면 브라우저는 응답을 할 때까지 계속 로딩을 하게 되므로

반드시 return을 해야 한다.

(아니면 next() 함수로 다음 함수로 넘길 수도 있다.)

 

[Node.js] package.json
2021. 10. 14. 18:33 - 프론트맨

Node.js는 Ryan Dahl 가 최초 개발한 2009년부터

꾸준한 상승세를 이어오고 있는 프로그래밍 언어다.

 

기존의 Javascript는 브라우저 내에서만 작동했다면

Node.js는 Javascript의 언어로 브라우저 밖에서 사용할 수 있다.

 

Node.js를 사용하면 서버 확장이 용이하고

I/O (Input/Output) 처리가 빠르고

무엇보다 프론트 필수 언어인 Javascript로 

백엔드까지 작성할 수 있다는 어마어마한 장점이 있다.

 

Node.js를 설치하면 npm도 같이 설치된다.

npm은 Node.js의 패키지를 관리해주는 프로그램이다.

npm과의 상호작용으로 Node.js는 더욱 강력해진다.

 

 

Node.js를 사용하려면 package.json 파일을 이해해야 한다.

사용자가 Node.js 파일을 github와 연동하거나

Node.js 관련 모듈을 설치할 때마다 package.json 파일에 내용이 추가된다.

 

 

기본적으로 json 파일은 텍스트 파일일 뿐이라 이상하게 수정한다고 해도 당장 Node.js 파일에 문제가 생기진 않는다. 하지만 사용자가 package.json 파일을 활용해서 터미널에 명령을 내릴 수가 있다.

 

 

package.json에 대해 정리해보았다.

 

 

 

scripts

"scripts": {
    "start": "index.js"
  }

 

scripts는 Node.js 파일의 실행 방법을 정의할 수 있다.

(실행할 이름) : (파일명(경로)) 형식으로 작성하면 된다.

원래 index.js 파일을 실행시키려면 터미널에 아래와 같이 입력해야 했다. 

(참고로 나는 Linux 가상 환경을 사용한다.)

 

npm run index.js

 

하지만 scripts에서 index.js 파일을 "start"라는 이름으로 정의했으므로

이렇게 입력할 수 있다. 

 

npm run start

 

여기서 끝이 아니다. 

 

보통 Node.js를 babel(최신 자바스크립트를 사용할 수 있게 해주는 컴파일러)

과 같이 사용하는데 scripts에서 사용방법도 정의할 수 있다.

 

"scripts": {
    "start": "babel-node index.js"
  }

 

babel을 설치한 뒤 파일명 앞에 babel-node 라고 입력하면 

아까처럼 실행시켰을 때 babel을 간편하게 사용할 수 있다.

 

nodemon이라는 도구도 사용할 수 있다.

원래는 실행시킬 때마다 npm run start 라고 입력해야 했지만

nodemon을 사용하면 자바스크립트처럼 

파일을 저장하기만 해도 알아서 실행시켜준다.

 

nodemon을 설치한 뒤 아래와 같이 입력하면 된다.

 

"scripts": {
    "start": "nodemon --exec babel-node index.js"
  }

 

처음 한 번만 실행시켜주면 그 뒤는 저장만 해도 실행시킬 수가 있다.

 

 

 

dependencies / devDependencies

 

express 같은 라이브러리를 설치하면 dependencies에 입력되고

babel, nodemon 같은 라이브러리를 설치하면 devDependencies

입력되는 것을 볼 수 있다.

 

 

dependencies는 런타임에도 계속 사용하는 패키지를 적어두는 곳이다.

express 같은 라이브러리가 이에 해당된다.

 

devDependencies는 dev가 의미하듯 개발자에게 필요한 패키지를 적어두는 곳이다.

babel 같은 컴파일러가 이에 해당된다.

 

dependencies, devDependencies 가 유용한 이유는 

만약 Node.js 폴더를 누군가에게 보내야 할 때 

설치한 라이브러리까지 다 보내버리면 용량 때문에 오래 걸릴 것이다.

 

하지만 package.json 파일에 라이브러리 정보가 기록되어 있으면

라이브러리를 제외하고 보낼 수가 있다.

 

폴더를 받은 사람은 터미널에 npm install 이라고만 입력하면

npm이 json 파일을 읽어서 필요한 라이브러리를 알아서 다운받아준다.

문제

 

윈도우 위에 리눅스 가상 환경을 만들고 Node.js를 설치했다.

 

Visual Studio Code에서 index.js, package.json 같은 기본 파일을 만들고

npm run 명령어로 index.js 파일을 실행시켰다.

 

그런데 console.log 같은 간단한 프로그램도 실행시키는데 20초가 넘게 걸렸다.

 

 

 

해결

 

 

처음엔 그저 노트북 성능 문제라고 생각했다.

그런데 이건 너무 비정상적으로 느린 것 같아서 구글링을 해보다 해결책을 찾았다.

 

나는 프로젝트 폴더를 Window 아래에 있는 Documents 폴더에 저장하고 있었다.

그래서 Linux에서 Window 파일을 실행시키려니 시간이 많이 걸렸던 것.

 

(자신이 작업하고 있는 폴더의 위치는 Visual Studio Code에서 확인할 수 있다.

창 목록에서 오른쪽 마우스 버튼 > Copy Path를 클릭하면 파일의 주소가 복사된다.)

 

 

해결 방법은 간단했다.

project 폴더를 Window에서 Linux 홈으로 옮겨주면 되었다.

 

우선 node_modules 파일과 package-lock.json 파일은 용량이 많으므로 삭제한다.

어차피 package.json 파일에 설치 목록이 남아있어서 나중에 쉽게 설치할 수 있다.

 

이제 Linux 터미널에서 폴더가 있는 곳으로 이동한다.

(나 같은 경우는 Documents 폴더로 이동했다.)

 

그리고 아래의 명령어를 입력한다.

 

mv (파일명) ~/

 

나 같은 경우는 mv project ~/ 를 입력했다.

이렇게 하면 폴더를 Linux 홈으로 이동시킨다.

 

 

 

이제 Node.js를 실행시켜보니 빨라진 걸 확인할 수 있었다.

'Programming > Linux' 카테고리의 다른 글

[Linux] 기본 명령어 정리  (0) 2021.10.13
[Linux] 기본 명령어 정리
2021. 10. 13. 23:15 - 프론트맨

Window 컴퓨터에 WSL을 설치하고 Linux 가상환경을 만들었다.

 

Window는 모두 알다시피 창과 마우스 Event (더블클릭, 드로그 앤 드롭 등) 를 이용해서

일반 사용자에게 편하게 만들어져 있다.

 

하지만 Linux에서는 모든 걸 콘솔에서 제어해야 하기 때문에 

개발자에게 초점이 맞춰져있다고 보면 된다.

 

 

 

오늘은 Linux의 명령어에 대해서 간단하게 정리해보았다.

 

 

Window에서 Linux 가상환경을 사용할 때는 꼭 주의할 점이 있다.

 

Linux에서 Window에 있는 파일을 건드리는 것은 상관없다.

하지만 반대로 Window에서 Linux의 파일을 건드리면 절대 안된다.

 

이것만 조심하면 Linux 환경에서 더 재밌게 코딩할 수 있을 것이다.

 

 

 

'Programming > Linux' 카테고리의 다른 글

Linux 에서 Node.js 느리게 돌아갈 때 해결 방법  (0) 2021.10.14
[Python] Selenium 정리
2021. 10. 13. 22:09 - 프론트맨

파이썬으로 웹 크롤링, 웹 스크래핑을 할 때는

먼저 타겟 url로 접속을 해야 합니다.

이때는 보통 2가지 방법이 주로 쓰이는데

 

바로 RequestsSelenium입니다.

 

Requests는 백그라운드에서 실행되어서 빠르다는 장점이 있지만

정적인 방식이기 때문에 정보를 가져오는 것 밖에 할 수 없다는 단점이 있습니다.

 

Selenium은 직접 창을 열면서 실행되기 때문에 Request에 비해서 느리긴 하지만

동적인 방식이기 때문에 스크롤을 내리거나 검색어를 입력하는 등의 작업이 가능합니다.

 

↓ Requests 정리

 

[Python] 파이썬 웹 스크래핑 완벽 정리(주식 시가 가져오기)

오늘은 파이썬을 이용한 웹 스크래핑에 대해 알아보겠습니다 웹 페이지를 가져와서 데이터를 추출해 내는 행위를 웹 크롤링(crawling) 혹은 웹 스크래핑(scraping)이라고 합니다. 웹 스크래핑을 하

squidcoding.tistory.com

 

오늘은 Selenium에 대해 살펴보겠습니다.

 

우선 터미널에 아래의 코드를 입력해서 Selenium을 설치합니다.

 

pip install selenium

 

그리고 Selenium으로 크롬 브라우저를 실행하기 위해서 Chrome Driver를 따로 다운 받아야 합니다.

 

주소창에 chrome://version 이라고 치면 크롬 브라우저의 버전을 확일할 수 있습니다.

 

 

그리고 자신의 브라우저 버전의 ChromeDriver를 다운로드하면 됩니다.

https://chromedriver.chromium.org/downloads

 

ChromeDriver - WebDriver for Chrome - Downloads

Current Releases If you are using Chrome version 95, please download ChromeDriver 95.0.4638.17 If you are using Chrome version 94, please download ChromeDriver 94.0.4606.61 If you are using Chrome version 93, please download ChromeDriver 93.0.4577.63 For o

chromedriver.chromium.org

 

이제 코드를 칩니다.

from selenium import webdriver

browser = webdriver.Chrome("C:/Users/chromedriver.exe")
browser.get("http://naver.com")

webdriver.Chrome( )에는 chromedriver.exe 파일의 경로를 적으면 됩니다. (같은 위치에 있으면 비워놔도 됨)

그리고 browser.get 메서드로 이동할 페이지의 주소를 입력합니다.

 

 

여기까지는 Requests와 비슷합니다.

이제부터 Selenium의 동적인 기능에 대해 알아봅시다.

 

네이버에서 '오징어 게임'을 검색하는 예제입니다.

개발자 모드에서 열어보면 검색창은 input 태그에 'query'라는 id를 갖고 있습니다.

 

from selenium import webdriver

browser = webdriver.Chrome("C:\\Users\\LG\\Desktop\\Python Workspace\\chromedriver.exe") 

browser.get("http://naver.com")

elem = browser.find_element_by_id('query')
elem.send_keys('오징어게임')

browser.find_element_by_id 메서드를 사용해서 elem 변수에 저장하고

elem.send_keys로 검색어를 입력할 수 있습니다.

 

element를 가져오는 방법은 id 외에도

class, xpath, tag_name, css_selector 등 다양합니다.

 

만약에 elem 변수를 한번 사용하고 말 것이면 

굳이 변수에 저장하지 않아도 됩니다.

 

 

이제 검색 버튼을 클릭합니다.

아래를 보면 button 태그에 search_btn의 id를 갖고 있는 것을 볼 수 있습니다.

 

 

이 버튼을 클릭하는 방법입니다.

 

from selenium import webdriver

browser = webdriver.Chrome("C:\\Users\\LG\\Desktop\\Python Workspace\\chromedriver.exe") 

browser.get("http://naver.com")

elem = browser.find_element_by_id('query')
elem.send_keys('오징어게임')

browser.find_element_by_id('search_btn').click() # 검색 버튼 클릭

 

이번엔 변수에 저장하지 않는 방법을 사용했습니다.

click() 메서드로 쉽게 버튼을 클릭할 수 있습니다.

 

 

여기까지 Selenium으로 네이버에서 키워드를 검색해보는 예제였습니다.

Selenium으로 웹 페이지를 이동해서 웹 스크래핑을 하려면

그 페이지의 소스를 Beautifulsoup에 넘겨주어야 합니다.

 

from selenium import webdriver
from bs4 import BeautifulSoup

browser = webdriver.Chrome("C:\\Users\\LG\\Desktop\\Python Workspace\\chromedriver.exe") 

browser.get("http://naver.com")

elem = browser.find_element_by_id('query')
elem.send_keys('오징어게임')

browser.find_element_by_id('search_btn').click()

res = browser.page_source # 현재 페이지의 소스를 변수에 저장
soup = BeautifulSoup(res, "lxml") # BeautifulSoup 에 소스를 전달

browser.page_source 메서드로 현재 페이지의 소스를 가져올 수 있습니다.

 

마지막으로 작업이 끝난 후 창을 닫는 메서드입니다.

 

browser.close()

browser.close() → 현재 탭만 종료시킵니다.

 

browser.quit()

browser.quit() → 전체 브라우저를 종료시킵니다.

 

 

 

 

오늘은 Selenium에 대해 간단히 정리해 보았습니다.

끝까지 읽어주셔서 감사합니다.

Python에는 한 줄 for문이라는 독특한 문법이 있습니다.

처음에는 되게 복잡해 보이고 이게 뭐지 싶을 텐데 

이해하면 정말 편하고 유용한 기술입니다.

 

 

 

한 줄 for문을 쓰는 이유

 

한 줄 for문은 간편하게 리스트를 만드는 용도로 쓰입니다.

먼저 기본형을 살펴보면

 

# 한 줄 for문을 사용하지 않을 때
my_list = []
for x in range(5):
	my_list.append(x)

print(my_list) # [0,1,2,3,4]
    
# 한 줄 for문을 사용했을 때
my_list = [x for x in range(5)]

print(my_list) # [0,1,2,3,4]

 

리스트에 0부터 4까지 집어넣는 예제입니다.

위의 코드와 아래 코드는 같은 의미입니다.

원래는 3줄을 써야 하는데 한 줄 for문을 사용하면 말 그대로 한 줄이면 충분합니다.

 

 

 

한 줄 for문 응용하기 (수식 추가)

 

수식을 추가할 수도 있습니다.

 

my_list = [x+x for x in range(5)]

print(my_list) # [0,2,4,6,8]


my_list = [x*x for x in range(5)]

print(my_list) # [0,1,4,9,16]


my_list = [x**x for x in range(5)]

print(my_list) # [1,1,4,27,256]

 

 

한 줄 for문 응용하기 ( if문 )

 

조건을 추가하는 것도 가능합니다.

 

my_list = [x for x in range(1, 11) if x % 2 == 0] # 짝수만 추출

print(my_list) # [2,4,6,8,10]



my_list = []
for x in range(1, 11):
    if x % 2 == 0:
        my_list.append(x)

print(my_list) # [2,4,6,8,10]

 

반복문 끝에 if 문을 추가하면 조건을 달 수 있습니다.

위의 코드를 풀어쓰면 아래 코드가 됩니다.

 

 

한 줄 for문 응용하기 ( 이중 for문 )

 

이중 for문도 가능합니다.

nums = [[4, 26, 88],
       [77, 78, 26, 2, 89],
       [2, 42, 70, 41],
       [31, 92, 41],
       [24, 85, 22, 5, 76]]

nums 에서 값이 50 이상인 숫자만 my_list에 담는 예제입니다.

 

한 줄 for문 없이 짠 코드

 

my_list = []

for x in nums:
    for y in x:
        if y >= 50:
            my_list.append(y)

print(my_list) # [88, 77, 78, 89, 70, 92, 85, 76]

 

한 줄 for문으로 짠 코드

 

my_list = [y for x in nums for y in x if y >= 50]

print(my_list) # [88, 77, 78, 89, 70, 92, 85, 76]

 

다차원 리스트를 한 줄 for문으로 접근할 때 한 가지 주의할 점은

마지막에 결국 my_list에 들어갈 값을 맨 앞에 적어야 합니다.

 

이것만 조심하면 어렵지 않게 한 줄 for문을 다룰 수 있을 것이라고 생각합니다.

 

 

 

 

지금까지 한 줄 for문에 대해 다뤄보았습니다.

파이썬 초급자에게는 다소 생소할 수 있을 문법이라고 생각해서 정리해 보았습니다.

끝까지 읽어주셔서 감사드립니다.

 

파이썬의 requests 모듈로 웹 스크래핑을 하다가

requests.exceptions.ConnectionError 오류가 발생했다.

 

아무래도 특정 사이트에서 requests로 들어오는 걸 막은 것 같다.

 

 

해결 방법

 

해결 방법은 간단하다.

우리가 사이트에 들어가면 user-agent 정보를 전달하는데

requests의 user-agent 정보를 내 것으로 바꿔주면 된다.

 

먼저 아래의 사이트에서 자신의 agent 정보를 복사한다.

https://www.whatismybrowser.com/detect/what-is-my-user-agent 

 

What is my user agent?

Every request your web browser makes includes your User Agent; find out what your browser is sending and what this identifies your system as.

www.whatismybrowser.com

 

import requests

headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64)..."} # 개인마다 다르다
url = "https://squidcoding.tistory.com"

result = requests.get(url, headers = headers)

 

headers 변수 안에 딕셔너리를 만들고 "User-Agent"의 값으로 아까 복사했던 정보를 붙여넣기 한다.

그다음 requests.get의 url 정보 옆에 headers의 정보를 추가로 입력하면 끝이다.

일론 머스크, 그는 사기꾼인가?
2021. 10. 9. 23:59 - 프론트맨

오늘은 제가 좋아하는

세계 최고의 부자이자 코인 사기꾼인 우리 형

일론 머스크에 대해 간단히 소개하고자 합니다.

풀네임

 

일론 머스크의 풀네임은 일론 리브 머스크(Elon Reeve Musk)입니다.

 

 

가정환경

 

일론 머스크는 1971년 남아공에서 태어났습니다. 그의 아버지는 엔지니어, 어머니는 모델 겸 영양사였으며, 집이 굉장히 잘살았다고 합니다.

 

그러나 부모님이 10대에 이혼했고 머스크는 아버지를 선택했는데 훗날 그는 이때의 선택을 가장 후회했습니다.

 

그의 아버지는 폭력적인 성격에 자신의 의붓딸과 아이를 가지는 등 

머스크의 동생 킴벌의 말에 따르면 '인간말종'이었다고 합니다.

 

 

 

학창 시절

 

머스크는 10살 때부터 컴퓨터에 흥미를 가졌습니다. 부자 집안답게 그 시절 최고급 사양의 컴퓨터를 가질 수 있었고 12살에는 Blastar라는 게임을 동생과 만들어 게임 잡지에 팔기도 했습니다. 또한 로켓에도 큰 취미를 가졌다고 합니다.

 

 

18세에 머스크는 캐나다로 유학을 떠났습니다.

이때부터 그의 고생길은 시작됩니다.

 

몬트리올에 있을 줄 알았던 그의 증조부는 얼마 전 미국으로 이민을 가버렸습니다.

아버지와는 사이가 멀어져 있었고 어머니는 돈이 없었습니다.

그래서 그는 1년 동안 공장에서 갖가지 궂은일을 하며 노숙자처럼 생활하게 됩니다.

 

 

 

대학생활

 

2년 동안 퀸즈 대학교에서 물리학을 전공하다 펠실베니아 대학교로 편입한 뒤

경제학 학점까지 이수해서 물리학과 경제학 복수전공으로 학사과정을 마치게 되었습니다.

훗날 그는 물리학적 사고방식이 정말 도움이 많이 되었다고 밝혔습니다.

 

 

 

PayPal

 

어린 시절 공상과학소설을 좋아했던 그는 어릴 때부터 인간을 화성에 보내는 게 꿈이었다고 합니다.

지금 그는 수많은 회사를 운영하고 있는데 

궁극적인 목표는 인류를 화성에 이주시켜 다행성 종족으로 만드는 것이고

그때까지 기후 변화의 재앙이 닥치지 않게 시간을 벌어야 해서

전기차, 솔라시티를 창업했다고 합니다.

 

 

대학을 갓 졸업한 그는 그의 꿈을 실현하려고 했으나 

무엇보다 돈이 없으면 불가능하다는 것을 깨달았습니다.

그리고 돈을 벌려면 소프트웨어가 적합했습니다.

 

 

이제 그는 창업의 길로 뛰어들게 됩니다.

ZIP2(신문에 도시 가이드 소프트웨어를 제공하거나 라이선스를 부여하는 업체)를

창업한 그는 컴팩에게 3억 700만 달러에 팔았고 7%의 지분을 가지고 있던 머스크는

2200만 달러를 손에 넣으며 28살에 백만장자가 되었습니다.

 

 

 

그다음 친한 동료들과 X.com(엑스 닷컴)을 설립하였고

나중에 PayPal로 이름을 바꾸게 됩니다.

 

PayPal은 이메일 주소를 이용해서 송금을 하게 해주는 업체였는데

구성원들끼리 갈등이 많이 일어났습니다.

 

그러던 중 머스크가 휴가를 떠난 사이 동료들이 머스크의 해임안을 올려 해임당하고 말았습니다.

당시 페이팔에는 라이벌 경쟁사가 있었고 내부 균열로 시끄러운 상태였지만

고객의 충성도는 페이팔 쪽이 더 높았습니다.

결국 이베이가 페이팔을 15억 달러에 인수하게 되고 지분 11%를 가지고 있던 머스크는 

억만장자가 되어버렸습니다.

 

 

 

그 후

 

이제 일론 머스크는 그의 꿈을 실현할 수 있는 자본을 갖췄습니다.

이때부터 테슬라(전기차 제조 업체), Space-X(로켓 제조 업체), 솔라시티(태양에너지 서비스 업체)를

잇달아 창업하며 다시 도전을 외쳤습니다.

 

그 후 테슬라, Space-X는 여러 번 파산위기를 맞았지만 무사히 넘겼고

2021년 지금은 재활용 로켓 발사를 잇달아 성공하고 OpenAl, 뉴럴 링크를 추가로 설립하며

세계 최고의 부자 순위에 이름을 올렸습니다.

 

 

 

 

가끔씩 코인으로 사기 치기도 하고

SNL에 나와서 큰 웃음을 주기도 하지만 

이 사실만큼은 부인할 수 없을 겁니다.

 

 

 

지금 우리가 일론 머스크의 시대에 살고 있다는 걸 말이죠.

 

 

오늘은 파이썬을 이용한 웹 스크래핑에 대해 알아보겠습니다

 

웹 페이지를 가져와서 데이터를 추출해 내는 행위를

웹 크롤링(crawling) 혹은 웹 스크래핑(scraping)이라고 합니다.

 

웹 스크래핑을 하려면 우선 기본적인 html 이해도가 필요합니다.

 

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <header></header>
  <div></div>
</body>
</html>

html은 태그와 속성으로 구성되어 있습니다.

 

웹 스크래핑을 하는 방법은 우선 html에서 추출하고 싶은 데이터가 있는 태그를 찾고

for문, if문 같은 파이썬의 다양한 문법을 이용해서 데이터를 필터링하는 형식입니다.

 

 

 

requests

 

파이썬으로 html을 읽기 위해서는

링크를 입력했을 때 그 링크로 접속해줄 도구가 필요합니다.

 

pip install requests

터미널에 위의 코드를 입력해서 requests 라이브러리를 설치해줍니다.

 

import requests

url = "https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=%EC%A3%BC%EC%8B%9D%EC%8B%9C%EA%B0%80%EC%B4%9D%EC%95%A1"
result = requests.get(url)

담고 싶은 데이터가 있는 주소를 url 변수에 저장하고 

requests.get(url) 을 입력해서 페이지에 있는 모든 html 정보를 result 변수에 저장합니다.

 

위의 url은 네이버에 주식 시가총액을 검색했을 때 나오는 주소입니다.

위에서 선택된 부분만 추출해서 파일에 저장하는 실습을 해보겠습니다.

 

 

BeautifulSoup

 

이제 requests로 불러온 html 정보에서 우리가 원하는 정보를 찾아야 합니다.

그걸 가능하게 해주는 라이브러리가 BeautifulSoup 라이브러리입니다

 

pip install beautifulsoup4

터미널에 위의 코드를 입력해서 BeautifulSoup 라이브러리를 설치해줍니다.

 

import requests
from bs4 import BeautifulSoup

url = "https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=%EC%A3%BC%EC%8B%9D%EC%8B%9C%EA%B0%80%EC%B4%9D%EC%95%A1"
result = requests.get(url)
soup = BeautifulSoup(result.text, "lxml")

 

result.text 는 아까 가져온 html 정보에서 text만 추출합니다.

이제 그것을 BeautifulSoup이 사용할 수 있는 표현 방식으로 변환시켜 주어야 합니다.

BeautifulSoup에는 변환을 시켜주는 파서(parser) 기능이 있습니다.

 

parser는 4가지의 종류가 있고 각각 장단점이 있지만 

속도가 빠른 lxml 을 사용하는 것을 권장하고 있습니다.

 

 

위의 코드는 웹 스크래핑을 하기 위해 꼭 해야 하는 작업입니다.

 

이제 페이지에서 가져올 데이터가 속해있는 태그를 찾아야 합니다.

 

우선 F12 버튼을 눌러서 개발자 모드를 띄워줍니다.

화살표가 가리키는 버튼을 클릭하면 마우스로 원하는 태그를 찾을 수 있습니다.

 

 

이렇게 표로 정리되어 있는 형식은 보통 <table> 태그 안에 있습니다.

 

 

<table> 태그의 내용은 <tbody> 태그 속에 있습니다.

그리고 <tr> 태그는 table row 를 뜻하며 <tbody>의 각 행을 구성합니다.

 

이제 우리가 할 일은 다음과 같습니다.

 

1. <table> 태그의 class 속성을 이용해서 특정 <table>을 선택한다.

2. 선택한 <table>에 있는 <tbody>, 그 밑에 있는 <tr> 태그들을 리스트에 담는다.

3.  반복문을 돌려서 <tr> 태그의 원하는 정보를 추출한 다음 파일에 옮겨 닮는다.

 

 

 

먼저 BeautifulSoup의 find 메소드로 <table> 태그를 선택합니다.

 

import requests
from bs4 import BeautifulSoup

url = "https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=%EC%A3%BC%EC%8B%9D%EC%8B%9C%EA%B0%80%EC%B4%9D%EC%95%A1"
result = requests.get(url)
soup = BeautifulSoup(result.text, "lxml")

table = soup.find("table", {"class":"lsttype_tb"}) # class가 lsttype_tb 인 table중 첫번째

 

이제 <tr> 태그를 저장합니다.

find 메소드는 찾는 태그가 여러 개 존재해도 첫 번째 태그만 저장합니다.

하지만 find_all 메소드를 사용하면 모든 태그를 리스트에 담을 수 있습니다.

 

import requests
from bs4 import BeautifulSoup

url = "https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=%EC%A3%BC%EC%8B%9D%EC%8B%9C%EA%B0%80%EC%B4%9D%EC%95%A1"
result = requests.get(url)
soup = BeautifulSoup(result.text, "lxml")

table = soup.find("table", {"class":"lsttype_tb"})
tr_list = table.find("tbody").find_all("tr") # <table> > <tbody> > <tr>

 

이러면 tr_list 안에는 <tr> 태그들의 정보가 담겨있습니다.

 

이제 for문을 사용해서 데이터를 추출해야 합니다.

 

그림을 보면

 

종목 이름: <tr> 태그의 첫 번째 <a> 태그

가격: <tr> 태그의 첫 번째 <td> 태그인 것을 알 수 있습니다.

 

import requests
from bs4 import BeautifulSoup

url = "https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=%EC%A3%BC%EC%8B%9D%EC%8B%9C%EA%B0%80%EC%B4%9D%EC%95%A1"
result = requests.get(url)
soup = BeautifulSoup(result.text, "lxml")

table = soup.find("table", {"class":"lsttype_tb"})
tr_list = table.find("tbody").find_all("tr")

for tr in tr_list:
    name = tr.find("a").get_text() # a 태그의 text 부분을 추출
    price = tr.find_all("td")[0].get_text()
    
    with open("stock_quote.txt","a",encoding="utf8") as f: 
    	f.write(f"{name}: {price}\n")

 

for문을 돌려서 각 tr에 있는 이름과 가격을 추출해서 파일에 담았습니다.

 

 

결과를 보면 가격이 천차만별입니다.

마지막으로 여기서 가격이 500,000원 미만인 것들만 담아보겠습니다.

 

하지만 문제가 있습니다.

가격 정보를 보면 71,500 같이 쉼표가 포함되어있는 문자열입니다. 

 

우선 replace() 함수를 사용해서 쉼표를 ""(빈 문자열)로 바꾸고

int 형 변환을 해야 합니다.

import requests
from bs4 import BeautifulSoup

url = "https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=%EC%A3%BC%EC%8B%9D%EC%8B%9C%EA%B0%80%EC%B4%9D%EC%95%A1"
result = requests.get(url)
soup = BeautifulSoup(result.text, "lxml")

table = soup.find("table", {"class":"lsttype_tb"})
tr_list = table.find("tbody").find_all("tr")

for tr in tr_list:
    name = tr.find("a").get_text() # a 태그의 text 부분을 추출
    price = tr.find_all("td")[0].get_text()

    price = price.replace(",", "")
    if int(price) >= 500000: # 만약 가격이 50만원 이상이면 continue 
        continue
    
    with open("stock_quote.txt","a",encoding="utf8") as f: 
    	f.write(f"{name}: {price}\n")

 

 

 

이렇게 웹 스크래핑으로 주식 정보를 파일에 옮겨 닮아 보았습니다.

 

웹 스크래핑의 진정한 힘은 엄청난 양의 데이터를 받아와서

내가 원하는 대로 가공을 할 수 있다는 점입니다.

 

간단히 정리해 볼 생각이었는데 글이 너무 길어졌네요 ^^

 

끝까지 봐주셔서 감사합니다.

 

 

자바스크립트에서 객체나 배열을

 

복사하는 방법에 대해 알아보겠습니다.

 

 

복사에는 얕은 복사와

 

깊은 복사(Deep Copy)가 있습니다.

 

 

얕은 복사(Shallow Copy)란?

 

과일을 예로 들어보겠습니다.

See the Pen by jisupark123 (@jisupark123) on CodePen.

 

 

fruitsAfruitsB에 복사하고

 

fruitsB에만 "melon"을 집어넣었는데 

 

출력 결과 두 배열 모두 바뀐 것을 볼 수 있습니다.

 

우리는 단순히 값을 복사 했다고 생각하지만 컴퓨터의 내부를 들여다보면 다릅니다.

 

      100      100
fruitsA fruitsB
["apple", "banana"] ["apple", "banana"]

 

 

fruitsB = fruitsA 라고 입력하면 자바스크립트는 단순히 값을 복사하지 않고

 

fruitsA의 메모리 주소 ex)100 를 fruitsB와 공유하게 됩니다.

 

이렇게 하면 메모리를 절약할 수 있기 때문이죠.

 

 

그래서 fruitsB의 값을 바꾸면 같은 메모리 주소를 공유하는 fruitsA의 값도 바뀌게 됩니다.

 

이렇게 이름만 같은 변수로 복사하는 것을 얕은 복사(참조 복사)라고 부릅니다.

 

 

깊은 복사(Deep Copy)란?

 

깊은 복사는 얕은 복사의 반대말입니다.

 

깊은 복사를 하게 되면 복사한 두 배열이 완전히 독립적으로 작동하게 됩니다.

 

 

See the Pen by jisupark123 (@jisupark123) on CodePen.

 

 

 

처음 코드와의 차이점은

const fruitsB = fruitsA

에서

const fruitsB = [...fruitsA]​

로 바뀐 것입니다.

 

전개 연산자(...)는 말 그대로 배열, 객체의 요소를

코드 내에서 전개시키는 역할을 합니다.

 

위의 코드에서 ...fruitsA

fruitsA 에서 [ ] 를 뺀 "apple", "banana" 와 같습니다.

 

 

아래 코드는 전개 연산자를 응용하는 방법입니다.

 

 

See the Pen by jisupark123 (@jisupark123) on CodePen.

 

 

전개 연산자가 쓰여진 자리에 배열이 전개되는 것뿐이므로

 

이런 식으로 응용할 수도 있습니다.