
Web Scraping
/robot.txt 을 붙이면 소유자가 제출한 txt 파일 확인 가능robot.txt에 crawl-delay가 설정된 경우 준수하기soup = BeautifulSoup(contents, "언어.parser")
lxml 패키지도 임포트 해야 함)🏗️ website.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Angela's Personal Site</title>
</head>
<body>
…
</body>
</html>
⌨️ main.py
######################## 기본 설정 ###########################
from bs4 import BeautifulSoup
# html 파일 오픈
with open("website.html") as file:
contents = file.read()
# 수프 만들기
soup = BeautifulSoup(contents, "html.parser")
###########################################################
# HTML 코드인 객체를 파이썬 객체로 가져올 수 있음
print(soup) # HTML 파일 전체 가져오기
print(soup.prettify()) # HTML 파일을 들여쓰기해서 가져오기
print(soup.title) # 태그 가져오기
print(soup.title.name) # 태그의 이름 가져오기
print(soup.title.string) # 태그의 문자열 가져오기
print(soup.a) # 첫 번째 앵커 태그 가져오기
print(soup.p) # 첫 번째 단락 가져오기
[ 출력 결과 ]
# HTML 파일 전체 가져오기
<!DOCTYPE html>
<html>
<head>
…
</html>
# HTML 파일을 들여쓰기해서 가져오기
<!DOCTYPE html>
<html>
<head>
…
</html>
# 태그 가져오기
<title>Angela's Personal Site</title>
# 태그의 이름 가져오기
title
# 태그의 문자열 가져오기
Angela's Personal Site
# 첫 번째 앵커 태그 가져오기
<a href="url주소">The App Brewery</a>
# 첫 번째 단락 가져오기
<p><em>Founder of <strong><a href="url주소">The App Brewery</a></strong>.</em></p>
name(태그 이름), attrs(속성 이름) 등과 일치하는
soup.find("span").find("a") 처럼 반복 호출 가능 tag.getText() : 가져온 태그 내에서 텍스트만 추출(리스트에는 사용 불가)
tag.get( name, attrs, ... ) : 가져온 태그 내에서 괄호 안의 조건과 같은 항목만 추출
# 모든 앵커 태그
all_anchor_tags = soup.find_all(name="a")
print(all_anchor_tags)
# 앵커 태그의 텍스트만 가져오기
for tag in all_anchor_tags:
print(tag.getText())
# 앵커 태그의 url만 가져오기
for tag in all_anchor_tags:
print(tag.get("href"))
# 조건에 맞는 첫 번째 항목만 가져오기
# (class는 파이썬 예약어이기 때문에 뒤에 _를 붙여서 구분)
print(soup.find(name="h3", class_="heading"))
[ 출력 결과 ]
[<a href="https://www.appbrewery.co/">The App Brewery</a>, ……, ……]
The App Brewery
My Hobbies
Contact Me
https://www.appbrewery.co/
https://angelabauer.github.io/cv/hobbies.html
https://angelabauer.github.io/cv/contact-me.html
<h3 class="heading">Books and Teaching</h3>
CSS 선택기를 사용하여 원하는 요소의 범위를 좁혀가며 찾는 방법
요소 요소…로 입력 (요소 사이에 공백)class=값1 값2처럼 여러 값이 있을 경우 .값1.값2로 공백 없이 붙이기)company_url = soup.select_one(selector="p a")
print(company_url)
name = soup.select_one(selector="#name")
print(name)
headings = soup.select(".heading")
print(headings)
[ 출력 결과 ]
<a href="https://www.appbrewery.co/">The App Brewery</a>
<h1 id="name">Angela Yu</h1>
[<h3 class="heading">Books and Teaching</h3>, <h3 class="heading">Other Pages</h3>]
requests 모듈로 웹사이트의 실시간 데이터 스크래핑하기
먼저 Hacker News에서 각 항목의 제목과 링크 가져오기
↓
크롬 브라우저에서 스크래핑하려는 부분의 HTML 코드 확인
↓
먼저 첫 번째 항목만 추출하여 원하는 데이터가 출력되는지 확인
from bs4 import BeautifulSoup
import requests
response = requests.get("https://news.ycombinator.com/news")
yc_web_page = response.text
soup = BeautifulSoup(yc_web_page, "html.parser")
article_tag = soup.find(name="span", class_="titleline").find(name="a")
article_text = article_tag.getText()
article_link = article_tag.get("href")
article_upvotes = soup.find(name="span", class_="score").getText()
↓
확인 후 모든 항목을 추출하는 것으로 변경
from bs4 import BeautifulSoup
import requests
response = requests.get("https://news.ycombinator.com/news")
yc_web_page = response.text
soup = BeautifulSoup(yc_web_page, "html.parser")
articles = soup.find_all(name="span", class_="titleline")
article_texts = []
article_links = []
for article in articles:
article_tag = article.find(name="a")
text = article_tag.getText()
article_texts.append(text)
link = article_tag.get("href")
if "https://" not in link:
link = "https://news.ycombinator.com/" + link
article_links.append(link)
article_upvotes = [int(score.getText().split()[0]) for score in soup.find_all(name="span", class_="score")]
print(article_texts)
print(article_links)
print(article_upvotes)
↓ 추천수가 가장 많은 기사 찾기
…
largest_number = max(article_upvotes)
largest_index = article_upvotes.index(largest_number)
print(article_texts[largest_index])
print(article_links[largest_index])
웹사이트에서 꼭 봐야할 영화 100선 목록을 스크랩하기
🔍 유의 사항
- Empire's 100 Greatest Movie Of All Times에서 100개의 영화를 스크랩하기
📄movies.txt생성 후 영화 목록 작성- 웹사이트에서는 목록이 100부터 시작하지만 파일에서는 1부터 시작하도록 변경하기
⌨️ main.py
import requests
from bs4 import BeautifulSoup
URL = "https://web.archive.org/web/20200518073855/https://www.empireonline.com/movies/features/best-movies-2/"
response = requests.get(URL)
website_html = response.text
soup = BeautifulSoup(website_html, "html.parser")
all_movies = [movie.getText() for movie in soup.find_all(name="h3", class_="title")]
movies = all_movies[::-1]
with open("movies.txt", "w") as file:
for movie in movies:
file.write(f"{movie}\n")
📄movies.txt
1) The Godfather
2) The Empire Strikes Back
3) The Dark Knight
…
100) Stand By Me