์น ์คํฌ๋ ์ดํผ ์ ๋ฌธ
Beautiful Soup์ ์คํ
Beautiful Soup์์ ๊ฐ์ฅ ๋๋ฆฌ ์ฐ์ด๋ ๊ฐ์ฒด๋ BeautifulSoup ๊ฐ์ฒด์ด๋ค.
๋ค์ ์์ ๋ฅผ ๋ณด์.
from urllib.request import urlopen
from bs4 import BeautifulSoup
html=urlopen("https://pythonscraping.com/pages/page1.html")
bs=BeautifulSoup(html.read(), 'html.parser')
print(bs.h1)
์ถ๋ ฅ ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ๋ค.
<h1>An Interesting Title</h1>
ํ๋์ฉ ์ดํด๋ณด์.
์น ํ์ด์ง ์ฃผ์๋ก BeautifulSoup ๊ฐ์ฒด ์์ฑํ๊ธฐ
urlopen ํจ์๋ ์น ํ์ด์ง ์ฝ๋๋ฅผ ๋ฐํํด์ค๋ค. ๋ฐ๋ผ์ html์ด๋ผ๋ ๋ณ์์๋ ํ์ฌ ์น ํ์ด์ง ์ฝ๋๊ฐ ๋ค์ด์๋ค.
BeautifulSoup ๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค. ์ด๋ ๋ ๊ฐ์ง ๋งค๊ฐ๋ณ์๊ฐ ๋ค์ด๊ฐ๋ค.
์ฒซ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๊ฐ ๋๋ ๊ฒ์ ๊ฐ์ฒด์ ๊ทผ๊ฐ์ด ๋๋ HTML ํ ์คํธ์ด๋ค.
html.read()๋ฅผ ์ถ๋ ฅํด ๋ณด๋ฉด ์น ํ์ด์ง ์ฝ๋๋ฅผ ๋ณผ ์ ์๋ค.
๋ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ BeautifulSoup๊ฐ ๊ฐ์ฒด๋ฅผ ๋ง๋ค ๋ ์ฐ๋ ๊ตฌ๋ฌธ ๋ถ์๊ธฐ์ธ๋ฐ, ์ด ๊ตฌ๋ฌธ ๋ถ์๊ธฐ๋ ์ฐ๋ฆฌ๊ฐ ์ง์ ์ง์ ํ ์ ์๋ค.
์๊ธฐ ์์ ์์ ์ฌ์ฉํ html.parser๋ ํ์ด์ฌ3์ ํจ๊ป ์ค์น๋๋ฏ๋ก ๋ฐ๋ก ์ค์นํ ํ์ ์๋ค.
ํน๋ณํ ๋ค๋ฅธ ๋ถ์๊ธฐ๊ฐ ํ์ํ ๊ฒฝ์ฐ๊ฐ ์๋๋ผ๋ฉด ์ด๋ฅผ ๊ณ์ ์ฌ์ฉํ ๊ฒ์ด๋ค.
lxml ๋๋ html5lib ๋ ๋ถ์๊ธฐ๋ก ์ฌ์ฉํ ์ ์๋ค. ์ด๊ฒ๋ค์ ์ํฉ์ ๋ฐ๋ผ parser๋ณด๋ค ๋ ์ข์ ๊ธฐ๋ฅ์ ์ํํ ์ ์์ง๋ง ๋ณ๋๋ก ์ค์นํด์ผ ํ๋ค.
๋ถ์๊ธฐ๋ฅผ ๊ฑฐ์ณ ์์ฑ๋ BeautifulSoup ๊ฐ์ฒด์ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ๋ค.
html : <html><head>...</head><body>...</body></html>
- head : <head><title>A Useful Page</title></head>
-- title : <title>A Useful Page</title>
-body : ......
์ด๋ฐ ์์ด๋ค.
์๊ธฐ ์์ ์์ ์ถ์ถํ <h1> ํ๊ทธ๋ ๊ฐ์ฒด์์ ๋ ๋จ๊ณ๋งํผ ์ค์ฒฉ๋์ด์๋ค. ํ์ง๋ง ์ฐ๋ฆฌ๊ฐ ๊ฐ์ฒด์์ ๊ฐ์ ธ์ฌ ๋๋ h1 ํ๊ทธ๋ฅผ ์ง์ ๊ฐ์ ธ์๋ค. ์ฌ์ค ๋ค์ ์ค ๋ฌด์์ ์ฌ์ฉํด๋ ๊ฒฐ๊ณผ๋ ๊ฐ๋ค.
bs.html.body.h1
bs.body.h1
bs.html.h1
์น์ฌ์ดํธ์์์ ํฌ๋กค๋ง ์ฐจ๋จ
ํฌ๋กค๋ง์ ์ฐจ๋จํ์ฌ 406 ์๋ฌ๊ฐ ๋์ฌ ์๋ ์๋ค.
์ด๋๋ ์ ์ ์ ๋ณด๋ฅผ ์ง์ ์ง์ ํ์ฌ ํฌ๋กค๋ง ์ฐจ๋จ์ ์ฐํํด์ผํ๋ค.
๊ธฐ๋ณธ ์ฝ๋์ ์ฐํ ์ฝ๋๋ฅผ ์ฐจ๋ก๋๋ก ๋ณด์ฌ์ฃผ๊ฒ ๋ค.
from urllib.request import urlopen
from bs4 import BeautifulSoup
html=urlopen("https://pythonscraping.com/pages/page1.html")
bs=BeautifulSoup(html.read(), 'html.parser')
import urllib.request
import urllib.parse
from bs4 import BeautifulSoup
headers_info = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36'}#์ ์ ์ ๋ณด ์ง์ ์ง์
html=urllib.request.Request('https://hushinn.tistory.com/manage/newpost/112', headers=headers_info)
bs=BeautifulSoup(urllib.request.urlopen(html).read() , 'html.parser')
์์ธ์ฒ๋ฆฌ(์ค์!!)
์น์ ์๋ง์ง์ฐฝ์ด๋ค! ๋ฐ์ดํฐ ํ์์ ์ ๋๋ก ์ง์ผ์ง์ง ์๊ณ ์น์ฌ์ดํธ๋ ์์ฃผ ๋ค์ด๋๊ณ ๋ซ๋ ํ๊ทธ๋ ์ข ์ข ๋น ์ ธ์๋ค...
์ป ์คํฌ๋ ์ดํผ๊ฐ ์๊ธฐ์น ๋ชปํ ๋ฐ์ดํฐ ํ์์ ๋ถ๋ํ ๋ฉ์ถฐ๋ฒ๋ฆฌ๋ ๊ฒฝ์ฐ๊ฐ ๋งค์ฐ ๋ง๋ค!
๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ ์น ์คํฌ๋์ดํผ๋ฅผ ๋ง๋ค ๋ ์ฐ๋ฆฌ๊ฐ ๋ชฉํ๋ก ํ๋ ์์์ ์ด๋ป๊ฒ ์ ๊ทผํ ๊ฒ์ธ๊ฐ ๋ฟ ์๋๋ผ ์์์น ๋ชปํ ์ค๋ฅ๋ฅผ ๋ง๋ฌ์ ๋ ์ด๋ฅผ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ์ง์ ๋ํด์๋ ๊น์ด ๊ณ ๋ฏผํด์ผํ๋ค.
์์ ์์ ๋ฅผ ์๊ธฐํ๋ฉฐ ๋ฐ์ํ ์ ์๋ ์ค๋ฅ์ ๋ํด ์์๋ณด๊ณ , ์ฒ๋ฆฌ ๋ฐฉ๋ฒ์ ๋ํด์๋ ์์๋ณด์.
html=urlopen("https://pythonscraping.com/pages/page1.html")
์ด ํ์์ ๋ฌธ์ ๊ฐ ์๊ธธ ์ ์๋ ๋ถ๋ถ์ ํฌ๊ฒ ๋ ๊ฐ์ง์ด๋ค.
- ํ์ด์ง๋ฅผ ์ฐพ์ ์ ์๊ฑฐ๋, URL ํด์์์ ์๋ฌ๊ฐ ์๊ธด ๊ฒฝ์ฐ.
- ์๋ฒ๋ฅผ ์ฐพ์ ์ ์๋ ๊ฒฝ์ฐ.
์์ธ์ฒ๋ฆฌ๋ฅผ ๋ฐ๋ก ํด์ฃผ์ง ์๋ ๊ฒฝ์ฐ, ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ๋ง์ฃผ์ณค์๋ ์น ์คํฌ๋ ์ดํผ๋ ๋ฉ์ถฐ๋ฒ๋ฆฌ๊ณ ๋ง๋ค.
์ฒซ ๋ฒ์งธ ์ํฉ์์๋ HTTP ์๋ฌ๋ฅผ ๋ฐํํ ๊ฒ์ด๋ค.
์ด ์๋ฌ๋ "404 Page Not Found", "500 Internal Server Error" ๋ฑ์ด๋ค.
์ด๋ฐ ๋ชจ๋ ๊ฒฝ์ฐ์ urlopen ํจ์๋ HTTPError๋ฅผ ์ผ์ผํจ๋ค. ์ด ์์ธ๋ ๋ค์๊ณผ ๊ฐ์ด ์ฒ๋ฆฌํ๋ค.
from urllib.request import urlopen
from urllib.request import HTTPError
from bs4 import BeautifulSoup
try:
html=urlopen("https://pythonscraping.com/pages/page1.html")
except HTTPError as e:
print(e)
#null์ ๋ฐํํ๊ฑฐ๋, break๋ฌธ์ ์คํํ๊ฑฐ๋...
else:
#ํ๋ก๊ทธ๋จ์ ๊ณ์ ์คํํ๋ค.
์ด๋ ๊ฒ ์ฝ๋๋ฅผ ์ง์ฃผ๋ฉด HTTP์๋ฌ ์ฝ๋๊ฐ ๋ฐํ๋์์ ๋, ํ๋ก๊ทธ๋จ์ ์๋ฌ๋ฅผ ์ถ๋ ฅํ๊ณ else๋ฌธ์ ์คํํ์ง ์์ ๊ฒ์ด๋ค.
๋ ๋ฒ์งธ ์ํฉ์ ์๋ฒ๋ฅผ ์ ํ ์ฐพ์ ์ ์์๋ ๋ฐ์ํ๋ค.
์น์ฌ์ดํธ๊ฐ ๋ค์ด๋๊ฑฐ๋, URL์ ์คํ๊ฐ์์๋ urlopen์ URLError ์์ธ๋ฅผ ์ผ์ผํจ๋ค.
์ด๊ฒ๋ ์บ์นํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ค.
from urllib.request import urlopen
from urllib.request import HTTPError
from urllib.request import URLError
from bs4 import BeautifulSoup
try:
html=urlopen("https://pythonscraping.com/pages/page1.html")
except HTTPError as e:
print(e)
except URLError as e:
print('The server could not be found!')
else:
print('It Worked!')
๋ฌผ๋ก ํ์ด์ง๋ฅผ ์๋ฒ์์ ์ฑ๊ณต์ ์ผ๋ก ๊ฐ์ ธ์์ด๋ ํ์ด์ง ์ฝํ ์ธ ๊ฐ ์์๊ณผ ๋ฌ๋ผ ์๋ฌ๊ฐ ๋ฐ์ํ ์ ์๋ค.
๋ฐ๋ผ์ BeautifulSoup ๊ฐ์ฒด์ ๋ค์ด์๋ ํ๊ทธ์ ์ ๊ทผํ ๋๋ง๋ค ๊ทธ ํ๊ทธ๊ฐ ์ค์ ์กด์ฌํ๋์ง ์ฒดํฌํ๋ ํธ์ด ์ข๋ค.
์กด์ฌํ์ง ์๋ ํ๊ทธ์ ์ ๊ทผ์ ์๋ํ๋ฉด BeautifulSoup๋ None ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
์ฌ๊ธฐ์ None ๊ฐ์ฒด ์์ฒด์ ํ๊ทธ๊ฐ ์๋ค๊ณ ๊ฐ์ ํ๊ณ ์ ๊ทผํ๋ ค ํ๋ฉด AttributeError๊ฐ ์ผ์ด๋๋ค.
๋ฐ๋ผ์ ์ ์ด์ ํ๊ทธ์ ์ ๊ทผํ ๋ ํน์ ํ๊ทธ๊ฐ ์กด์ฌํ๋ ์ง๋ฅผ ์ฌ์ ์ ๊ฒ์ฌํ๋ฉฐ ์งํํ๋ ๊ฒ์ด ์ข๋ค.
์๋ฅผ ๋ค์ด ์์ ์์์ bs ๊ฐ์ฒด์ nonExistiongTag ๋ผ๋ ํ๊ทธ๊ฐ ์กด์ฌํ ๊ฒ์ด๋ฉฐ, ๊ทธ ํ์์ anotherTag ๋ผ๋ ํ๊ทธ๊ฐ ์กด์ฌํ ๊ฒ์ด๋ผ๊ณ ์์ํ๋ค๊ณ ๊ฐ์ ํ์. ๊ทธ๋ ๋ค๋ฉด ์ด๋ป๊ฒ ์ ๊ทผํ๋ ๊ฒ์ด ์ข์๊น?
๋ค์ ์ฝ๋์ ๊ฐ์ด ์์ฑํ๋ฉด ๋๋ค.
try:
target_content=bs.nonExistingTag.anotherTag
except AttributeError as e:
print("Tag was not found")#nonExistingTag ๊ฐ ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ
else:
if badContent == None:
print("Tag was not found")#anotherTag ๊ฐ ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ
else:
print(badContent)#์ ์ ์ํฉ!!
์ด๋ ๊ฒ ๊ฐ๋ฅํ ์๋ฌ๋ฅผ ๋ชจ๋ ์ฒดํฌํ๊ณ ์ฒ๋ฆฌํ๋ ์ผ์ด ์ง๊ฒน๋ค๊ณ ๋๋ ์ ์์ผ๋, ์ฝ๋๋ฅผ ์กฐ๊ธ๋ง ์์ ํ๋ฉด ์ข ๋ ์ฝ๊ฒ ์ฝ์ ์ ์๋ค.
๋ค์ ์ฝ๋๋ฅผ ๋ณด์.
from urllib.request import urlopen
from urllib.request import HTTPError
from urllib.request import URLError
from bs4 import BeautifulSoup
def GetTitle(url):
try:
html=urlopen(url)
except HTTPError as e:
return None
except URLError as e:
return None
try:
bs=BeautifulSoup(html.read(), 'html.parser')
title=bs.body.h1
except AttributeError as e:
return None
return title
title = GetTitle('https://pythonscraping.com/pages/page1.html')
if title == None:
print('Title could not be found')
else:
print(title)
์ด ์์ ์์๋ GetTitle ํจ์์ ๋งํฌ๋ฅผ ์ ๋ฌํ ๊ฒฝ์ฐ ํ์ดํ์ด ์์ผ๋ฉด ํ์ดํ์, ํ์ดํ์ด ์์ผ๋ฉด none๊ฐ์ ๋ฐ์ ์ ์๋ค.
์ฐ๋ฆฌ๋ ์น์ฌ์ดํธ์ ํ์ดํ์ ์ ๊ทผํด์ผ ํ ๊ฒฝ์ฐ ์ด ํจ์์ ๋งํฌ๋ฅผ ์ ๋ฌํ ๋ค, ๊ฒฐ๊ณผ๊ฐ์ด None์ธ์ง๋ง ๊ฒ์ฌํ๋ฉด ๋ฐ๋ก ํ์ดํ์ ์ทจ๊ธํ ์ ์๋ค.
์ด๋ ๋ฏ ๊ธฐ๋ฅ์ ์บก์ํํ์ฌ ์ฌ์ฌ์ฉํ๋ ๋ฐฉ์์ผ๋ก ์คํฌ๋ ์ดํผ๋ฅผ ์ ์ํด์ผ ํ๋ค.
์๋ฌ ์ฒ๋ฆฌ๊ฐ ๋ฒ๊ฑฐ๋กญ๋ค๊ณ ํ์ฌ ์๋ฌ ์ํฉ์ ๋ฐฐ์ ํ ์คํฌ๋ ์ดํผ๋ฅผ ์ ์ํ๋ฉด ๊ฒฐ๊ตญ ํฌ๋กค๋ง์ ๋ฌธ์ ๊ฐ ์๊ธฐ๊ณ ๋ง ๊ฒ์ด๋ค.