우리는 파이썬을 배울 때, 기본적으로 파이썬을 설치하여 하나의 파이썬 버전만 설치하여 사용하였다. 특정 프로젝트 진행시에 파이썬 3.5버전에 A 1.3버전 라이브러리 B 1.5 라이브러리를 사용해야할 수 있다. 이런 경우 파이썬의 버전이나 정보들을 여러개로 분리하여, 각각을 독립적으로 가상환경으로 만들어 선택하여 사용 가능하다.
step 1.
visual studio code 접속한다.
step 2.
python3-mvenvtutorial-env를 입력한다.
step 3.
* 윈도우의 경우
tutorial-env\Scripts\activate.bat 입력
* Unix 또는 Mac OS의 경우
sourcetutorial-env/bin/activate 입력
이렇게 되면 turoial-env라는 독립적인 가상환경이 만들어 진 것이다. 다른 프로젝트와 독립적인 공간에서 패키지를 설치하고 사용할 수 있다.
- 웹페이지의 소스코드를 가져올 수 있는 기능. 소스코드 분석 및 웹페이지를 활용한 자동화를 이용할 시에 유용하다.
Request
- Request는 웹 사이트에 소스코드를 요청하는 라이브러리다.
Mac Terminal
1. pip3 install requests
import requests
res=requests.get("http://google.com")
res.raise_for_status()
print(len(res.text))
print(res.text)
with open("mygoogle.html", "w", encoding="utf-8") as f:
f.write(res.text)
request를 통해서 구글.com을 스크래핑한다.
res.text를 mygoogle.html이라는 파일로 만들고 "w" 쓰기모드로 저장한다.
User-Agent
import requests
url = "http://codingboycc.tistory.com"
headers = {"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36"}
res = requests.get(url, headers=headers)
res.raise_for_status()
with open("codingboycc.html", "w", encoding="utf8") as f:
f.write(res.text)
티스토리에서는 '우리가 request를 통해서 접속하는 사람이 사람이 아니고 기계일 것이다' 가정하여 정확한 웹스크롤링이 가능하지 않다. 이럴 경우에 이용할 수 있는 것이 User-Agent다.
1. 구글에 what is my user agent를 검색한다.
headers = {} 안에 user agent 값을 입력한다.
이렇게 코드를 실행하고 나면 정확한 웹스크롤링이 가능해진다.
Beautiful Soup
- Beautiful Soup은 웹 페이지의 소스코드를 가져 온 뒤에 특정 소스만을 색인하여 가져올 수 있는 라이브러리이다.
1. pip3 install beautifulsoup4
2. pip3 install lxml
* XML이란 단순한 문자열을 넘어서서, 내부적으로 트리 구조를 가진 파일을 표현하기 위한 마크업 언어이다. html 및 오피스파일도 XML에 속한다. 파이썬에서도 XML parser로서 주로 이용되는 패키지가 lxml이다.
import requests
from bs4 import BeautifulSoup
url = "https://comic.naver.com/webtoon/weekday.nhn"
res = requests.get(url)
res.raise_for_status()
soup = BeautifulSoup(res.text, "lxml")
print(soup.title)
print(soup.title.get_text())
print(soup.a) # soup 객체에서 처음 발견되는 a element 반환
print(soup.a.attrs) a element의 속성 정보를 출력
print(soup.a["href"]) #a element의 href 정보 출력
print(soup.find("a", attrs={"class":"Nbtn_upload"}))
print(soup.find(attrs={"class":"Nbtn_upload"}))
print(soup.find("li", attrs={"class":"rank01"}))
rank1 = soup.find("li", attrs={"class":"rank01"})
print(rank1.a)1
위의 해당 url에 페이지 내에서 원하는 정보를 마음대로 빼올 수 있다. class 값을 설정하여 특정 class 소스만 크롤링한다던가 등등...
정규식
- 예시로 이것은 올바른 주민번호의 형식이야, 이건 올바른 이메일의 형식이야 등, 올바른 정규 표현식에 대해서 알아보자.
Import re를 하는데 re = regular expression(정규 표현식)의 줄임말인 듯 하다.
import re
p = re.compile("ca.e")
def print_match(m):
if m :
print(m.group())
else:
print("매칭되지 않음")
m = p.match("careless")
print_match(m)
위의 함수에 대해서 ca.e를 기준으로 잡아서 careless와 일치하는 지를 판단하는 코드이다.
# . (ca.e) : 하나의 문자를 의미 > cane, cake, cafe(O) | caffe (x)
print((readLine()?.split(separator: " ")
.map { Int($0)!}.reduce(0, { x, y in -x - y}))!)
Solution 2.
import Foundation
let line = readLine() ?? ""
let lineArr = line.characters.split($0 == ""}.map(String.init)
let a = Int(lineArr[0]) ?? 0
let b = Int(lineArr[1]) ?? 0
print(a-b)
문제7.
두 정수 A와 B를 입력받은 다음, AxB를 출력하는 프로그램을 작성하시오.
입력
첫째 줄에 A와 B가 주어진다.(0<A, B<10)
Solution.
import Foundation
let lineArr = readLine()?.components(separatedBy: " ") ?? [""]
let A = Int(lineArr[0]) ?? 0
let B = Int(lineArr[1]) ?? 0
print(A*B)
Point.
Line이 필요 없다!
문제8.
두 정수 A와 B를 입력받은 다음, A/B를 출력하는 프로그램을 작성하시오.
입력
첫째 줄에 A와 B가 주어진다. (0 < A, B < 10)
출력
첫째 줄에 A/B를 출력한다. 실제 정답과 출력값의 절대오차 또는 상대오차가 10^-9 이하이면 정답이다.
Solution.
import Foundation
let lineArr = readLine()?.components(separatedBy: " ") ?? [""]
let A = Double(lineArr[0]) ?? 0
let B = Double(lineArr[1]) ?? 0
let AB = String(format: "%.9f",A/B)
print(AB)
Point.
format: "%.9f", A/B -> 소수점 n번째 자리까지 출력할 수 있어?
Float은 8자리 이하 소수점까지, Double은 16자리 이하 소수점까지 사용한다.
문제9.
두 자연수 A와 B가 주어진다. 이때, A+B, A-B, A*B, A/B(몫), A%B(나머지)를 출력하는 프로그램을 작성하시오.
입력
두 자연수 A와 B가 주어진다.(1 <= A, B <= 10,000)
출력
첫째 줄에 A+B, 둘째 줄에 A-B, 셋째 줄에 A*B, 넷째 줄에 A/B, 다섯재 줄에 A%B를 출력한다.
Solution.
import Foundation
let lineArr = readLine()?.components(separatedBy: " ") ?? [""]
let A = Int(lineArr[0]) ?? 0
let B = Int(lineArr[1]) ?? 0
print("\(A+B)\n\(A-B)\n\(A*B)\n\(A/B)\n\(A%B)")
문제 10.
(A+B)%C는 ((A%C) + (B%C)%C와 같을까?
(A+B)%C는 ((A%C) x (B%C)%C와 같을까?
세 수 A, B, C가 주어졌을 때, 위의 네 가지 값을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 A, B, C가 순서대로 주어진다.(2 <= A, B, C <= 10000)
출력
첫째 줄에 (A+B)%C, 둘째 줄에 ((A%C) + (B%C)%C, 셋째 줄에 (AxB)%C, 넷째 줄에 ((A%C) x (B%C))%C를 출력한다.
Solution.
import Foundation
let lineArr = readLine()?.components(separatedBy: " ") ?? [""]
let A = Int(lineArr[0]) ?? 0
let B = Int(lineArr[1]) ?? 0
let C = Int(lineArr[2]) ?? 0
print("\((A+B)%C)\n\((A%C+B%C)%C)\n\((A*B)%C)\n\((A%C*B%C)%C)")
문제 11.
(세 자리 수) x (세 자리 수)는 다음과 같은 과정을 통하여 이루어진다.
(1)과 (2) 위치에 들어갈 세 자리 자연수가 주어질 때, (3), (4), (5), (6) 위치에 들어갈 값을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 (1)의 위치에 들어갈 세 자리 자연수가, 둘째 줄에 (2)의 위치에 들어갈 세자리 자연수가 주어진다.
출력
첫째 줄부터 넷째 줄 까지 차례대로 (3), (4), (5), (6)에 들어갈 값을 출력한다.
Solution 1.
import Foundation
let A = Int(readLine() ?? "") ?? 0
let B = Int(readLine() ?? "") ?? 0
print("\(A*(B%10))\n\(A*(B%10)%10))\n\(A*(B/100))")
Point.
1의 자리, 10의 자리, 100의 자리를 구분할 수 있는가? 1의 자리 -> n%10, 10의 자리 - > (n/10)%10, 100의 자리 n/100
Solution 2.
import Foundation
let strA = readLine() ?? ""
let strB = readLine() ?? ""
let a = Int(strA) ?? 0
let b = Int(strB) ?? 0
var tmpB = b
while tmpB != 0 {
print(a*(tmpB%10))
tmpB /= 10
}
print(a*b)
Point.
n번째 자리수의 숫자 추출 방법 : 추출하고자 하는 자리수의 숫자를 1의 자리에 오도록 10으로 나눈 후, 10 나머지 연산을 계산한다.