다음 강의를 정리하여 작성하였습니다
https://www.youtube.com/watch?v=yQ20jZwDjTE&list=LL&index=3&t=1526s
웹 스크래핑 -> 웹 페이지에서 내가 원하는 정보를 가져 오는 것
웹 크롤링 -> 웹페이지에서 링크를 따라가며 모든 내용을 가져오는 것
HTML
Hyper Text Markup Language
즉 웹페이지 만드는 언어이다
VSC에서 이걸 열고 싶으면
HTML은 아래와 같이 코드를 작성한다
보통 다음과 같이
<html>
<head>
</head>
<body>
</body>
</html>
이것을 기본 구조로 가진다
이를 응용해보면
<html>
<head>
<title>승종 홈페이지</title>>
</head>
<body>
<h1> Hello World</h1>
<input type="text" value="아이디를 입력하세요">
<input type="password" value="비밀번호를 입력하세요">
<input type="button" value="로그인">
</body>
</html>
먼저 꺽쇠로 시작을 하고 /로 닫으므로써 element로 구성한다
바로닫고 싶으면 <html/> 이렇게도 쓴다
head : 홈페이지의 제목, 선행작업
body : 웹페이지의 본문
h1 : 글자가 크게 나옴
element들의 세부 속성을 attribute를 통해 지정을 하고
위에서는 type과 value를 사용 하였다
이를 출력해보면
다음과 같이 출력이 되고 만약 한글이 깨진다면
<html>
<head>
<meta charset="utf-8">
<title>승종 홈페이지</title>>
</head>
<body>
<h1> Hello World</h1>
<input type="text" value="아이디를 입력하세요">
<input type="password" value="비밀번호를 입력하세요">
<input type="button" value="로그인">
</body>
</html>
다음과 같이 meta를 이용하여서 선행작업을 수행해주면 된다
그러면 링크는 어떻게 걸까???
<html>
<head>
<title>승종 홈페이지</title>>
</head>
<body>
<h1> Hello World</h1>
<input type="text" value="아이디를 입력하세요">
<input type="password">
<input type="button" value="로그인">
<a href="http://google.com"> 구글로 이동하기 </a>>
</body>
</html>
다음과 같이 a href를 이용하면 된다
다음과 같이 하이퍼링크가 생긴다
추가적인 공부는
W3Schools Free Online Web Tutorials
W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.
www.w3schools.com
여기에서 추가 공부를 하면 된다
XPath
다음과 같은 예시를 보자
<학교 이름 = "고등학교">
<학년 value= "1학년">
<반 value="1반">
<학생 value="1번" 학번 = "1-1-1">이지은</학생>
<학생 value="2번" 학번 = "1-1-2">가나다</학생>
<학생 value="3번" 학번 = "1-1-3">라마바</학생>
<학생 value="4번" 학번 = "1-1-4">이지은</학생>
</반>
<반 value="2반"/>
<반 value="3반"/>
<반 value="4반"/>
</학년>
<학년 value= "2학년">
<학년 value= "3학년">
</학교>
나는 1학년 1반 4번 이지은을 부르고 싶은데 1번이랑 이름이 겹쳐서 혼동이 올 수 도 있다
즉, 어떤 element를 지칭하는지를 확실하게 하기 위해 XPath를 사용
ex)
/학교/학년/반/학생[2]
[2]: 두번째 element
이렇게 하면 복잡해지면 너무 깊어지기 때문에 위에서 학번을 지정해줌
ex)
//*[@학번 = '1-1-3']
이렇게 줄일 수 있다
학번이 1-1-3인 걸 모든 문서에서 찾아주세요 라는 뜻
/ : 하위 디렉토리
// : 모든 하위 디렉토리
* : 이름 상관 없이
즉, 다음과 같이 2가지 표현이 있다
/학교/학년/반/학생[2]
//*[@학번 = '1-1-3']
ex)
다음과 같이 네이버의 로그인 버튼 부분을 가져와 보자
다음과 같이
full XPath로 가져오면
/html/body/div[2]/div[3]/div[3]/div/div[2]
이고
XPath 로 가져오면
//*[@id="account"]
이다
Chrome
원하는 element에 마우스 올리고 우클릭하고 검사를 누르거나
단축키 f12
저 버튼을 누르고
화면에 원하는 부분을 클릭하면 해당 element로 호출이 자동으로 된다
Requests 라이브러리
웹 스크래핑을 위해 html 문서 정보를 가져와야하는데 이를 해줌
pip install requests
다음 코드를 통해 설명
import requests
res = requests.get("http://naver.com") #url에 대한 정보를 받아와 res에 저장
#서버 응답이 정상적인지 확인하는 방법
print("응답코드 : ", res.status_code) #200이면 정상
#ex) 403 -> 접근권한이 없다
#응용 -> 아래의 세개가 같은 기능이다
if res.status_code == 200:
print("서버 응답이 정상적이다")
else:
print("문제가 생겼습니다 [에러코드 : ",res.status_code, "]")
if res.status_code == requests.codes.ok:
print("서버 응답이 정상적이다")
else:
print("문제가 생겼습니다 [에러코드 : ",res.status_code, "]")
res.raise_for_status() #문제 없을땐 pass, 문제 있을땐 error
print("웹 스크래핑을 진행합니다")
위에서 가져온 res에 문자들을 보고 싶으면
print(res.text)
이를 응용해보면
import requests
res = requests.get("http://google.com") #url에 대한 정보를 받아와 res에 저장
#서버 응답이 정상적인지 확인
res.raise_for_status() #문제 없을땐 pass, 문제 있을땐 error
print("웹 스크래핑을 진행합니다")
print("웹 페이지 문자 개수 : ", len(res.text))
with open("mygoogle.html", "w", encoding= "utf-8") as f:
f.write(res.text)
를 실행했더니 다음과 같이
AttributeError: partially initialized module 'requests' has no attribute 'get' (most likely due to a circular import)
가 떴다
이는 파일명과 모듈명이 동일 (requests.py) 해서 발생한 error 이므로 파일명을 바꿔주도록 한다
이제 mygoogle.html을 열어보면
다음과 같이 글씨만 전부 가져온 것을 볼 수 있다
정규식
정규식 : Regular Expression
줄여서 re, regex, regexp 라고 많이 쓴다
의미는 정해진 형식이라고 해석하면 된다
사용법
import re
다음과 같은 구조를 가지는 단어를 찾는다 가정을 하자
c a _ e
다음과 같이 코드를 짤 수 있다
import re
#어떤 정규식을 컴파일 할지를 정함
p = re.compile("ca.e")
m = p.match("case")
#p.match("비교할 값")
print(m.group()) #만족하는 문자들을 출력, 매치되지 않으면 error가 발생
- . : 하나의 문자 cafe 가능 caffe 등은 불가
- ^ : 문자열의 시작 ex) ^de : desk, destination 가능 face : 불가
- $ : 문자열의 끝 ex) $ie -> compile , pie .....
이를 이용하여서 매칭 되었을 때만 처리하는 코드
import re
#어떤 정규식을 컴파일 할지를 정함
p = re.compile("ca.e")
m = p.match("case")
if m:
print(m.group) #만족하는 문자들을 출력, 매치되지 않으면 error가 발생
else:
print("매칭되지 않음")
이렇게 해서 error를 발생하지 않고 할 수 있다
다음과 같이 응용을 할 수 있다
주의점
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)
이거는 매치가 된다 (뒤에는 뭐가 있던지 상관없음 -> 앞에 부터 care면 ok)
아래는 매칭되지 않는다고 나온다
import re
#어떤 정규식을 컴파일 할지를 정함
p = re.compile("ca.e")
def print_match(m):
if m:
print(m.group())
else:
print("매칭되지 않음")
m = p.match("good care")
print_match(m)
그러면 위와 같이 주어진 문자열 중에 일치하는게 있는지 확인하는 방법은 무엇일까?
Search()를 이용
import re
#어떤 정규식을 컴파일 할지를 정함
p = re.compile("ca.e")
def print_match(m):
if m:
print(m.group())
else:
print("매칭되지 않음")
m = p.search("good care")
print_match(m)
이러면 주어진 문자열 중에 일치하는게 있는지를 확인하는 것이다
그런데 이렇게 하면
print(m.group())에서
>> care 라고 출력이 된다. 이걸 good care로 출력을 하려면 어떻게 해야할까?
p.search(), p.match() 의 결과 값을 받은 m 은 다양한 기능들이 있는데
- m.group() : 일치하는 문자열 반환
- m.string : 입력받은 문자열 -> 이건 함수가 아님
- m.start() : 일치하는 문자열의 시작 index
- m.end() : 일치하는 문자열의 끝 index
- m.span() : 일치하는 문자열의 시작과 끝 index를 함께 출력
를 이용할 수 있다
밑에 코드에서 자세히 알아보자
import re
#어떤 정규식을 컴파일 할지를 정함
p = re.compile("ca.e")
def print_match(m):
if m:
print("m.group() : ", m.group()) # : 일치하는 문자열 반환
print("m.string : ", m.string) # : 입력받은 문자열 -> 이건 함수가 아님
print("m.start() : ", m.start()) # : 일치하는 문자열의 시작 index
print("m.end() : ", m.end())# : 일치하는 문자열의 끝 index
print("m.span() : ",m.span()) #: 일치하는 문자열의 시작과 끝 index를 함께 출력
else:
print("매칭되지 않음")
m = p.search("good care")
print_match(m)
를 실행하면 다음과 같은 결과를 얻을 수 있다
그러면 p.match 와 search 말고는 뭐가 있을까??
findall()
-> 일치하는 모든 것을 리스트 형태로 반환
import re
#어떤 정규식을 컴파일 할지를 정함
p = re.compile("ca.e")
lst = p.findall("good care cafe")
print(lst)
를 실행시키면
다음과 같은 list를 확인할 수 있다
정리
1. p = re.compile("원하는 형태") 을 통해 형태를 받아 온다
2. 다양한 함수를 통해 확인을 한다
m = p.match("비교할 문자열 ") : 주어진 문자열의 처음부터 일치하는지 확인
m = p.search("비교할 문자열 ") : 주어진 문자열 중에 일치하는게 있는지 확인
lst = p.findall("비교할 문자열 ") : 일치하는 모든 것을 리스트 형태로 반환
※원하는 형태
. (ca.e) : 하나의 문자를 의미 > care, cafe, case (O) | caffe (X)
^ (^de) : 문자열의 시작 > desk, destination (O) | fade (X)
$ (se$) : 문자열의 끝 > case, base (O) | face (X)
추가적인 공부는 마찬가지로
https://www.w3schools.com/python/python_regex.asp
Python RegEx
W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.
www.w3schools.com
여기나 re 공식 문서 사이트
https://docs.python.org/3/library/re.html
re — Regular expression operations
Source code: Lib/re/ This module provides regular expression matching operations similar to those found in Perl. Both patterns and strings to be searched can be Unicode strings ( str) as well as 8-...
docs.python.org
를 통해서 공부가 가능하다
User Agent
만약 네이버에서 권한을 주지 않으면 다음의 코드를 실행시켜보면 403 error 가 난다
import requests
res = requests.get("http://naver.com") #url에 대한 정보를 받아와 res에 저장
res.raise_for_status() #문제 없을땐 pass, 문제 있을땐 error
with open("mycrowling.html", "w", encoding= "utf8") as f :
f.write(res.text)
그러면 어떻게 해결을 할까???
다음의 사이트를 통해 나의 User 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
를 보면
그러면 다시 돌아와서 다음의 User Agent 정보를 넘겨주자
headers 라는 변수를 만들어서 requests.get에 parameter로 넘겨주자
import requests
url = "http://naver.com"
headers = {"User-Agent" : "빨강색 박스 부분 복붙"}
res = requests.get(url, headers = headers)
res.raise_for_status() #문제 없을땐 pass, 문제 있을땐 error
with open("mycrowling.html", "w", encoding= "utf8") as f :
f.write(res.text)
쉽게 말해서 그냥 불법 프로그램이 아닌 사람이라는 것을 알려주는 것이라 생각하면 될 것 같다
(즉, 우리가 크롬등을 통해서 접근한 것과 동일한 정보를 얻을 수 있다)
'Python > Application' 카테고리의 다른 글
[Python] Streamlit 활용 전 정리 (0) | 2024.06.05 |
---|---|
[Data Scraping] Error : Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the same (0) | 2023.02.10 |
[Data Scraping] 구글에서 고화질 이미지 스크래핑(크롤링) - selenium (0) | 2023.01.27 |
[Scraping] Web Crowling 이라기 보단 Scraping (beautifulsoup4) (0) | 2023.01.24 |