본문 바로가기

Python

[Python] 파이썬로 ArXiv 크롤링하기

pyArXiv 0.0.3이후로는 이하 블로그 글과 구조가 많이 달라졌습니다...


파이썬은 urllib, bs4.BeautifulSoup, requests같이 크롤링을 위한 라이브러리를 다수 제공한다. 오늘은 간단히 ArXiv 파서를 만들어 보면서 얻었던 크롤링 경험을 포스팅 해보자 한다. 




문제의 시작은 ArXiv 논문 다운로드에서 출발했다. ArXiv는 논문 번호로 조회와 다운로드가 가능하다. 하지만 다운로드 할때 논문 이름 대신 논문 번호로 pdf이름이 받아진다. 결국 논문 정리할 때 일일이 열어보고 아 이거 아니네 하는일이 빈번해서 받을때 논문 이름으로 다운받게 해주는 파이썬 크롤링 패키지를 만들기로 했다.


pyArXiv 패키지는 두개의 메소드를 가진다. 하나는 논문 번호로 논문 정보를 찾는 query 메소드이고 다른 하나는 논문 정보를 인자로 받아  논문을 논문 이름을 가진 pdf 파일로 다운로드하는 download 메소드이다.


먼저 query 메소드를 살펴보자. 

1. query method

일단 query 메소드는 인자로 받은 논문  번호를 이용해 다음의 코드로 제목이 포함된 논문 정보 페이지를 받아온다.

url = "https://arxiv.org/abs/{}".format(paper_id)
html = requests.get(url)

그 다음에는 불러온 논문 정보 페이지가 200을 반환한 성공적인 조회인지 판별하기 위해 if 문을 추가하여 검증한다.

if html.status_code != 200:
return ValueError

requests를 통해 성공적인 조회가 완료되었다면 이제 받아온 페이지에서 BeautifulSoup을 이용해 제목만을 뽑아오는 html 파싱을 수행해야 한다. 파싱 코드는 여러 줄로 짤 수도 있지만 번거로워서 아래의 단 한줄로 숏코딩했다.

paper_name = str(list(BeautifulSoup(html.text, 'html.parser').find("h1", "title mathjax"))[1])


일부러 숏코딩 해놓은 부분이니 설명하자면 먼저 html의 텍스트 부분을 beautifulsoup의 html 파서로 불러온다. 그 다음 h1 태그 중 title mathjax라는 태그를 가진 요소를 모두 찾는다. 그 다음 이 객체를 리스트로 형변환해서 두번째 요소를 가져온 후 이 두번째 요소를 문자열로 바꾸어 paper_name에 저장하는 코드이다.


조회가 아무 문제 없이 완료되었다면 download 메소드를 위한 dict 객체를 만들어 리턴한다.


query 메소드의 풀 코드는 다음과 같다.




def query(paper_id):

url = "https://arxiv.org/abs/{}".format(paper_id)

  html = requests.get(url)
if html.status_code != 200:
return ValueError


paper_name = str(list(BeautifulSoup(html.text, 'html.parser').find("h1", "title mathjax"))[1])
paper_info = {
"paper_id": paper_id,
"paper_name": paper_name
}
return paper_info


2. download 메소드

다운로드 메소드는 한개의 query 메소드가 만들어 낸 하나의 딕셔너리 변수를 인수로 받아 파일을 다운로드 한다.

{

"paper_id": "1506.01497",

"paper_name": "\nFaster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks"

}


인수로 받게 되는 dict 변수는 위의 형태를 갖추고 있다.


일단 이 변수를 풀어야 한다 각각 paper_id와 paper_name으로 풀어주자.


paper_name = paper_info["paper_name"][1:] # remove newline character by str slicing

paper_id = paper_info["paper_id"]


이제 urllib을 사용하여 pdf 파일을 받아오자.


url = "https://arxiv.org/pdf/{}.pdf".format(paper_id)

pdf_name = "{}.pdf".format(paper_name).replace(' ', '_').replace(':', '_')


urllib.request.urlretrieve(url, "{}".format(pdf_name))


urlretrive 함수는 지정된 url에서 지정한 이름으로 파일을 받아오게 된다. 


download 메소드의 풀 코드는 다음과 같다


def download(paper_info):

paper_name = paper_info["paper_name"][1:] # remove newline character by str slicing

paper_id = paper_info["paper_id"]

url = "https://arxiv.org/pdf/{}.pdf".format(paper_id)

pdf_name = "{}.pdf".format(paper_name).replace(' ', '_').replace(':', '_')

urllib.request.urlretrieve(url, "{}".format(pdf_name))



이로써 ArrXiv에서 코드로 논문 정보를 로딩하고 논문 정보로 파일을 논문 이름으로 바꾸어 다운로드하는 패키지를 완성했다. 


이 메소드들은 improved_arxiv란 이름으로 pypi에 업로드 되어 있다. 다음은 improved_arxiv를 설치하여 사용하는 예시이다.


from improved_arxiv.pyArXiv import pyArXiv  

paper_id = 1506.01497  # example id

paper_info = pyArXiv.query(paper_id)
pyArXiv.download(paper_info)



▶GitHub


▶PyPi

'Python' 카테고리의 다른 글

[파이썬] 파이썬의 타입 힌트  (0) 2018.11.15
[Python] pypi에 패키지 업로드하기  (0) 2018.01.29