본문 바로가기
Python

playwright(동적 스크래핑)

by Coarti 2024. 1. 28.

 

pip install playwright



설치 후 터미널 재실행

playwright install

https://www.wanted.co.kr

 

원티드 - 일하는 사람들의 모든 가능성

이력서, 채용 공고, 연봉 정보, 직무 콘텐츠 등 이직 및 커리어 성장에 필요한 모든 것을 만나보세요.

www.wanted.co.kr

원티드에서 검색 시 무한 스크롤로 버튼식 페이지 변경이 아닌것을 알 수 있다.

정적인 페이지가 아니기에 bs4만으로는 충분한 데이터를 수집하기 어렵다 때문에 추가적인 모듈로 스크랩을 하자

from playwright.sync_api import sync_playwright
import time
from bs4 import BeautifulSoup
import csv

class Scraper:
    def __init__(self, keyword):
        self.keyword = keyword
        self.data = []
        
    def get_resource(self):
        p = sync_playwright().start()

        ## headless : 브라우저를 실행 시키지만 눈에 보이지 않음
        browser = p.chromium.launch(headless=False)

        page = browser.new_page()

        ##page.goto("https://www.wanted.co.kr/")
        page.goto(f"https://www.wanted.co.kr/search?query={self.keyword}&tab=position")

        time.sleep(2)

        ##page.click("button.Aside_searchButton__Xhqq3")
        ####page.locator("button.Aside_searchButton__Xhqq3").click()
        ##
        ####page.screenshot(path="screnshot.png")
        ##
        ##time.sleep(2)
        ##
        ##page.get_by_placeholder("검색어를 입력해 주세요.").fill("java")
        ##
        ##time.sleep(2)
        ##
        ##page.keyboard.down("Enter")
        ##
        ##time.sleep(2)
        ##
        ##page.click("a#search_tab_position")
        ##
        ##time.sleep(2)

        for _ in range(4):
            page.keyboard.down("End")
            time.sleep(2)

        content = page.content()

        browser.close()

        p.stop()

        return content

    def search_jobs(self):
        soup = BeautifulSoup(self.get_resource(), "html.parser")

        ## type: list
        jobs = soup.find_all("div", class_ = "JobCard_container__FqChn")


        for job in jobs:
            link = f"https://www.wanted.co.kr{job.find('a')['href']}"
            title = job.find("strong", class_="JobCard_title__ddkwM").text
            company_name = job.find("span", class_="JobCard_companyName__vZMqJ").text
            location = job.find("span", class_ = "JobCard_location__2EOr5").text
            reward = job.find("span", class_ = "JobCard_reward__sdyHn").text

            job = {
                "title": title,
                "company_name": company_name,
                "location": location,
                "reward": reward,
                "link": link,
            }
            self.data.append(job)

        return len(self.data)

    def to_csv(self):
        if not self.data:
            return "Wrong word or No searching Information"
        
        file = open(f"{self.keyword}_jobs_wanted.csv", "w")
        writter = csv.writer(file)
        writter.writerow(
            [
                "Title",
                "Company",
                "Location",
                "Reward",
                "Link",
            ]
        )

        data = self.data
        for d in data:
            writter.writerow(d.values())
        file.close()
        
        return "success"

keywords = [
    "ios",
    "java",
    "flutter",
]
for keyword in keywords:
    s = Scraper(keyword)
    print(s.search_jobs())
    print(s.to_csv())

동작 시 키워드만 바꾸면서 파일을 만들어 준다

 

  • get_resource() : playwright 사용으로 동적으로 페이지를 움직이게 만든다
    • 클릭, 스크롤, 텍스트 입력, 키 입력, 스크린 샷 등 다양한 기능이 있다.
  • search_jobs() : bs4를 사용하여 데이터를 추출한다.
  • to_csv() : csv파일로 만들어 데이터를 확인할 수 있다.

 


from playwright.sync_api import sync_playwright
import time
from bs4 import BeautifulSoup

p = sync_playwright().start()

## headless : 브라우저를 실행 시키지만 눈에 보이지 않음
browser = p.chromium.launch(headless=False)

page = browser.new_page()

page.goto("https://www.wanted.co.kr/")

time.sleep(2)

## 같은 동작을 한다
page.click("button.Aside_searchButton__Xhqq3")
##page.locator("button.Aside_searchButton__Xhqq3").click()

## 스크린샷
##page.screenshot(path="screnshot.png")

time.sleep(2)

page.get_by_placeholder("검색어를 입력해 주세요.").fill("java")

time.sleep(2)

page.keyboard.down("Enter")

time.sleep(2)

page.click("a#search_tab_position")

time.sleep(2)

for _ in range(5):
    page.keyboard.down("End")
    time.sleep(2)

content = page.content()

browser.close()

p.stop()

soup = BeautifulSoup(content, "html.parser")

## type: list
jobs = soup.find_all("div", class_ = "JobCard_container__FqChn")

jobs_db = []
for job in jobs:
    link = f"https://www.wanted.co.kr{job.find('a')['href']}"
    title = job.find("strong", class_="JobCard_title__ddkwM").text
    company_name = job.find("span", class_="JobCard_companyName__vZMqJ").text
    location = job.find("span", class_ = "JobCard_location__2EOr5").text
    reward = job.find("span", class_ = "JobCard_reward__sdyHn").text

    job = {
        "title": title,
        "company_name": company_name,
        "location": location,
        "reward": reward,
        "link": link,
    }
    jobs_db.append(job)

print(len(jobs_db))

원티드 홈부터 검색과정을 순차적으로 볼 수 있다.


시간이 지나면 페이지는 변할 수 있기 때문에 항상 동작하지 않는다 

상황에 맞게 변형하면서 필요한 자료를 가져올 수 있게 코드를 작성해야 한다.

728x90

'Python' 카테고리의 다른 글

CentOS 7 에 Python 3.10 이상 설치  (0) 2024.08.13
인공지능 로드맵  (0) 2024.06.28
bs4 응용  (0) 2024.01.31
bs4(BeautifulSoup)  (0) 2024.01.27