English Linguistics 논문 abstract 가져오기

Junha Kim·2021년 1월 3일
0

Crawling

목록 보기
3/4

학술제를 준비하며, Linguistics 관련 논문 Abstract 데이터가 필요했다. 좋은 사이트를 찾기 위해서 정말 많이 찾아보았지만, 아래의 사이트가 그나마 괜찮았다.


크롤링 사이트

lingbuzz - archive of linguistics articles


URL 구조 및 설명


카테고리 페이지

  • 논문을 담고있는 테이블은 html 중 2번째 테이블, table > tbody > tr 의 td 첫번째 자식

    tables = html.select('table')
    temp_table = tables[2]
    paper_table = temp_table.select_one('table')
  • td 안에 또 table이 존재하고, 그 안의 tr들이 각 논문을 담고 있다.

    rows = paper_table.select('tr')
  • tr 안에 td 중 마지막 요소가 논문 detail 페이지의 href를 가지고 있다.

    for row in rows:
    	  detail_url = row.select('td')[-1].select_one("a")['href']
    	  detail_page = requests.get(base + detail_url)
    	  detail_page_html = bs(detail_page.text, 'html.parser')

Detail Page

  • 논문 제목 : center > font > a 태그

    • bs4객체.제거할태그.extract() : 제거 + 해당 태그를 return

      title = detail_page_html.select_one("center").font.extract().text
  • 논문 저자 : center > a 태그

    author_list = detail_page_html.select("center a")
    
    # author 추출
    author = ''
    for person in author_list:
        author += person.text + ', '
    author = author.strip(', ')
  • 논문 내용 : body태그 내에 아무 태그 없이 존재 → 나머지 태그를 제거해야됨

    • bs4객체.제거할태그.decompose() : return 값 없이 태그 제거

      # abstract 만을 남겨놓기 위한 태그 삭제
      detail_page_html.center.decompose()
      detail_page_html.title.decompose()
      detail_page_html.table.decompose()
      detail_page_html.table.decompose()
      detail_page_html.p.decompose()
      
      abstract = detail_page_html.text

기타

논문 Abstract에 프랑스어와 같은 인코딩 없이 들어갈 수 없는 문자들이 있어서 utf-8-sig로 인코딩을 해주었다. 하지만 utf-8로도 인코딩이 불가한 특수문자들이 존재했다. 예를 들어 작은따옴표(’), 쌍따옴표(”)과 같은 것들이 일반적으로 쓰는 문자가 아닌 특수문자로 되어있어서 replace를 해주었고, 간혹 text에 JS 코드가 섞인게 있어서 그것 또한 replace를 해주었다.

https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fa31122a9-b058-4d04-8e27-d3f512e06d44%2FUntitled.png?table=block&id=ec9f1884-9e62-468f-9374-e06b68592c14&width=3070&userId=5789effa-edf3-43f5-ad7c-8247a5264b62&cache=v2


전체 코드

import requests
from bs4 import BeautifulSoup as bs

def crawl(cate):
    total = []
    base = 'https://ling.auf.net/'
    'https://ling.auf.net/lingbuzz/_listing?community=Phonology&start=31'
    print(cate)
    print()
    start = 1
    while True:
        base_url = base + "lingbuzz/_listing?community=" + cate + "&start=" + str(start)
        res = requests.get(base_url)
        html = bs(res.text, 'html.parser')

        tables = html.select('table')
        temp_table = tables[2]
        paper_table = temp_table.select_one('table')
        if len(paper_table.text.strip()) == 0:
            break

        rows = paper_table.select('tr')

        for row in rows:
            paper = {'category' : cate}
            detail_url = row.select('td')[-1].select_one("a")['href']
            detail_page = requests.get(base + detail_url)
            detail_page_html = bs(detail_page.text, 'html.parser')

            # title 추출 및 제거
            title = detail_page_html.select_one("center").font.extract().text
            print(cate, len(total), title)
            paper['title'] = title
            author_list = detail_page_html.select("center a")

            # author 추출
            author = ''
            for person in author_list:
                author += person.text + ', '
            author = author.strip(', ')
            paper['author'] = author
						
						# abstract 만을 남겨놓기 위한 태그 삭제
            detail_page_html.center.decompose()
            detail_page_html.title.decompose()
            detail_page_html.table.decompose()
            detail_page_html.table.decompose()
            detail_page_html.p.decompose()

            abstract = detail_page_html.text.replace('’',"'").replace('“','"').replace("혻혻","").replace("/*<![CDATA[*/function onLoad(){};/*]]>*/", "").replace('”', '"').replace("—","-").replace("‘","'").strip()
            paper['abstract'] = abstract
            paper['url'] = base + detail_url
            total.append(paper)
				# 시작페이지 수 증가
        if start == 1:
            start += 30
        else:
            start += 100
		# csv로 저장
    import pandas as pd
    data = pd.DataFrame(total)
    data.to_csv(cate + ".csv", encoding='utf-16')

# 4개 토픽 스레드로 처리
import threading

category = ['phonology', 'semantics', 'syntax', 'morphology']

thread_count = len(category)
threads = []

# 새로운 스레드 생성/실행 후 스레드 리스트에 추가
for i in range(thread_count):
    thread = threading.Thread(target=crawl, args=( (category[i], ) ))
    thread.start()
    threads.append(thread)

# 메인 스레드는 각 스레드의 작업이 모두 끝날 때까지 대기
for thread in threads:
    thread.join()

0개의 댓글