Python

[python] ์›นํฌ๋กค๋ง beautifulsoup ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ - ์„ค์น˜์™€ ํ™œ์šฉ๋ฒ•

hyonie 2024. 5. 4. 18:33

 

๋ชฉ์ฐจ

     


    ํŒŒ์ด์ฌ์˜ ๋‹ค์–‘ํ•œ ํ™œ์šฉ ๊ธฐ๋Šฅ

    ํŒŒ์ด์ฌ์€ ์›นํฌ๋กค๋ง, ์ž๋™ํ™”, ๋”ฅ๋Ÿฌ๋‹, ์›นํŽ˜์ด์ง€ ์ œ์ž‘, ๋ฐ์ดํ„ฐ๋ถ„์„, GUI ํ”„๋กœ๊ทธ๋ž˜๋ฐ, ๊ฒŒ์ž„๊ฐœ๋ฐœ, ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ ๋“ฑ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์—ฌ ์ฃผ๋ชฉ์„ ๋ฐ›๊ณ  ์žˆ๋‹ค. ๊ฐ๊ฐ์˜ ํ™œ์šฉ ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ณด์ž. ๊ทธ๋ฆฌ๊ณ  ์›น ํฌ๋กค๋ง BeautifulSoup ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.

    ๊ธฐ๋Šฅ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ/ ํ”„๋ ˆ์ž„์›Œํฌ
    ์›น ํฌ๋กค๋ง BeautifulSoup
    ์ž๋™ํ™” Selenium
    ๋”ฅ๋Ÿฌ๋‹ TensorFlow
    ์›นํŽ˜์ด์ง€ ์ œ์ž‘ Django, Flask
    ๋ฐ์ดํ„ฐ ๋ถ„์„ Pands, Matplotlib
    GUI ํ”„๋กœ๊ทธ๋ž˜๋ฐ Tkinter, PyQt
    ๊ฒŒ์ž„ ๊ฐœ๋ฐœ Pygame
    ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ OpenCV

     


     

    ๐Ÿ” ์›นํฌ๋กค๋ง์ด๋ž€?

    • ์ธํ„ฐ๋„ท ์ƒ์˜ ์›นํŽ˜์ด์ง€์—์„œ ์ •๋ณด๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ์ž‘์—…์œผ๋กœ
    • ์›นํŽ˜์ด์ง€์˜ HTML ์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ์™€์„œ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœํ•˜๋Š” ๊ธฐ์ˆ ์ด๋‹ค.

     

     


     

    ๐Ÿ”ง ํ•„์š”ํ•œ ๋„๊ตฌ

    • 'requests' : ์›นํŽ˜์ด์ง€์—์„œ HTML ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ชจ๋“ˆ
    • 'BeautifulSoup' : ๊ฐ€์ ธ์˜จ HTML์„ ๋ถ„์„ํ•˜์—ฌ ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์ถ”์ถœํ•˜๋Š” ๋ชจ๋“ˆ

     

     


     

    โš™ ํฌ๋กค๋ง, ํŒŒ์‹ฑ, ์Šคํฌ๋ž˜ํ•‘์˜ ์ฐจ์ด๋Š” ๋ฌด์—‡์ผ๊นŒ?

    • ํฌ๋กค๋ง์€ ์›น ์ธ๋ฑ์‹ฑ์„ ์œ„ํ•ด ์›”๋“œ์™€์ด๋“œ์›น(WWW)์„ ์ฒด๊ณ„์ ์œผ๋กœ ํƒ์ƒ‰ํ•ด ๋‚˜๊ฐ€๋Š” ์ž‘์—…
    • ํŒŒ์‹ฑ์€ ์›น์ƒ์˜ ๋ฌธ์ž์—ด์„ ๋ถ„์„ํ•˜์—ฌ ์˜๋ฏธ ์žˆ๋Š” ์ •๋ณด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ณผ์ •
    • ์Šคํฌ๋ž˜ํ•‘์€ ๋‹ค์–‘ํ•œ ์›น ์‚ฌ์ดํŠธ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœํ•˜๋Š” ๊ธฐ์ˆ ์„ ์˜๋ฏธ

     

     


     

    ์›นํฌ๋กค๋ง BeautifulSoup ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ™œ์šฉ

     

     

    ๐Ÿ“ฆ BeautifulSoup ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜

    ์›นํฌ๋กค๋ง ์‹œ ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•œ๋‹ค. beautifulsoup4, requests

     

    1. cmd ์ฐฝ์„ ์‹คํ–‰ํ•œ๋‹ค (Window + R)
    2. ํŒŒ์ด์ฌ ์‰˜ ๋ชจ๋“œ ์‹คํ–‰ํ•œ๋‹ค. (โœ… ํŒŒ์ด์ฌ ์„ค์น˜์‹œ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ํŒจ์Šค๋ฅผ ๋ฐ˜๋“œ์‹œ ์ฒดํฌํ•ด์•ผ ์‰˜์„ ์‚ฌ์šฉํ• ์ˆ˜ ์žˆ๋‹ค.)
    3. ํŒŒ์ด์ฌ ์‰˜ ์—์„œ Beautifulsoup ๋ชจ๋“ˆ ํ™•์ธ 
    4. ์„ค์น˜๊ฐ€ ์•ˆ๋œ ๊ฒฝ์šฐ ctrl + z๋กœ ์‰˜ ํ™”๋ฉด์„ ์ข…๋ฃŒํ•˜๊ณ , ์•„๋ž˜ install ๋ช…๋ น ์‹คํ–‰

     


     

     

    ๐Ÿ“ ediya.html ํŒŒ์ผ ์›นํฌ๋กค๋งํ•˜๊ธฐ - ๋กœ์ปฌ

    1. ์ด๋””์•ผ ์‚ฌ์ดํŠธ๋ฅผ ํฌ๋กค๋งํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ediya.html ํŒŒ์ผ์„ ์ž‘์—…๊ณต๊ฐ„์— ๋ฐฐ์น˜ํ•œ๋‹ค.
    2. File > NewFile > "์›นํฌ๋กค๋ง.py" ๋กœ ์ €์žฅ

     

    ๐Ÿ“ ์›นํฌ๋กค๋ง.py ์ฝ”๋“œ ์ž‘์„ฑ

    from bs4 import BeautifulSoup
    
    homepage = open('ediya.html', 'r', encoding = 'utf-8')
    doc = homepage.read()
    homepage.close()
    
    #print(doc)
    
    soup = BeautifulSoup(doc,'html.parser')
    result = soup.find_all('p', class_='each-menu')
    #print(result)
    
    
    for data in result:
        #print(data)
        print(data.text)

     

    • `from bs4 import BeautifulSoup` : ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” HTML ๋ฐ XML ๋ฌธ์„œ๋ฅผ ํŒŒ์‹ฑํ•˜๊ณ  ๋ถ„์„ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ
    • `homepage = open('')` : html ํŒŒ์ผ์„ ์ฝ๊ธฐ๋ชจ๋“œ('r')๋กœ ์—ด๊ณ , ํŒŒ์ผ์„ ์ฝ์„๋•Œ UTF-8 ์ธ์ฝ”๋”ฉ์„ ์‚ฌ์šฉํ•œ๋‹ค. ์ด๋•Œ ํŒŒ์ผ์ด ํ˜„์žฌ ๋””๋ ‰ํ† ๋ฆฌ์— ์žˆ์–ด์•ผ ํ•œ๋‹ค. ํŒŒ์ผ์„ ์—ด๊ณ  ํ•ด๋‹น ๋‚ด์šฉ์„ ๋ณ€์ˆ˜ hompage์— ์ €์žฅํ•œ๋‹ค.
    • `doc = homepage.read()` : homepage์—์„œ HTMLํŒŒ์ผ์˜ ๋‚ด์šฉ์„ ์ฝ์–ด์™€ ๋ณ€์ˆ˜ doc์— ์ €์žฅํ•œ๋‹ค. ์ด ๋ณ€์ˆ˜์—๋Š” HTMLํŒŒ์ผ์˜ ๋ชจ๋“  ๋‚ด์šฉ์ด ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ ์ €์žฅ๋œ๋‹ค.
    • `homepage.close()` : โš  ํŒŒ์ผ์„ ์—ด์—ˆ์œผ๋ฉด ํ•ญ์ƒ ํŒŒ์ผ์„ ๋‹ซ์•„์•ผํ•œ๋‹ค.!! 
    • doc์— ๋‹ด๊ธด HTML ํŒŒ์ผ์„ ์—ด์–ด์„œ ํ•ด๋‹น ๋‚ด์šฉ์„ ๋ฌธ์ž์—ด๋กœ ์ฝ์–ด์˜จ ํ›„์—, BeautifulSoup ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์‹ฑ๋œ ๊ฒฐ๊ณผ๋ฅผ ํ†ตํ•ด ์›ํ•˜๋Š” ์ •๋ณด๋ฅผ ์ถ”์ถœํ• ์ˆ˜ ์žˆ๋‹ค.
    • `soup = BeautifulSoup(doc, 'html.parser') ` : BeautifulSoup ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ์ด๋•Œ, doc์— ์ €์žฅ๋œ HTML๋ฌธ์„œ๋ฅผ ๋ฌธ์ž์—ด๋กœ ํŒŒ์‹ฑํ•˜๊ณ  BeautifulSoup๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค. HTML ๋ฌธ์„œ๋ฅผ ํŒŒ์‹ฑํ• ๋•Œ๋Š” 'html.parser'๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
    • `result = soup.find_all('p', class_='each-menu')` : BeautifulSoup ๊ฐ์ฒด soup ์—์„œ find_all ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ HTML๋ฌธ์„œ์—์„œ <p> ํƒœ๊ทธ ์ค‘ ํด๋ž˜์Šค ์†์„ฑ์ด each-menu ์ธ ๋ชจ๋“  ์š”์†Œ๋ฅผ ์ฐพ๋Š”๋‹ค. ๊ฒฐ๊ณผ๋Š” ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜๋˜๊ณ , ์ด ๋ฆฌ์ŠคํŠธ์—๋Š” ํ•ด๋‹น ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๋ชจ๋“  ์š”์†Œ๊ฐ€ ํฌํ•จ๋œ๋‹ค.
    • `for data in result` : result ๋ฆฌ์ŠคํŠธ์— ์ €์žฅ๋œ ๊ฐ ์š”์†Œ๋“ค์„ ์ˆœํšŒํ•˜๋ฉด์„œ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ data๋Š” result ๋ฆฌ์ŠคํŠธ์— ์žˆ๋Š” ๊ฐ๊ฐ์˜ ์š”์†Œ๋ฅผ ์˜๋ฏธํ•œ๋‹ค.
    • `print(data.text)` :  BeautifulSoup ๊ฐ์ฒด์ธ data์˜ ํ…์ŠคํŠธ ๋‚ด์šฉ๋งŒ ์ถœ๋ ฅํ•œ๋‹ค. ํƒœ๊ทธ๊นŒ์ง€ ๋‚˜์˜ค๋Š”๊ฒƒ์„ ์›ํ•˜์ง€ ์•Š์„๋•Œ๋Š” .text์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ์š”์†Œ์˜ ํ…์ŠคํŠธ ๋‚ด์šฉ๋งŒ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•œ๋‹ค. 

     

    print(doc) ๋ฐ ๊ฐ๊ฐ์˜ ์ถœ๋ ฅ๊ฐ’

     

     

     


     

    ๐Ÿฅ• ๋‹น๊ทผ๋งˆ์ผ“ ์‚ฌ์ดํŠธ ์›นํฌ๋กค๋งํ•˜๊ธฐ - Colab

    ์ด๋ฒˆ์—๋Š” ์‹ค์ œ ๋‹น๊ทผ๋งˆ์ผ“ ์‚ฌ์ดํŠธ๋ฅผ Colab์—์„œ ํฌ๋กค๋งํ•ด๋ณด์ž.

     

    ๐Ÿ“ ์ฝ”๋“œ ์„ค๋ช…

     

    • `requests` ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ url ์ฃผ์†Œ์— ์žˆ๋Š” ์›นํŽ˜์ด์ง€์˜ ๋‚ด์šฉ์„ ๊ฐ€์ ธ์˜จ๋‹ค. `get` ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ์›นํŽ˜์ด์ง€์— GET์š”์ฒญ์„ ๋ณด๋‚ด๊ณ , ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ์‘๋‹ต์„ webpage ๋ณ€์ˆ˜์— ์ €์žฅํ•œ๋‹ค.

    • ํŒŒ์‹ฑ๋œ html ๋ฌธ์„œ์—์„œ ํŠน์ • ํƒœ๊ทธ๋‚˜ ํด๋ž˜์Šค๋ฅผ ์ฐพ์•„๋‚ด๊ณ  ์ •๋ณด๋ฅผ ์ถ”์ถœํ• ์ˆ˜์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ title, title.string, h1.string์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ๊ฐ ์š”์†Œ์—์„œ ์ •๋ณด๋ฅผ ์ถ”์ถœํ–ˆ๋‹ค.
    • `soup.ul.children` : ์„ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์‹ฑ๋œ HTML๋ฌธ์„œ์—์„œ <ul> ํƒœ๊ทธ์˜ ์ž์‹ ์š”์†Œ์˜ ๋ฌธ์ž์—ด์„ ์ถœ๋ ฅํ•œ๋‹ค.

     

    ๐Ÿ“ ์ •๊ทœ ํ‘œํ˜„์‹

    • `import re` : ํ•ด๋‹น ๋ชจ๋“ˆ์€ ์ •๊ทœ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์ž์—ด์„ ์ฒ˜๋ฆฌํ•œ๋‹ค. 
    • `re.compile("[ou]l")` : ์ •๊ทœ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์—ฌ <ul>, <ol> ํƒœ๊ทธ๋ฅผ ๋ชจ๋‘ ์ฐพ์•„ ์ถœ๋ ฅ
    • `re.compile("h[1-9]")` : <h1> ๋ถ€ํ„ฐ <h9> ๊นŒ์ง€์˜ ๋ชจ๋“  ์ œ๋ชฉ ํƒœ๊ทธ๋ฅผ ์ฐพ์•„ ์ถœ๋ ฅ

     

    ๐Ÿ“ Select() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ CSS ์„ ํƒ์ž๋กœ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ

     

    • BeautifulSoup ์˜ select() ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•˜์—ฌ HTML ํด๋ž˜์Šค๊ฐ€ card-region-name ์ธ ์š”์†Œ๋“ค์„ ์„ ํƒํ•œ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ฐ ์š”์†Œ์—์„œ .get_text()๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ…์ŠคํŠธ๋ฅผ ์ถ”์ถœํ•˜๊ณ  ์ถœ๋ ฅํ•œ๋‹ค.

     

    ๐Ÿ’ญ ์›นํฌ๋กค๋ง : ๋ฐ์ดํ„ฐ ์ถ”์ถœ๊ณผ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ํ™œ์šฉ

     

    ํฌ๋กค๋ง์€ ์›น ํŽ˜์ด์ง€์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœํ•˜๋Š” ์ž‘์—…์ด๋‹ค. ๋‹น๊ทผ๋งˆ์ผ“๊ณผ ๊ฐ™์€ ์‚ฌ์ดํŠธ์—์„œ ์›ํ•˜๋Š” ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด ํฌ๋กค๋ง์ด ํ•„์š”ํ•˜๋‹ค. ์ด์ฒ˜๋Ÿผ ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ API๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์›น ํฌ๋กค๋ง์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•˜๋ฉด ๋œ๋‹ค.

     

    ํฌ๋กค๋ง์„ ํ†ตํ•ด ์„œ์šธ์— ์žˆ๋Š” ์ธ๊ธฐ์žˆ๋Š” ์ƒํ’ˆ์„ ๋ณด๊ณ ์‹ถ๋‹ค๋ฉด ํ•ด๋‹น ์›นํŽ˜์ด์ง€์˜ HTML์„ ๊ฐ€์ ธ์™€์„œ BeautifulSoup์™€ ๊ฐ™์€ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›ํ•˜๋Š” ์ •๋ณด๋ฅผ ์ถ”์ถœํ• ์ˆ˜ ์žˆ๋‹ค.

     

    ํฌ๋กค๋ง์„ ์ง„ํ–‰ํ•  ๋•Œ๋Š” ๊ฐœ๋ฐœ์ž ๋„๊ตฌ(F12)๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ์œ ์šฉํ•˜๋‹ค. ๋ธŒ๋ผ์šฐ์ €์˜ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์—ด๊ณ  ์š”์†Œ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋ฉด ํƒœ๊ทธ์˜ ๊ตฌ์กฐ์™€ ํด๋ž˜์Šค๋ฅผ ํ™•์ธํ• ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์–ด๋–ค ํƒœ๊ทธ๋ฅผ ์ฐพ์•„๋‚ด์•ผ ํ•˜๋Š”์ง€ ํŒŒ์•…ํ• ์ˆ˜ ์žˆ๋‹ค.

     

    ์š”์•ฝํ•˜์ž๋ฉด, ํฌ๋กค๋ง์€ ์›น ํŽ˜์ด์ง€์—์„œ ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๊ฐœ๋ฐœ์ž๋„๊ตฌ๋ฅผ ์ด์šฉํ•ด์„œ ์›นํŽ˜์ด์ง€์˜ ๊ตฌ์กฐ๋ฅผ ํŒŒ์•…ํ•˜๊ณ  BeautifulSoup์™€ ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœํ• ์ˆ˜ ์žˆ๋‹ค.