TIL - Methods to extract html

Heechul Yoon·2020년 2월 12일
0

LOG

목록 보기
4/62

html파일에서 원하는 부분을 끌어오는 대표적인 방법들에 대해서 알아보자.

import requests
from bs4 import BeautifulSoup
url = 'https://kr.indeed.com/%EC%B7%A8%EC%97%85?q=django&l=%EC%84%9C%EC%9A%B8+%EA%B0%95%EB%82%A8%EA%B5%AC'

html = requests.get(url).text

soup = BeautifulSoup(html,'html.parser')

우선 해당 페이지의 url을 읽어와 BeautifulSoup parser의 객체를 soup 인스턴스에 넣어준다.

  1. soup.find_all()
<a target="_blank" id="jl_ffd9cedb23e97344" href="/rc/clk?jk=ffd9cedb23e97344&amp;fccid=df5e7ec512668ebf&amp;vjs=3" onmousedown="return rclk(this,jobmap[0],0);" onclick="setRefineByCookie([]); return rclk(this,jobmap[0],true,0);" rel="noopener nofollow" title="파이썬SW 금융분야 특화 챗봇 개발 함께 할 엔지니어" class="jobtitle turnstileLink " data-tn-element="jobTitle">
<b>파이</b>썬SW 금융분야 특화 챗봇 개발 함께 할 엔지니어</a>

위의 부분은 indeed홈페이지에서 python을 검색하면 title부분에 나오는 html 소스코드이다. 페이지에 있는 모든 title을 가져오기 위해서 우리는 위와같은 title부분에서 공통점을 찾은 결과 class="jobtitle turnstileLink " 부분은 모든 title의 a태그가 가지고 있는 부분이다.

soup.find_all(class_="jobtitle turnstileLink")

위와같이 매서드를 사용해주면 다음과같은 결과가 나온다.

[<a class="jobtitle turnstileLink" data-tn-element="jobTitle" href="/rc/clk?jk=55a19c92c845685e&amp;fccid=74d05cee5b52f133&amp;vjs=3" id="jl_55a19c92c845685e" onclick="setRefineByCookie([]); return rclk(this,jobmap[0],true,0);" onmousedown="return rclk(this,jobmap[0],0);" rel="noopener nofollow" target="_blank" title="Developer / Designer recruit">
Developer / Designer recruit</a>, <a class="jobtitle turnstileLink" data-tn-element="jobTitle" href="/rc/clk?jk=6c1d50662fa2d7f7&amp;fccid=71bba75c2a7d79a0&amp;vjs=3" id="jl_6c1d50662fa2d7f7" onclick="setRefineByCookie([]); return rclk(this,jobmap[1],true,0);" onmousedown="return rclk(this,jobmap[1],0);" rel="noopener nofollow" target="_blank" title="서울 강남구 인썸니아 시니어 개발자 및 퍼블리셔">
서울 강남구 인썸니아 시니어 개발자 및 퍼블리셔</a>, .........

즉 class="jobtitle turnstileLink"를 가진 a태그를 전부 리스트의 인자로 가져왔다.

여기서 a태그안의 url을 얻기 위해서는 href속성을 가져와야한다.

titles_all[0]['href']

위와같이 반환된 전체리스트인 soup.findall(class="jobtitle turnstileLink")
에서 0번째 인덱스의 'href'속성을 가져오는 코드를 실행해보면

/rc/clk?jk=55a19c92c845685e&fccid=74d05cee5b52f133&vjs=3

와같이 url만 가져온다.

그렇다면 a태그를 명시해주면서 'a태그자체의 속성 href'는 어떻게 가져올 수 있는 직관적인 코드를 알아보자.

titles_all[0].attrs['href']

위의 코드는 titles_all리스트 안의 0번째 인덱스(즉, a태그)에서 'href'속성을 가져오는 함수이다. 즉 titles_all[0]['href']
와 같은 결과를 리턴하지만 a태그 안에서의 attribute인 href를 가져온다는 좀 더 직관적인 코드라고 할수 있다.

여기서 주의할 점은

titles_all[0].a['href']

와 같이 리스트의 0번째 인덱스객체로 취급해서 a태그안의 href를 가져오는 시도는 애러를 발생시킨다는 것이다.

이유는 이미 find_all을 통해서 가져온 값들이 전부 a태그 그 자체이기 때문에 특정 값을 찾을 때 'a태그 안의 href'와 같은 코드를 작성하면 syntax error을 발생시킨다.

이제 해당 url을 가져왔으니 for문을 통해서 모든 url을 추출할 수 있다.

  1. soup.select()
    이제 셀렉터 경로를 통해서 원하는 데이터를 가져와보자.
soup.select('div.title > a')

class='title'인 div 태그의 하위 a태그의 값을 가져온다.

[<a class="jobtitle turnstileLink" data-tn-element="jobTitle" href="/rc/clk?jk=55a19c92c845685e&amp;fccid=74d05cee5b52f133&amp;vjs=3" id="jl_55a19c92c845685e" onclick="setRefineByCookie([]); return rclk(this,jobmap[0],true,0);" onmousedown="return rclk(this,jobmap[0],0);" rel="noopener nofollow" target="_blank" title="Developer / Designer recruit">
Developer / Designer recruit</a>, <a class="jobtitle turnstileLink" data-tn-element="jobTitle" href="/rc/clk?jk=6c1d50662fa2d7f7&amp;fccid=71bba75c2a7d79a0&amp;vjs=3" id="jl_6c1d50662fa2d7f7" onclick="setRefineByCookie([]); return rclk(this,jobmap[1],true,0);" onmousedown="return rclk(this,jobmap[1],0);" rel="noopener nofollow" target="_blank" title="서울 강남구 인썸니아 시니어 개발자 및 퍼블리셔">
서울 강남구 인썸니아 시니어 개발자 및 퍼블리셔</a>,.....

위와같이 결과가나오는데 soup.findall(class="jobtitle turnstileLink")
와 똑같이 a태그 전체를 리스트에 담아서 가져온 것을 알 수 있다. 따라서 원하는 값을 얻으려면

titles[0]['href']
titles[0].attrs['href']

둘중 하나를 쓰면 원하는 url을 얻을 수 있다.

하지만 실재로 웹페이지에서 selector 복사를 하면 아래와 같은 값이 복사된다.

soup.select('div.title')

즉, class='title'인 div태그 만으로도 충분히 같은 형식의 원하는 데이터를 가져올 수 있다는 뜻이다.

[<div class="title">
<a class="jobtitle turnstileLink" data-tn-element="jobTitle" href="/rc/clk?jk=55a19c92c845685e&amp;fccid=74d05cee5b52f133&amp;vjs=3" id="jl_55a19c92c845685e" onclick="setRefineByCookie([]); return rclk(this,jobmap[0],true,0);" onmousedown="return rclk(this,jobmap[0],0);" rel="noopener nofollow" target="_blank" title="Developer / Designer recruit">
Developer / Designer recruit</a>
</div>, 

결과는 위와같이 나온다. div의 하위테이블에는 우리가 타겟팅하는 a태그밖에 없다. 그렇다면 굳이 a태그 까지 내려갈 필요 없이 url값을 가져올 수 있다.

titles[0].a['href']

이제는 a태그의 부모태그인 div태그 까지 같이 가지고 왔기 때문에 위와같이 titles의 0번째 인덱스값에서 a태그까지 내려가서 href를 찾아줘야 syntax error없이 url값을 리턴한다

profile
Quit talking, Begin doing

0개의 댓글

관련 채용 정보