본문 바로가기

개발자/파이썬 Python

파이선 웹 스크래퍼 만들어 보자. 코드 2

반응형

 

 

앞의 코드 1 에서 작성한 코드를 재사용성을 높이고 파일로 별도 보관하기 위해 분리한다.

폴더 구조는 아래와 같고 main.py 코드는 아래와 같다.

 

 

replit.com 사이트에서 실습

 

from requests import get
from bs4 import BeautifulSoup
from extractors.wwr import extract_wwr_jobs

jobs = extract_wwr_jobs("python")
print(jobs)

 

위 폴더 구조 이미지에서 폴더 extractors 를 만들고 이전 작업한 코드를 wwr.py 파일로 분리하여 만들었다. wwr.py 코드는 아래와 같다.

 

from requests import get
from bs4 import BeautifulSoup

def extract_wwr_jobs(keyword):  
  base_url = "https://xxxxxxxxxxx/remote-jobs/search?term="
  
  response = get(f"{base_url}{keyword}")    
  if response.status_code != 200:
    print("Can't request website")
  else:
    soup = BeautifulSoup(response.text, "html.parser")
    jobs = soup.find_all('section', class_="jobs")
    results = []
    for job_section in jobs:
      job_posts = job_section.find_all('li')
      job_posts.pop(-1)
      for post in job_posts:
        anchor = post.find_all('a')
        anchor = anchor[1]
        link = anchor['href']
        company, kind, region = anchor.find_all('span', class_="company")
        title = anchor.find('span', class_='title')
        #print(company.string, kind.string, region.string, title.string) 
        job_data = {
          'compamy': company.string,
          'region': region.string,
          'position': title.string
        }
        results.append(job_data)
  
    return results
    '''
    for result in results:
      print(result)
      print("/////////")
    '''

 

 

여기까지 리팩토링하고 main.py 에서 시작한다. 

 

우선 indeed.com 사이트에서 python으로 검색하여 결과가 나오는 것을 확인하고 URL 주소를 우리가 이용할 수 있도록 가져온다. 그러면 주소는 아래와 같이 얻는다.

 

https://kr.indeed.com/jobs?q=python&l=&vjk=bcb41b925b56a584

https://kr.indeed.com/jobs?q=

 

초반에 403 메시지가 떠서 금지된 페이지라고 뜬다. 그러니까 지금 코드를 봇이라고 파악하고 데이터를 보내지 않는다. 문제를 잡기 위해 Selenium 사이트에서 문제를 해결하기로 한다. Selenium은 실제 브라우저를 띄워 원하는 사이트에 접근하도록 돕는 일을 한다. 결과적으로 봇으로 인식하지 않게 만들어 준다. 아래는 replit을 사용하지 않는 사람은 참고한다. 강의동영상 주소 에서 시작하고, Selenium 에 대해 자세히 공부하고 싶은 사람은 마찬가지로 사이트를 참고한다. 

 

local에서 하시는 분들은 참고하세요!! (VS code 등..)

셀레니움 설치
pip install selenium (혹은 pip3 install selenium)

드라이버 설치
크롬 : https://sites.google.com/a/chromium.org/chromedriver/downloads
파이어폭스 : https://github.com/mozilla/geckodriver/releases
사파리 : https://webkit.org/blog/6900/webdriver-support-in-safari-10/
(mac은 brew가 편해요 brew install chromedriver)

나머지는 운영체제와 사용할 프로그램에 맞게 검색해서 쓰시는 것을 추천드려요!!

 

 

진행한 코드는 아래와 같다.

 

from requests import get
from bs4 import BeautifulSoup
from extractors.wwr import extract_wwr_jobs
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")

browser = webdriver.Chrome(options=options)

browser.get("https://xxxxxxxxx/jobs?q=python&limit=50")

print(browser.page_source)

 

여기까지 했다면 아래 코드를 따라한다.

 


from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup
options = Options()
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")

browser = webdriver.Chrome(options=options)

browser.get("https://xxxxxxxxxx/jobs?q=python")

soup = BeautifulSoup(browser.page_source, "html.parser")
job_list = soup.find("ul", class_="jobsearch-ResultsList")


jobs = job_list.find_all('li', recursive=False)

for job in jobs:
  zone = job.find("div", class_="mosaic-zone")
  if zone == None:
    print("job li")
  else:
    print("mosaic li")

 

None은 무엇인가 있어야 하는데 없다는 것을 나타내는 데이터 타입이다. False와 다르다.

 

여기까지 하고 전체 코드는

 

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup

options = Options()
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")

browser = webdriver.Chrome(options = options)

#print(browser.page_source)
base_url = "xxxxxxxxxxxx/jobs?q="
search_term = "python"

browser.get(f"{base_url}{search_term}")
results = []
soup = BeautifulSoup(browser.page_source, "html.parser")
job_list = soup.find('ul', class_= "jobsearch-ResultsList css-0")
jobs = job_list.find_all('li', recursive = False)
#ul 바로밑 li만을 찾아낼 것이다
for job in jobs:
  zone = job.find("div", class_="mosaic-zone")
  #find는 찾은 element를 주거나 None을 준다
  if zone == None:#job li에서 job을 추출한다
    anchor = job.select_one("h2 a")
    title = anchor['aria-label']
    link = anchor['href']
    #print(title, link)
    #print("///////\n///////")
    company = job.find("span",class_="companyName")
    region = job.find("div",class_="companyLocation")
    job_data = {
        'link' : f"https://www.indeed.com{link}",
        'company' : company.string,
        'location' : region.string,
        'position' : title
    }
    results.append(job_data)
for result in results:
  print(result, "\n///////////\n")


#beaifulsoup은 검색결과를 list와 dictionary로 만든다
#print(results)
"""
h2 = job.find("h2",class_="jobTitle")
a = h2.find("a")
else:
print('mosaic li')
#mosaic-zone을 가진 li 구분, 필요없음
#None은 무언가 없을때 사용하는 자료형이다
"""

 

 

 

반응형

캐어랩 고객 지원

취업, 창업의 막막함, 외주 관리, 제품 부재!

당신의 고민은 무엇입니까? 현실과 동떨어진 교육, 실패만 반복하는 외주 계약, 아이디어는 있지만 구현할 기술이 없는 막막함.

우리는 알고 있습니다. 문제의 원인은 '명확한 학습, 실전 경험과 신뢰할 수 있는 기술력의 부재'에서 시작됩니다.

이제 고민을 멈추고, 캐어랩을 만나세요!

코딩(펌웨어), 전자부품과 디지털 회로설계, PCB 설계 제작, 고객(시장/수출) 발굴과 마케팅 전략으로 당신을 지원합니다.

제품 설계의 고수는 성공이 만든 게 아니라 실패가 만듭니다. 아이디어를 양산 가능한 제품으로!

귀사의 제품을 만드세요. 교육과 개발 실적으로 신뢰할 수 있는 파트너를 확보하세요.

지난 30년 여정, 캐어랩이 얻은 모든 것을 함께 나누고 싶습니다.

카카오 채널 추가하기

카톡 채팅방에서 무엇이든 물어보세요

당신의 성공을 위해 캐어랩과 함께 하세요.

캐어랩 온라인 채널 바로가기

캐어랩