링크에 있는 컨텐츠를 전부 내려 받는 방법
06 Nov 2017 | PythonPython 3.x 기반의 코드입니다.
상대 경로 사용 방법
소스 코드
from urllib.parse import urljoin baseUrl = "http://snowdeer.github.io/blog/categories/" print(urljoin(baseUrl, "/python/2017/05/01/difference-between-python-2-7-x-and-python-3-x/")) print(urljoin(baseUrl, "/python/2017/11/03/download-file-from-network/")) print(urljoin(baseUrl, "/python/2017/11/04/get-html-body/"))
실행 결과
http://snowdeer.github.io/python/2017/05/01/difference-between-python-2-7-x-and-python-3-x/
http://snowdeer.github.io/python/2017/11/03/download-file-from-network/
http://snowdeer.github.io/python/2017/11/04/get-html-body/
위의 예제와 같이 baseUrl
변수를 기본 URL 아래의 하위 카테고리 경로까지 지정했음에도, urljoin
을 이용해서 만들어진 상대 경로들은 올바르게 만들어지는 것을 확인할 수 있습니다.
재귀적으로 하위 링크들의 컨텐츠를 모두 내려받는 코드
아래의 코드를 활용하면 특정 웹 페이지의 하위 링크들을 재귀적으로 방문하면서 모두 저장하게 됩니다. 단, BeautifulSoup
라이브러리를 이용하여 웹페이지 파싱을 통해 하위 링크들을 검색하기 때문에 저장하려는 대상 페이지에 따라 파싱 코드를 따로 작성을 해야 합니다.
소스 코드
from bs4 import BeautifulSoup from urllib.request import * from urllib.parse import * from os import makedirs import os.path, time, re # 이미 처리가 끝난 파일인지 확인하기 위한 용도 finished_files = {} # HTML 문서 내부의 링크 추출 def get_links_in_html(html, base): soup = BeautifulSoup(html, "html.parser") links = soup.select("link[rel='stylesheet']") links += soup.select("a[href]") result_list = [] for a in links: href = a.attrs['href'] url = urljoin(base, href) # 링크를 절대 경로로 변환 result_list.append(url) return result_list # URL로부터 파일 다운로드 def download_file(url): out = urlparse(url) file_path = "./" + out.netloc + out.path if re.search(r"/$", file_path): file_path += "index.html" folder_path = os.path.dirname(file_path) if os.path.exists(file_path): return file_path if not os.path.exists(folder_path): print("make folder: ", folder_path) makedirs(folder_path) try: print("download file: ", url) urlretrieve(url, file_path) time.sleep(1) return file_path except: print("download failed: ", url) return None def analyze_html(url, root_url): file_path = download_file(url) if file_path is None: return if file_path in finished_files: return finished_files[file_path] = True print("analyze_html: ", url) html = open(file_path, "r", encoding="utf-8").read() links = get_links_in_html(html, url) for link_url in links: if link_url.find(root_url) != 0: if not re.search(r".css$", link_url): continue if re.search(r".(html|htm)$", link_url): analyze_html(link_url, root_url) continue download_file(link_url) if __name__ == "__main__": url = "https://docs.python.org/3.7/library/" analyze_html(url, url)
실행 결과
make folder: ./docs.python.org/3.7/library
download file: https://docs.python.org/3.7/library/
analyze_html: https://docs.python.org/3.7/library/
make folder: ./docs.python.org/3.7/_static
download file: https://docs.python.org/3.7/_static/pydoctheme.css
download file: https://docs.python.org/3.7/_static/pygments.css