2 분 소요

[BeautifulSoup] HTML의 Locator로 원하는 요소 찾기

1. HTML의 Locator로 원하는 요소 찾기

BeautifulSoup을 이용해서 더 정확하게 우리가 원하는 정보를 가져오는 방법을 학습해봅시다.

blog2

id와 class

태그는 자신의 이름뿐만 아니라 고유한 속성 또한 가질 수 있습니다. 이 중에서 idclass는 Locator로서 특정 태그를 지칭하는 데 사용됩니다.

  • tagname: 태그의 이름
  • id: 하나의 고유 태그를 가리키는 라벨
  • class: 여러 태그를 묶는 라벨
<p>This element has only tagname</p>
<p id="target">This element has tagname and id</p>
<p class="targets">This element has tagname and class</p>

id를 이용해서 요소 가져오기

id는 요소 하나를 지칭하는 특별한 별명입니다. id를 이용하면 해당하는 태그 단 하나를 쉽게 가져올 수 있습니다.

# 스크래핑에 필요한 라이브러리를 불러옵니다.
import requests
from bs4 import BeautifulSoup

# 또 다른 연습 사이트를 이용해봅시다.
url = "http://example.python-scraping.com/"
res = requests.get(url)
soup = BeautifulSoup(res.text, "html.parser")

# id 없이 div 태그를 찾아봅시다.
divs = soup.find_all("div")
print("All div tags:", divs)

# id가 results인 div 태그를 찾아봅시다.
results_div = soup.find("div", id="results")
print("Div with id 'results':", results_div)

class를 이용해서 요소(들) 가져오기

class는 유사한 요소들을 구분짓는 별명입니다. class를 이용하면 해당하는 태그 단 하나를 쉽게 가져올 수 있습니다.

# class가 "page-header"인 div 태그를 찾아봅시다.
header_div = soup.find("div", class_="page-header")
print("Div with class 'page-header':", header_div)

# 위 결과에서 text 값을 깔끔하게 가져와봅시다.
header_text = header_div.text.strip()
print("Header text:", header_text)

2. BeautifulSoup을 이용해 원하는 요소 가져오기 II - Hashcode 질문 가져오기

BeautifulSoup을 이용해서 Hashcode 질문 내용을 스크래핑해봅시다. 스크래핑하고자 하는 사이트는 Hashcode입니다.

스크래핑 원칙

  1. 과도한 요청을 보내지 않습니다.
  2. 받아온 정보 활용에 유의합니다.

User-Agent 추가하기

아래와 같이 User-Agent를 설정하여 요청을 보냅니다.

user_agent = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36"
}

질문 내용 스크래핑하기

필요한 라이브러리를 불러온 후, 요청을 진행합니다.

import requests
from bs4 import BeautifulSoup

res = requests.get("https://hashcode.co.kr/", headers=user_agent)
soup = BeautifulSoup(res.text, "html.parser")

# 질문의 빈도를 체크하는 dict를 만든 후, 빈도를 체크합니다.
questions = soup.find_all("li", "question-list-item")
for q in questions:
    print(q.find("div", "question").find("div", "top").h4.text)

예시 질문

  • 아나콘다 설치 오류/파이썬 제거 안됨(살려주세요ㅜㅜ)
  • 네이버 스토어 리뷰 크롤링 오류
  • 중력 물리엔진 질문에 오류가 발생하는데 이유를 모르겠어요
  • 네이버 지도 리뷰 크롤링 문제
  • DBMS에서 wait-die에 대한 질문입니다.

Bonus: 페이지네이션(Pagination)

페이지네이션은 많은 정보를 인덱스로 구분하는 기법입니다. 저희가 진행하고 있는 사이트는 Query String을 통해서 이를 구분하는데요, 이를 감안해서 다시 한번 진행해봅시다.

import time

# Pagination이 되어있는 질문 리스트의 제목을 모두 가져와봅시다.
for i in range(1, 6):
    res = requests.get(f"https://hashcode.co.kr/?page={i}", headers=user_agent)
    soup = BeautifulSoup(res.text, "html.parser")
    questions = soup.find_all("li", "question-list-item")
    
    for q in questions:
        print(q.find("div", "question").find("div", "top").h4.text)
    
    # 과도한 요청을 방지하기 위해 1초마다 요청을 보냅니다.
    time.sleep(1)

예시 질문

  • AWS EC2 ssh 접속 에러
  • 리액트 검색 기능 구현
  • Jupyter notebook 기본 포트 8888이 안 열립니다.

댓글남기기