카테고리 없음

파이썬으로 웹 크롤링하기(4)최대 페이지

터렛짓는다 2021. 3. 23. 17:42

이전 글에서는 페이지 번호를 내가 지정해서 그 페이지까지 크롤링을 하였지만 최대 페이지를 모르는 경우도 있고 여러가지 상황이 있을 수 있다.
다음 소스코드는 최대 페이지까지 크롤링을 진행하여준다.

 

-소스코드

import requests
from bs4 import BeautifulSoup
import pandas as pd
from selenium import webdriver
from openpyxl import Workbook
import os
import time

def get_data(url):
    name = list()
    author = list()
    price = list()

    options = webdriver.ChromeOptions()
    chromedriver_path = (r'C:/Users/eco/Desktop/공부/크롤링/chromedriver.exe')   #chromedrive
    options.add_argument('headless')                                           #크롬드라이버 창 숨기기
    driver = webdriver.Chrome(os.path.join(os.getcwd(), chromedriver_path), options=options)
    driver.maximize_window()
    driver.get(url)
    html = requests.get(url).text
    soup = BeautifulSoup(html, 'html.parser')

    for n in range(1, 999):
        #페이지가 변하면 페이지 정보 다시 받아오기
        html = driver.page_source
        soup = BeautifulSoup(html, 'html.parser')
        time.sleep(1)

        try:
            #제목 정보 크롤링
            for anchor in soup.select("div.info_area > div.detail > div.title > a > strong"):
                name.append(anchor.get_text())
            #가격 정보 크롤링
            for anchor in soup.select("div.info_area > div.detail > div.price > strong.sell_price"):
                price.append(anchor.get_text())
            #작가 정보 크롤링
            for anchor in soup.select("div.info_area > div.detail > div.pub_info > span.author"):
                author.append(anchor.get_text())
            #10페이지가 넘어갈 경우 n을 10으로 나눈 나머지값으로 번호로 클릭
            if n % 10 != 0:
                if n % 10 == 9:
                    driver.find_element_by_xpath(
                        '//*[@id="eventPaging"]/div/ul/li[{num}]/a'.format(num=(n % 10) + 1)).click()
                else:
                    driver.find_element_by_xpath(
                        '//*[@id="eventPaging"]/div/ul/li[{num}]/a'.format(num=(n + 1) % 10)).click()
            else:
                driver.find_element_by_xpath('//*[@id="eventPaging"]/div/a[2]/img').click()
        #다음 페이지가 없는 경우 크롤링 중단
        except:
            break
    driver.quit()

    li = list()

    #데이터 갯수만큼 반복
    for i in range(0, len(name)):
        li.append([name[i], author[i], price[i]])   #크롤링한 데이터 하나의 리스트안에 삽입

    return li





url = 'http://www.kyobobook.co.kr/categoryRenewal/categoryMain.laf?perPage=20&mallGb=KOR&linkClass=01&menuCode=002'

data = get_data(url)

그리고 이번에는 데이터를 추가로 평점, 출판사, 출간일, 줄거리, ISBN 정보를 얻어와 보자.


-소스코드

import requests
from bs4 import BeautifulSoup
import pandas as pd
from selenium import webdriver
from openpyxl import Workbook
import os
import time

def get_data(url):
    name = list()
    author = list()
    price = list()
    pub = list()
    isbn = list()
    yymmdd = list()
    summary = list()

    options = webdriver.ChromeOptions()
    chromedriver_path = (r'C:/Users/eco/Desktop/공부/크롤링/chromedriver.exe')   #chromedrive
    options.add_argument('headless')                                           #크롬드라이버 창 숨기기
    driver = webdriver.Chrome(os.path.join(os.getcwd(), chromedriver_path), options=options)
    driver.maximize_window()
    driver.get(url)
    html = requests.get(url).text
    soup = BeautifulSoup(html, 'html.parser')

    for n in range(1, 999):
        #페이지가 변하면 페이지 정보 다시 받아오기
        html = driver.page_source
        soup = BeautifulSoup(html, 'html.parser')
        time.sleep(1)

        try:
            #제목 정보 크롤링
            for anchor in soup.select("div.info_area > div.detail > div.title > a > strong"):
                name.append(anchor.get_text())
            #가격 정보 크롤링
            for anchor in soup.select("div.info_area > div.detail > div.price > strong.sell_price"):
                price.append(anchor.get_text())
            #작가 정보 크롤링
            for anchor in soup.select("div.info_area > div.detail > div.pub_info > span.author"):
                author.append(anchor.get_text())
            # 출판사
            for anchor in soup.select("div.info_area > div.detail > div.pub_info > span:nth-child(2)"):
                pub.append(anchor.get_text().strip())
            # 출간일
            for anchor in soup.select("div.info_area > div.detail > div.pub_info > span:nth-child(3)"):
                yymmdd.append(anchor.get_text().strip())
            # 줄거리
            for anchor in soup.select("div.info_area > div.detail > div.info"):
                summary.append(anchor.get_text())
            # ISBN
            for anchor in soup.find_all('input', {'name': 'barcode'}):
                if anchor.get('value'):
                    isbn.append(anchor.get('value'))
            
            #10페이지가 넘어갈 경우 n을 10으로 나눈 나머지값으로 번호로 클릭
            if n % 10 != 0:
                if n % 10 == 9:
                    driver.find_element_by_xpath(
                        '//*[@id="eventPaging"]/div/ul/li[{num}]/a'.format(num=(n % 10) + 1)).click()
                else:
                    driver.find_element_by_xpath(
                        '//*[@id="eventPaging"]/div/ul/li[{num}]/a'.format(num=(n + 1) % 10)).click()
            else:
                driver.find_element_by_xpath('//*[@id="eventPaging"]/div/a[2]/img').click()
        #다음 페이지가 없는 경우 크롤링 중단
        except:
            break
    driver.quit()

    li = list()

    #데이터 갯수만큼 반복
    for i in range(0, len(name)):
        li.append([name[i], author[i], price[i], pub[i], yymmdd[i], isbn[i], summary[i]])   #크롤링한 데이터 하나의 리스트안에 삽입

    return li





url = 'http://www.kyobobook.co.kr/categoryRenewal/categoryMain.laf?perPage=20&mallGb=KOR&linkClass=01&menuCode=002'

data = get_data(url)


df = pd.DataFrame(data, columns=['제목', '작가', '가격', '출판사', '출간일', 'ISBN', 'summary'])

df.to_csv("data_csv.csv", header=False, index=False, encoding='euc-kr')   #df.to_csv("경로/파일명.csv", header=1행(제목, 작가, 가격), index=(번호))
df.to_excel("data_xlsx.xlsx")

 

위 코드를 보면 ISBN은 데이터 파싱 방법이 다른데 selector로는 ISBN 정보를 얻어올 수 없기 때문이다.

input type="hidden" 태그들이 여러 가지여서 기존 selector로는 정보를 얻을 수 없고 위와 같은 방법으로 name값이 barcode인 곳을 찾아 value값을 가져오는 방식으로 진행하였다.

 

다음번에는 교보문고 전체 장르 페이지들을 크롤링을 해보겠다.