항해 99/사전 기본 스터디

WIL _ 웹스크래핑(크롤링) 기초 / .string .text의 차이

U_D 2022. 2. 24. 17:37
크롤링!이라니 해킹의 시작아닌가!

 

1. 패키지 추가 설치하기(beautifulsoup4)

  • 크롤링을 위한 기본 세팅으로는 파이썬(python)에서 'requests', 'bs4' 패키지 설치
  • 아래 코드 세팅
import requests
from bs4 import BeautifulSoup

# 타겟 URL을 읽어서 HTML를 받아오고,
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('<https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=pnt&date=20210829>',headers=headers)

# HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
# soup이라는 변수에 "파싱 용이해진 html"이 담긴 상태가 됨
# 이제 코딩을 통해 필요한 부분을 추출하면 된다.
soup = BeautifulSoup(data.text, 'html.parser')

#############################
# (입맛에 맞게 코딩)
#############################

 

2. select / select_one의 사용법

  • 네이버 영화 제목 가져오기

1) 원하는 부분에서 마우스 오른쪽 클릭 → 검사

2) 원하는 태그에서 마우스 오른쪽 클릭

3) Copy → Copy selector로 선택자를 복사할 수 있음

import requests
from bs4 import BeautifulSoup

headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=pnt&date=20210829',headers=headers)

soup = BeautifulSoup(data.text, 'html.parser')

#영화 제목 > 검사 > select 복사 > 아래 괄호에 붙여넣기
title = soup.select_one('#old_content > table > tbody > tr:nth-child(2) > td.title > div > a')
print(title) 
#태그안의 텍스트를 찍고 싶을 땐 -> 태그.txt ex. print(title.text)
#태그안의 속성을 찍고 싶을 떈 -> 태그['속성'] ex. print(title['href'])

#다른 영화 제목들을 검사해봐도 동일 반복 구간이 있음
#old_content > table > tbody > tr:nth-child(3) > td.title > div > a 
#old_content > table > tbody > tr:nth-child(4) > td.title > div > a

movies = soup.select('#old_content > table > tbody > tr')

for movie in movies:
    a = movie.select_one('td.title > div > a')
    if a is not None:
        print(a.text)
#페이지내 제목뿐만 아니라 라인의 값인 'NONE'이 딸려와서 그걸 제외하고 불러오는 코드

 

  • 네이버 영화 순위/제목/평점 같이 가져오기
import requests
from bs4 import BeautifulSoup

headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=pnt&date=20210829',headers=headers)

soup = BeautifulSoup(data.text, 'html.parser')

movies = soup.select('#old_content > table > tbody > tr')

for movie in movies:
    a = movie.select_one('td.title > div > a')
    if a is not None:
        title = a.text
        rank = movie.select_one('td:nth-child(1) > img')
        star = movie.select_one('td.point')
        print(rank["alt"], title, star.text)
        
#형태는 다르지만 같은 결과
for movie in movies:
    a = movie.select_one('td.title > div > a')
    if a is not None:
        title = a.text
        num = movie.select_one('td:nth-child(1) > img')['alt']
        star = movie.select_one('td.point').text
        print(num, title, star)

 

※문자열을 가져오는게 .text 말고 다른게 있나해서 검색하다 .string을 발견해서 차이점을 찾아보았다.

  -> 결과의 차이는 알겠는데 설명을 완벽히 이해하지는 못했다..

하위 HTML 태그를 추출한다고 가정하면

<td>some text</td>
<td></td>
<td><p>more text</p></td>
<td>even <p>more text</p></td>

.string
some text
None
more text
None

.text
some text
more text
even more text

.string은 태그 하위에 문자열을 객체화한다는데 잘 이해가 되지않는다..문자열이 없다면 빈칸이 아니라 없는 객체라고 표현을 하는 형태로 이해했다. 즉, 문자열이 없으면 None 을 반환한다.

.text는 하위 자식태그의 텍스트까지 문자열로 반환한다고 한다.