| 기초개념 |
- 크롤링(crawling)
크롤링은 크롤러가 하는 작업을 부르는 말로, 여러 인터넷 사이트의 페이지(문서, html 등)를 수집해서 분류하는 것이다. 대체로 찾아낸 데이터를 저장한 후 쉽게 찾을 수 있게 인덱싱한다.- 파싱(parsing)
파싱이란 어떤 페이지(문서, html 등)에서 내가 원하는 데이터를 특정 패턴이나 순서로 추출하여 정보를 가공하는 것이다.- 스크래핑(scraping)
스크래핑이란 HTTP를 통해 웹 사이트의 내용을 긁어다 원하는 형태로 가공하는 것이다.
쉽게 말해 웹 사이트의 데이터를 수집하는 모든 작업을 뜻한다.
크롤링도 일종의 스크래핑 기술이라고 할 수 있다.
아래의 3가지 외부 라이브러리를 별도로 다운받아야한다. (MAC OS 터미널 이용)
*주의점: 라이브러리, pip, python등 서로 호환이 잘 되게 버전체크 필수!
import requests
result = requests.get("https://en.wikipedia.org/wiki/Basketball") #http or https 인지 꼭 확인하기!
print(type(result))
import bs4
soup = bs4.BeautifulSoup(result.text, "lxml")
soup.select('title') #html 세부 섹션들 선택 가능함. <div>/<h>/<p>기타등등
soup.select('p')
print(soup.select('title')[0].getText()) # getText덕분에 string code 선택해서 출력
site_paragraphs = soup.select("p")
print(site_paragraphs[1]) #여기서 호출되는 값은 string이 아니고 특별한 Soup 객체이다
print(site_paragraphs[2].getText()) #20번 라인과 달리 여기는 string 출력됨 비교하기!
| 위에서 활용한 위키피디아 농구 페이지에서 원하는 사진을 스크래핑해보기 |
import requests
import bs4
result = requests.get("https://en.wikipedia.org/wiki/Basketball") #http or https 인지 꼭 확인하기!
soup = bs4.BeautifulSoup(result.text, "lxml")
# vsc에서는 print로 명령해줘야 관련 텍스트가 출력됨
(soup.select('.toctext')) #.점을 붙여서 class call을 함! 처음에 점 필수!
(type(soup.select('.toctext')[0]))
#타입결과를 출력해보면 <class 'bs4.element.Tag'> 이렇게 나오는데 이건 기존의 파이썬 타입이 아님 새로운 특별한 객체 타입임을 의미함!
first_item = soup.select('.toctext')[0]
(first_item.text)
basketball = soup.select('.thumbimage')[0]
print(basketball['class'])
print(basketball['src']) #여기서 추출되는 링크 소스 str이 웹스크래핑때 우리가 필요로 하는것!
image_link = requests.get("https://upload.wikimedia.org/wikipedia/commons/thumb/6/69/Canasta_y_tablero_-_0.00.jpg/800px-Canasta_y_tablero_-_0.00.jpg")
# print(image_link.content) #여기서 출력되는 값은 위 이미지 소스의 binary file 이고 컴퓨터만 이해 가능한 언어! 그래서 우리가 이미지 볼려면 따로 파일 오픈명령을 해줘야함!
f = open(/Users/raykim/Desktop/vscode/Udemy/Python3_Bootcamp/'my_basketball_image.jpg', 'wb')
f.write(image_link.content)
f.close()
| 목표: 2개 이상 별점을 받은 책 관련 정보만 따오기 |
import requests
import bs4
base_url = 'https://books.toscrape.com/catalogue/page-{}.html'
res = requests.get(base_url.format(1))
soup = bs4.BeautifulSoup(res.text, "lxml")
# print(soup)
len(soup.select(".product_pod")) #한페이지에 20개 아이템 컨테이너가 있다는 걸 확인한것! #product_pod 클래스에 내가 원하는 개별 아이템 정보들이 다 들어있음
two_stars_titles = []
for n in range(1,51): #=> 총 50쪽 페이지 스크래핑 의미
scrape_url = base_url.format(n)
res = requests.get(scrape_url) #=> 사이트에 스크랩 요청 의미
soup = bs4.BeautifulSoup(res.text, 'lxml') => Soup 기능 활성화
books = soup.select(".product_pod") #product_pod => 책별로 모든 관련 정보를 담고있는 컨테이너 클래스 선택
for book in books:
1안) if 'star-rating Two' in str(book): #=> str으로만 찾기
2안) if len(book.select('.star-rating.Two')) != 0:
#=> 클래스로 찾기
book_title = book.select('a')[1]['title'] #=> 필요한 정보 선택 세부화 과정
two_stars_titles.append(book_title)
#=> 처음 만들어놓은 리스트에 for looping으로 조건 맞는 아이템 추가
print(two_stars_titles)
추후 새로운 책제목 정보가 추가될 빈 리스트 two_starts_titles를 만든 후,
해당 페이지수가 50페이지 임을 확인하고 for 루프의 range를 (1, 51)로 설정함.
rating 정도를 찾기위해서 두가지 방법을 활용가능함.
1안) 빠르지만 결과가 조금 지저분한 문자 그대로의 str을 찾는 법,
2안) 2스타를 암시하는 class('.star-rating.Two')를 지정해서 찾기, 이게 더 깔끔하고 좋은 코드임. 클래스 찾을 때는 꼭 앞에 본 예시처럼 '.'을 붙이기!
"if len(book.select('.star-rating.Two')) != 0:" 해당 if 구절은 별점을 두개 받은 책이 해당 웹페이지에 확실히 존재하기 떄문에 이후 이어지는 논리전개를 확실히 이어주는 역할을 함.
example.select()[][] 포맷을 이용해서 딕셔너리 기능처럼 원하는 값을 세밀하게 호출할 수 있음. 위에서는 책 title 만을 추출하기 위해서 book.select('a')[1]['title']으로 표현함.
example.select("star-rating.Three") 원문 html에 띄어쓰기가 되어있다면 파이썬에서 호출할 때는 띄어쓰기 없이 점으로 그것을 표현해줘야함. 암기할 것!
코딩 결과값: 해당 웹사이트에 있는 복수의 페이지에 있는 수 많은 책제목 정보를 성공적으로 스크래핑함.