본문 바로가기
Python/Web Scraping

[Python] #2.10 StackOverflow extract jobs (#코딩공부)

by 함께 공부해요 2020. 2. 22.

https://youtu.be/KE6_1Idtc6c


<복습>

https://wook-2124.tistory.com/38

 

[Python] #2.9 StackOverflow Pages (#코딩공부)

https://youtu.be/i4RsYwp2Ln0 <복습> https://wook-2124.tistory.com/37 [Python] #2.8 Extracting Locations and Finishing up (#코딩공부) https://youtu.be/Qfchx372rhU <복습> https://wook-2124.tistory.com..

wook-2124.tistory.com


<준비물>

https://repl.it/

 

The world's leading online coding platform

Powerful and simple online compiler, IDE, interpreter, and REPL. Code, compile, and run code in 50+ programming languages: Clojure, Haskell, Kotlin (beta), QBasic, Forth, LOLCODE, BrainF, Emoticon, Bloop, Unlambda, JavaScript, CoffeeScript, Scheme, APL, Lu

repl.it

https://github.com/psf/requests

 

psf/requests

A simple, yet elegant HTTP library. Contribute to psf/requests development by creating an account on GitHub.

github.com

https://www.crummy.com/software/BeautifulSoup/

 

Beautiful Soup: We called him Tortoise because he taught us.

 

www.crummy.com


<코드기록>

# indeed.py와 동일하게 extract_jobs을 가져오고
# range는 int(정수)안에서만 기능할 수 있기때문에 return int(last_page)로 str을 int로 바꿔줌
import requests
from bs4 import BeautifulSoup

URL = f"https://stackoverflow.com/jobs?q=python&sort=i"

def get_last_page():
  result = requests.get(URL)
  soup = BeautifulSoup(result.text, "html.parser")
  pages = soup.find("div", {"class":"s-pagination"}).find_all("a")
  last_page = pages[-2].get_text(strip=True)
  return int(last_page)

def extract_jobs(last_page):
  jobs = []
  for page in range(last_page):
    print(page)

def get_jobs():
  last_page = get_last_page()
  jobs = extract_jobs(last_page)
  return jobs


# 두 번째 def 수정하기
# result 변수명을 만들고 {page + 1} 해준 것은 숫자가 0부터 출력되는 것을 1로 바꾸기 위함!
def extract_jobs(last_page):
  jobs = []
  for page in range(last_page):
    result = requests.get(f"{URL}&pg={page + 1}")
    print(result.status_code)


# 두 번째 def 수정하기
# indeed.py와 동일하게 soup 변수기능을 적용시킴
# soup 변수가 각각의 def함수에서 이름도 같지만 오류가 나지 않는 이유는 딱 그 함수의 scope(범위)에서만 기능하기 때문!
# div 안에있는 class: -job을 찾고 div data-jobid 출력!
def extract_jobs(last_page):
  jobs = []
  for page in range(last_page):
    result = requests.get(f"{URL}&pg={page + 1}")
    soup = BeautifulSoup(result.text, "html.parser")
    results = soup.find_all("div", {"class":"-job"})
    for result in results:
     print(result["data-jobid"])

1. Next를 제외한 last_page 숫자 가져오기

import requests
from bs4 import BeautifulSoup

URL = f"https://stackoverflow.com/jobs?q=python&sort=i"

def get_last_page():
  result = requests.get(URL)
  soup = BeautifulSoup(result.text, "html.parser")
  pages = soup.find("div", {"class":"s-pagination"}).find_all("a")
  print(pages)

def get_jobs():
  last_page = get_last_page()
  return []

저번 코드에서 pages = pages[0: -1]을 추가해, -1(Next)를 제외한 마지막 page인 172page를 가져왔다.

 

보인는 것과 같이 마지막 page인 last_page는 pages[-2]와 같다. 즉 -1이 Next이고 그 다음인 -2가 172(last_page)가 되는 것이다.


soup 기능 중 get_text()를 이용해 str만 가져와보자.

 

조잡한 나머지 글자가 사라지고 172만 남은 것을 알 수 있다.

 

그러나 172 값 밑에 빈칸이 있는 것을 알 수 있다.


이번엔 soup.get_text("|", strip=True)중 strip=True를 이용해보자.

 

get_text(strip=True)을 적고 출력을 하자 빈칸없이 깔끔하게 출력된 것을 알 수 있다.


2. indeed에서 extract_jobs(last_page) 코딩한 것 상속받기

indeed.py에서 코딩한 것과 동일하게 extract_jobs(last_page)를 갖고 오자.

 

sof.py에서도 indeed.py처럼 동일하게 코드를 작성하고(복붙하고) 출력했다.

 

하지만 range 함수는 integer(정수)에서만 기능을 하기 때문에, page 안에 있는 str을 int로 바꿔줘야한다.

(soup.get.text는 str으로 출력해주기 때문!)

 

last_page 앞에 int를 써줘서 str을 int로 바꾸니 정상적으로 작동한다.


3. result = requests.get(f'{URL}&pg={page + 1}')

result 변수명을 만들고, URL링크 뒤가 &pg= 였다는 것을 감안해서 URL과 page를 arguments(인자)화 해줬다.

그리고 {page +1}에서 +1을 해주는 이유는, 기계가 page를 0부터 읽는 것을 1부터 읽게끔 하기 위해서다.

 

마지막으로 indeed 홈페이지에서도 했던것처럼 soup.status_code를 통해 200값이 잘뜨는지 확인한다.


4. 직업 추출하기(extract_jobs)

직업의 inspection 결과 div는 data-jobid이고 class는 -job이란 것을 알 수 있다.

 

indeed 직업 추출할 때와 동일하게 soup와 results 변수명을 작성해주지만 class명은 다르게 작성하고 (-job), 마지막으로 result 변수명을 새로 만들어 data-jobid를 출력하면 홈페이지에서 봤던 번호가 출력되는 것을 알 수 있다.

 

본격적인 추출 내용은 다음시간에 이어서 정리하겠다! :)

 

※ soup 변수명이 여러 def(정의)에서 같은 변수명으로 쓰이는데도 오류가 나지 않는 이유는, 각각의 soup는 def(정의)의 범위(scope)안에서만 기능하기 때문이다.


※ 코로나바이러스감염증-19 조심하세요!!!!

댓글