Python-Markdown으로 마크다운 문서의 모든 링크 주소 추출하기
Python-Markdown 패키지를 이용해 마크다운 문서에서 모든 링크의 URL 주소를 추출하는 방법을 직접 확장을 만들어서 구현해 보자.
여러 방법이 있을 거라 생각되지만 이번에는 트리프로세서(Treeprocessor) 확장을 구현하는 방식을 보자. 트리프로세서 방식은 마크다운 문서를 파싱해서 HTML로 출력하기 전에 XML 트리 형태로 구축한 데이터를 직접 건드리는 방식을 의미한다.
두 개의 클래스 구현이 필요한데 하나는 Extension
을 상속한 확장 클래스, 다른 하나는 Treeprocessor
를 상속받은 실제로 일을 하는 클래스다.
class _LinkExtractor(Treeprocessor):
def run(self, root):
self.md.links = []
for link in root.findall(".//a"):
href = link.get("href")
if href not in self.md.links:
self.md.links.append(href)
class LinkExtractorExtension(Extension):
def extendMarkdown(self, md):
link_ext = _LinkExtractor(md)
md.treeprocessors.register(link_ext, "link_ext", 20)
_LinkExtractor
가 실제로 트리프로세서를 건드리는 클래스다. 여기서 findall
을 통해 트리에서 모든 a
태그를 찾아서 href
속성 즉 URL 텍스트를 추출해서 리스트로 정리하는 방식이다. 다만 패턴이 조금 특이할 수도 있는데 이 글에서 언급하긴 양이 많기에 직접 관련 레퍼런스 문서를 찾아보자.
LinkExtractorExtension
은 _LinkExtractor
를 Python-Markdown 확장으로 감싸주는 역할의 클래스다. 참고로 설명을 보면 알 수 있겠지만 트리 프로세서에 등록(register)하는 부분에서 20이라는 숫자가 표기되어 있는데 이 숫자는 우선순위다. 자체적으로 개발하는 확장의 처리 순서를 고려해야 한다면 이 우선순위도 주의 깊게 설정해야 할 것이다. 다만 확장이 많지 않다면 별 의미 없는 숫자일 수도 있다.
이렇게 만들어진 확장을 이용해 마크다운 문서를 HTML로 변환하면 Markdown
인스턴스의 links
프로퍼티에 원하는 내용이 들어가게 된다.
md = markdown.Markdown(extensions=[LinkExtractorExtension()])
html = md.convert(text)
print(f"links = {md.links})
당연하겠지만 links
프로퍼티에 들어있는 내용은 URL 주소들의 문자열 리스트다.
이런 식으로 트리프로세서 확장을 이용하면 마크다운 문서를 HTML로 해석한 뒤의 특수한 처리를 어느 정도는 자유롭게 구현할 수 있다.