티스토리 뷰

각 CVE의 정보와 CVSS Score를 담은 리스트를 만들고 싶어 시작하게 되었다.

CVE Details에서 점수별로 분류하여 확인은 가능하지만, 전체 리스트를 저장하는 기능은 찾지 못했다.

그래서 python BeautifulSoup를 이용하여 크롤링하고 저장하고 싶은 데이터만 파싱하여 엑셀 형태로 저장하는 코드를 작성하게 되었다.

 

CVE Details에서 1999-01-01 ~ 2021-12-14 까지의 CVE의 CVSS Score를 확인하면 다음과 같은 결과 페이지가 나온다.

 

Score가 총 10단계로 구분되어 있으며, 해당 점수대의 CVE 목록 확인이 가능하다.

 

URL에 page 번호와 Score 범위인 cvssscoremin, cvssscoremax 파라미터가 전달되며, 이를 증가시켜 점수대 별로 CVE 목록을 파싱해오기로 했다.

 

파싱 전에 테이블 구조를 살펴보았다.

class가 searchresults sortable인 테이블 안에 여러개의 tr로 구성되어 있다.

 

첫번째 tr에는 테이블 컬럼명이 담겨있어 파싱에선 제외하기로 하였다.

 

그 이후엔 CVE 정보가 담긴 tr과 해당 CVE에 대한 summary가 담긴 tr이 반복된다.

 

CVE 정보를 파싱할 때 리스트에 임시로 저장해두고, summary 파싱하는 부분에서 리스트에 담겨있는 CVE정보와 summary를 엑셀 시트에 저장하는 형태로 구현하기로 했다.

 

완성된 코드는 아래와 같다.

from bs4 import BeautifulSoup
import requests
import openpyxl

wb = openpyxl.Workbook()
sheet = wb.active
sheet.append(["idx","CVE ID","Vulnerability Type","Score","Summary"])

# 9페이지까지 있는걸 확인하고 작성함
# 추후 페이지 번호도 자동으로 파싱하도록 수정 필요
for i in range(1,10):
    # 파싱할 url (스코어가 0.0~0.99인 cvss 리스트의 페이지 번호를 증가시켜줌)
    page = requests.get("https://www.cvedetails.com/vulnerability-list.php?page="+str(i)+"&cvssscoremin=0&cvssscoremax=0.99&trc=447&sha=8cc1914b56963dbe370dba9383f2100c35cf3354")
    html = page.text

    soup = BeautifulSoup(html, 'html.parser')

    # cvss 정보가 담긴 테이블만 가져옴
    table = soup.find('table', {'class': 'searchresults sortable'})
    trs = table.find_all('tr')

    # 추후 cve 상세정보와 summary가 있는 tr을 구분하도록 수정 필요
    #trs_cve = table.find_all('tr', {'class': 'srrowns'})

    for idx, tr in enumerate(trs):
        tds = tr.find_all('td')

        # 0번째에는 컬럼명이 담겨있기 때문에 버림
        if idx==0:
            continue
        elif idx%2==1:
            sequence = tds[0].text.strip()
            cve_id = tds[1].text.strip()
            vuln_type = tds[4].text.strip()
            score = tds[7].text.strip()
            data = [sequence, cve_id, vuln_type, score] # summary와 합치기 위한 리스트 이 로직 지저분해서 맘에 안든다
            #sheet.append([sequence, cve_id, vuln_type, score])
            #print(sequence, cve_id, vuln_type, score)
        else:
            summary = tds[0].text.strip()
            sheet.append([data[0],data[1],data[2],data[3],summary]) # cve 상세정보 리스트와 summary를 엑셀 시트에 삽입
            data.clear() # 다음 정보를 저장하기 위해 리스트 초기화
            #print(summary)

    print(str(i)+" page parsing ended")

# 파싱 데이터 엑셀로 저장
wb.save("test.xlsx")

 

코드 실행 시 다음과 같이 엑셀에 저장되는 것을 볼 수 있다.

 

추후, Score 별 리스트 메인 페이지에서 cve 총 갯수인 trc 파라미터를 이용하여 총 페이지 수를 계산하고 자동으로 파싱해오도록 수정이 필요하다.

 

 

 

(추가)

총 갯수인 trc를 파싱하여 페이지 수를 계산하고 자동으로 파싱해오도록 해보았다.

 

점수대 별 제일 첫페이지에 상단과 하단에서 trc 값을 확인할 수 있다.

id가 pagingt, pagingb 인 idv 태그 내에 존재하는데, pagingt를 파싱하려 하니 안에 속해있는 태그들이 나오질 않았다.

for i in range(0,2):
    i_max = i+0.99
    if i==9:
        i_max=10;
    start_page = requests.get("https://www.cvedetails.com/vulnerability-list/cvssscoremin-"+str(i)+"/cvssscoremax-"+str(i_max)+"/vulnerabilities.html")
    html = start_page.text

    soup = BeautifulSoup(html, 'html.parser')

    # 점수대 별 첫번째 페이지에서 trc 값 파싱하여 최대 페이지 수 계산
    div = soup.find('div', {'id': 'pagingt'})
    print(div)

 

결과값

<div class="paging" id="pagingt" style="display:none; clear:both;"></div>
<div class="paging" id="pagingt" style="display:none; clear:both;"></div>

 

확인해보니 pagingt는 동적으로 구현되어 있어 div 태그 내에 있는 다른 태그들을 파싱해오지 못하는 것이었다.

그래서 정적으로 구현되어 있는 pagingb를 파싱하였더니 안에 있는 태그들까지 가져오는 것을 확인할 수 있었다.

<div class="paging" id="pagingb">
	Total number of vulnerabilities : <b>492</b>  
Page :
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=1&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=0&amp;cvssscoremax=0.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=492&amp;sha=8cc1914b56963dbe370dba9383f2100c35cf3354" title="Go to page 1">1</a>
(This Page)<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=2&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=0&amp;cvssscoremax=0.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=492&amp;sha=8cc1914b56963dbe370dba9383f2100c35cf3354" title="Go to page 2">2</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=3&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=0&amp;cvssscoremax=0.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=492&amp;sha=8cc1914b56963dbe370dba9383f2100c35cf3354" title="Go to page 3">3</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=4&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=0&amp;cvssscoremax=0.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=492&amp;sha=8cc1914b56963dbe370dba9383f2100c35cf3354" title="Go to page 4">4</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=5&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=0&amp;cvssscoremax=0.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=492&amp;sha=8cc1914b56963dbe370dba9383f2100c35cf3354" title="Go to page 5">5</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=6&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=0&amp;cvssscoremax=0.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=492&amp;sha=8cc1914b56963dbe370dba9383f2100c35cf3354" title="Go to page 6">6</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=7&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=0&amp;cvssscoremax=0.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=492&amp;sha=8cc1914b56963dbe370dba9383f2100c35cf3354" title="Go to page 7">7</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=8&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=0&amp;cvssscoremax=0.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=492&amp;sha=8cc1914b56963dbe370dba9383f2100c35cf3354" title="Go to page 8">8</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=9&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=0&amp;cvssscoremax=0.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=492&amp;sha=8cc1914b56963dbe370dba9383f2100c35cf3354" title="Go to page 9">9</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=10&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=0&amp;cvssscoremax=0.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=492&amp;sha=8cc1914b56963dbe370dba9383f2100c35cf3354" title="Go to page 10">10</a>
</div>
<div class="paging" id="pagingb">
	Total number of vulnerabilities : <b>1132</b>  
Page :
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=1&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 1">1</a>
(This Page)<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=2&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 2">2</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=3&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 3">3</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=4&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 4">4</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=5&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 5">5</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=6&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 6">6</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=7&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 7">7</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=8&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 8">8</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=9&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 9">9</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=10&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 10">10</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=11&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 11">11</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=12&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 12">12</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=13&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 13">13</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=14&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 14">14</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=15&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 15">15</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=16&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 16">16</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=17&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 17">17</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=18&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 18">18</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=19&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 19">19</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=20&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 20">20</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=21&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 21">21</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=22&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 22">22</a>
<a href="/vulnerability-list.php?vendor_id=0&amp;product_id=0&amp;version_id=0&amp;page=23&amp;hasexp=0&amp;opdos=0&amp;opec=0&amp;opov=0&amp;opcsrf=0&amp;opgpriv=0&amp;opsqli=0&amp;opxss=0&amp;opdirt=0&amp;opmemc=0&amp;ophttprs=0&amp;opbyp=0&amp;opfileinc=0&amp;opginf=0&amp;cvssscoremin=1&amp;cvssscoremax=1.99&amp;year=0&amp;month=0&amp;cweid=0&amp;order=1&amp;trc=1132&amp;sha=2ee333910b0146938c917d67aa60489f458567df" title="Go to page 23">23</a>
</div>

 

b 태그에 있는 trc 값을 파싱하고, 해당 값을 이용하여 전체 페이지 수를 구해보았다.

한 페이지당 50개씩 정렬하므로, 총 갯수를 50으로 나눠 페이지 수를 구해준다.

    div = soup.find('div', {'id': 'pagingb'})
    paging = div.find('b')
    trc = paging.contents[0]
    max_page = math.ceil(int(trc)/50)+1

    print(trc, max_page)

 

그 다음은 앞서 작성한 각 페이지 크롤링 코드와 합쳐주면 된다.

완성된 코드는 다음과 같다.

from bs4 import BeautifulSoup
import requests
import math
import openpyxl

wb = openpyxl.Workbook()
sheet = wb.active
sheet.append(["idx","CVE ID","Vulnerability Type","Score","Summary"])

# 각 점수대 첫번째 페이지에서 trc 값 파싱하기 위함
# 점수 대 별 url 접속하여 html 크롤링
for i in range(0,10):
    i_max = i+0.99
    if i==9:
        i_max=10;
    start_page = requests.get("https://www.cvedetails.com/vulnerability-list/cvssscoremin-"+str(i)+"/cvssscoremax-"+str(i_max)+"/vulnerabilities.html")
    html = start_page.text

    soup = BeautifulSoup(html, 'html.parser')

    # 점수대 별 첫번째 페이지에서 trc 값 파싱하여 최대 페이지 수 계산
    div = soup.find('div', {'id': 'pagingb'})
    paging = div.find('b')
    trc = paging.contents[0]
    max_page = math.ceil(int(trc)/50)+1

    print("------------- "+str(i) + "-" + str(i_max) +" score crawling start (total: "+str(max_page-1)+" page) -------------")

    # 점수대 별 각 페이지 접속하여 데이터 크롤링
    for j in range(1,max_page):
        page = requests.get("https://www.cvedetails.com/vulnerability-list.php?page="+str(j)+"&cvssscoremin="+str(i)+"&cvssscoremax="+str(i_max)+"&trc="+str(max_page)+"&sha=8cc1914b56963dbe370dba9383f2100c35cf3354")
        #print("https://www.cvedetails.com/vulnerability-list.php?page="+str(j)+"&cvssscoremin="+str(i)+"&cvssscoremax="+str(i_max)+"&trc="+str(trc)+"&sha=8cc1914b56963dbe370dba9383f2100c35cf3354")

        html = page.text

        soup = BeautifulSoup(html, 'html.parser')

        # cvss 정보가 담긴 테이블만 가져옴
        table = soup.find('table', {'class': 'searchresults sortable'})
        #print(table)

        trs = table.find_all('tr')

        for idx, tr in enumerate(trs):
            tds = tr.find_all('td')

            # 0번째에는 컬럼명이 담겨있기 때문에 버림
            if idx == 0:
                continue
            elif idx % 2 == 1:
                sequence = tds[0].text.strip()
                cve_id = tds[1].text.strip()
                vuln_type = tds[4].text.strip()
                score = tds[7].text.strip()
                data = [sequence, cve_id, vuln_type, score]  # summary와 합치기 위한 리스트 이 로직 지저분해서 맘에 안든다
                # sheet.append([sequence, cve_id, vuln_type, score])
                # print(sequence, cve_id, vuln_type, score)
            else:
                summary = tds[0].text.strip()
                sheet.append([data[0], data[1], data[2], data[3], summary])  # cve 상세정보 리스트와 summary를 엑셀 시트에 삽입
                data.clear()  # 다음 정보를 저장하기 위해 리스트 초기화
                # print(summary)

        print(str(j)+" page parsing ended")

    # 파싱 데이터 엑셀로 저장
    wb.save("test.xlsx")
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday