본문 바로가기
카테고리 없음

크롤링으로 구직사이트에서 구직 정보 수집하기

by 빛나는존재 2024. 7. 16.

구직사이트인 잡코리아에 있는 정보 중 회사 명, 자격 요건, 우대사항 등의 정보를 수집하고 이것을 자동으로 dataframe 형태로 만들어 주는 작업을 하려고 했다. 

개발자모드로 들어가서 커서를 움직여 가며 내가 원하는 정보가 담긴 HTML 구역에서 Xpath 도 뽑아내거나 아니면 그냥 Beautiful soup 으로 HTML 정보를 얻어냈지만 내가 원하는 정보는 나오지 않았다.

마지막으로 시도 한 방법은 내가 원하는 정보가 담긴 class 의 이름을 직접 넣어서 찾는 것. 이렇게 했더니 드디어 나왔다. 

 

맨 처음 시도 한 것. 이렇게 했을 때 에러는 안나지만 soup 변수에 내가 원하는 정보는 안들어가 있었음.

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from webdriver_manager.chrome import ChromeDriverManager
from bs4 import BeautifulSoup
import time

def get_full_html(url):
    chrome_options = Options()
    chrome_options.add_argument("--headless")
    chrome_options.add_argument("--window-size=1920,1080")
    chrome_options.add_argument("--disable-gpu")
    chrome_options.add_argument("--no-sandbox")
    chrome_options.add_argument("--disable-dev-shm-usage")
    chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")

    service = Service(ChromeDriverManager().install())
    driver = webdriver.Chrome(service=service, options=chrome_options)

    try:
        driver.get(url)
       
        # Wait for any element that's likely to be on the page
        try:
            WebDriverWait(driver, 30).until(
                EC.presence_of_element_located((By.TAG_NAME, "body"))
            )
        except TimeoutException:
            print("Page load timed out. Proceeding with available content.")
       
        # Check for and handle any popups or overlays
        try:
            popup = WebDriverWait(driver, 5).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, "button.popup-close"))
            )
            popup.click()
        except TimeoutException:
            print("No popup found or popup handling timed out.")
       
        # Scroll to the bottom of the page
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(5)  # Wait for any lazy-loaded content
       
        # Get the page source after all interactions
        html_content = driver.page_source
       
        return html_content

    finally:
        driver.quit()

# URL of the job posting

# Get the full HTML content
full_html = get_full_html(url)

# Parse the HTML with BeautifulSoup
soup = BeautifulSoup(full_html, 'html.parser')

# Now you can search for the elements you need
company_name = soup.select_one('div.co-name')
print("Company Name:", company_name.text.strip() if company_name else "Not found")

job_details = soup.select('div.tbRow')
for detail in job_details:
    title = detail.select_one('th')
    content = detail.select_one('td')
    if title and content:
        print(f"{title.text.strip()}: {content.text.strip()}")

# If you want to save the entire HTML for inspection
with open('full_page_content.html', 'w', encoding='utf-8') as f:
    f.write(full_html)
 
 

 

두번째 시도: iframe 사용해서 혹시 html에서 hidden 정보가 있는지 탐색. 그런데 이렇게 해도 원하는 정보는 안나옴. 

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager

chrome_options = Options()
chrome_options.add_argument("--headless")  # if you want to run Chrome in headless mode

# This will automatically download and use the correct ChromeDriver version
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=chrome_options)

# url 로 iframe 확인

# URL of the page to scrape

# Navigate to the page
driver.get(url)

# Wait for the page to load
wait = WebDriverWait(driver, 10)
wait.until(EC.presence_of_element_located((By.TAG_NAME, "body")))

# Get iframe content (if any)
iframes = driver.find_elements(By.TAG_NAME, "iframe")
for iframe in iframes:
    driver.switch_to.frame(iframe)
    iframe_content = driver.page_source
    # Process iframe content as needed
    driver.switch_to.default_content()  # Switch back to main content

# Get hidden elements or specific class elements
hidden_elements = driver.find_elements(By.CSS_SELECTOR, ".hidden-class")  # Replace with actual class name
for element in hidden_elements:
    # Process hidden elements as needed
    pass

# Get page source after JavaScript rendering
page_source = driver.page_source

# Use BeautifulSoup to parse the rendered HTML
soup = bs(page_source, 'html.parser')

# Extract information as before
# ...

# Close the browser
driver.quit()

그다음 택한 방법: 내가 택한 방법은 다시 한 번 개발자 도구 들어가서 원하는 부분에 커서 갖다대고 Xpath 찾아낸것.

이를 이용해서 아래와 같이 다시 시도. 그런데 이건 아예 에러가 나버린다.
from webdriver_manager.chrome import ChromeDriverManager
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Set up the WebDriver
chrome_options = Options()
chrome_options.add_argument("--headless")  # Optional: run in headless mode
# This will automatically download and use the correct ChromeDriver version

service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=chrome_options)

# Navigate to the page
driver.get(url)

try:
    # Wait for the element to be present
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.XPATH, "/html/body/div/table/tbody/tr/td"))
    )
   
    # Get the text content of the element
    content = element.text
    print("Content:", content)
   
    # If you need the HTML content instead of just the text:
    html_content = element.get_attribute('innerHTML')
    print("HTML Content:", html_content)

except Exception as e:
    print("An error occurred:", str(e))

finally:
    driver.quit()

마지막 시도 한 방법: 차라리 F12 누른 개발자모드에 뜬 스크린 샷을 Claude 에게 text 로 전환 하라고 한 후, 특정 class 에 있는 정보 어떻게 가져오냐고 물어봄.

 

Cluade 에게 한 질문: "can you convert all html source text in this image to text?"

질문 할 때 사용한 첨부파일 이미지: (이게 왜 그런지 몰라도 전체 코드 복사가 안되어서 이미지로 따와서 claude 에게 이걸 다 텍스트로 만들어달라고 함.

그리고 그 이후에 그 html source code 중 특정 class (recruitment-item) 에서 정보 가져오려면 어떻게 해야 하는 지 물어봄.

질문: " thanks! now, from this html source, what do I do if I want to extract text under "recruitment-information" class that contains "우대사항"?"

Claude 답: 

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
from webdriver_manager.chrome import ChromeDriverManager

# Set up Selenium
chrome_options = Options()
chrome_options.add_argument("--headless")  # Run in headless mode
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options)

# URL of the job posting
driver.get(url)

try:
    # Wait for the iframe to load
    iframe = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "gib_frame"))
    )
   
    # Switch to the iframe
    driver.switch_to.frame(iframe)
   
    # Wait for the recruitment-item to be present in the iframe
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.CLASS_NAME, "recruitment-item"))
    )
   
    # Get the HTML content of the recruitment-item
    recruitment_item_html = driver.find_element(By.CLASS_NAME, "recruitment-item").get_attribute('outerHTML')
   
    # Parse the HTML with BeautifulSoup
    soup = BeautifulSoup(recruitment_item_html, 'html.parser')
   
    # Find all p tags within the recruitment item
    p_tags = soup.find_all('p')
   
    extracting = False
    extracted_text = []
   
    for p in p_tags:
        if '우대' in p.text:
            extracting = True
       
        if extracting:
            extracted_text.append(p.text.strip())
       
        # Stop extracting if we hit another major section (you might need to adjust this condition)
        if extracting and p.find('b'):
            break
   
    # Join the extracted text
    result = '\n'.join(extracted_text)
    print(result)

except Exception as e:
    print(f"An error occurred: {str(e)}")

finally:
    driver.quit()

 

Soup 확인 해 보니 드디어 내가 원하는 정보 (지원 자격, 우대사항 등) 이 있었다.

이제 다음 단계는 다른 지원 공고 페이지에서도 이런 정보들을 똑같이 찾아서 이들을 테이블로 한꺼번에 넣는 작업.

 

반응형