본문 바로가기

Crawling

웹 페이지 스크레이핑

meta 태그에서 인코딩 방식 추출하기

import sys
from urllib.request import urlopen

# urlopen() 함수는 HTTPResponse 자료형의 객체를 반환합니다.
f = urlopen('http://www.hanbit.co.kr/store/books/full_book_list.html')
# bytes 자료형의 응답 본문을 일단 변수에 저장합니다.
bytes_content = f.read()  
bytes_content
# charset은 HTML의 앞부분에 적혀 있는 경우가 많으므로 응답 본문의 앞부분 1024바이트를 ASCII 문자로 디코딩해 둡니다.
# ASCII 범위 이위의 문자는 U+FFFD(REPLACEMENT CHARACTER)로 변환되어 예외가 발생하지 않습니다.
scanned_text = bytes_content[:1024].decode('ascii', errors='replace')
scanned_text
import re

# 디코딩한 문자열에서 정규 표현식으로 charset 값을 추출합니다.
match = re.search('charset=["\']?([\w-]+)', scanned_text)
match
# ["\']?  : 홑따옴표나 쌍따옴표 0 또는 1번 반복
# ([\w-]+)  : 알파벳,숫자,언더바(_),대쉬(-) 한 번 이상 반복 그룹
# match(charset)가 존재하는 경우
if match:
    encoding = match.group(1)
else:
    # charset이 명시돼 있지 않으면 UTF-8을 사용합니다.
    encoding = 'utf-8'
# 추출한 인코딩을 표준 오류에 출력합니다.
print('encoding:', encoding, file=sys.stderr)
# 추출한 인코딩으로 다시 디코딩합니다.
text_html = bytes_content.decode(encoding)
# 응답 본문을 표준 출력에 출력합니다.
print(text_html)
html_file = open('dp.html', 'w')
html_file.write(text_html)
html_file.close()

 

스크래핑한 웹 페이지에서 데이터 추출하기

import re
from html import unescape

# 이전 절에서 다운로드한 파일을 열고 html이라는 변수에 저장합니다.
with open('dp.html') as f:
    html = f.read()
html
# re.findall()을 사용해 도서 하나에 해당하는 HTML을 추출합니다.
for partial_html in re.findall('<td class="left"><a.*?</td>', html, re.DOTALL):
    # 도서의 URL을 추출합니다.
    url = re.search('<a href="(.*?)">', partial_html).group(1)
    url = 'http://www.hanbit.co.kr' + url
    # 태그를 제거해서 도서의 제목을 추출합니다.
    title = re.sub(r'<.*?>', '', partial_html)
    title = unescape(title)
    print('url:', url)
    print('title:', title)
    print('---')