
Scraping을 할 때는 원하지 않는 내용을 깍아내서 필요한 정보만을 얻어야 한다
여러 줄의 코드를 이용해 정보를 추출할 때는 곧바로 코드를 짜지 말고, 방법에 대해 고민하는 과정이 필요
<span class="green"> </span>, <span class="red"> </span>와 같은 tag가 있을 때,
->클래스를 이용해 쉽게 tag를 구분 가능
from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen('http://www.pythonscraping.com/pages/warandpeace.html')
bsObj = BeautifulSoup(urlopen, 'html.parser')
nameList = bsObj.findAll('span', {'class': 'green'}) # span tag 중 class가 green인 tag
for name in nameList:
print(name.get_text())
findAll(tag, attributes, recursive, text, limit, keywords)
findall 함수에 속성 목록을 넘기면 OR 필터처럼 동작하기 때문에 태그 목록이 길어진다.
keyword 매개변수는 AND 필터처럼 동작
문서 안에서의 위치를 기준으로 tag를 찾을 때 tree navigation을 사용
from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen('http://www.pythonscraping.com/pages/page3.html')
bsObj = BeautifulSoup(html, 'html.parser')
for sibling in bsObj.find('table', {'id': 'giftList'}).tr.next_siblings:
print(sibling)
from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen('http://www.pythonscraping.com/page/page3.html')
bsObj = BeautifulSoup(html, 'html.parser')
print(bsObj.find('img', {'src': '../img/gifts/imgs1.jpg'
}).parent.previous_siblings.get_text())
| 기호 | 의 미 | 예 제 | 일치하는 문자열 예제 |
|---|---|---|---|
| * | 바로 앞에 있는 문자, 하위표현식, 대괄호로 묶인 문자를 0번 이상 나타냄 | a*b* | ab, aabbb, abb, aaab, ''(빈 문자열) |
| + | 바로 앞에 있는 문자, 하위표현식, 대괄호로 묶인 문자를 1번 이상 나타냄 | a+b+ | ab, aaabb, abbb, aaaaaaabbbbb |
| [] | 대괄호 안에 있는 문자 중 하나를 나타냄 | [A-Z]* | APPLES, CAPITALS, QWERTY |
| () | group으로 묶인 하위 표현식. 정규 표현식 평가시 가장 먼저 평가되는 항목 | (a*b)* | aabaab, abaaba, ababaaaaab, bbbbbb |
| {m, n} | 바로 앞에 있는 문자, 하위표현식, 대괄호로 묶인 문자들을 m번 이상, n번 이상 나타냄 | a{2, 3}b{2, 3} | aabbb, aaabbb, abb |
| [^] | 대괄호 안에 있는 문자를 제외한 문자를 나타냄 | [^A-Z]* | apple, lowercase, qwerty |
| | | |로 분리된 문자, 하위표현식 중 하나를 나타냄 | b(a|i|e)d | bad, bid, bed |
| . | 문자하나를 나타냄 (와일드 카드) | b.d | bad, bzd, b$d, b d ... |
| ^ | 바로 뒤에 오는 문자 혹은 하위표현식이 문자열의 맨 앞에 나타남 | ^a | apple, asdf, a |
| \ | 특수 문자를 원래 문자 그대로 사용 | \., \|, \\ | ., |, \ |
| $ | 정규표현식 마지막에 주로 사용. 바로 앞에 오는 문자 또는 하위표현식이 문자열의 마지막에 나타남 |
[A-Z]*[a-z]$ | ABCabc, zzzyx, Bob |
| ?! | 포함하지 않는다는 의미. 바로 다음에 오는 문자는 해당 위치에 나타나지 않음 특정 문자를 완전히 배제하려면 ^, $와 함께 사용 |
^((?![A-Z]).)*$ | no-caps-here, $ymb0ls a4e fine |
정규 표현식을 사용하면 내가 원하는 tag만을 추출할 수 있음
tag 자체를 식별하는 무언가를 찾아야 한다
from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen('http://www.pythonscraping.com/pages/page3.htlm')
bsObj = BeautifulSoup(html, 'html.parser')
images = bsObj.findAll('img', {'src': re.compile('\.\.\/img\/gifts/img.*\.jpg')})
for image in images:
print(image['src'])
정규 표현식을 이용하면 매우 유연하게 원하는 tag를 탐색 가능
myTag.attrs
myImgTag.attrs['src'] # dict 객체임을 감안하여 접근 가능
lambda 표현식을 이용해 탐색을 할 수 있다
soup.findAll(lambda tag: len(tag.attrs) == 2) # 속성이 2개인 tag 탐색
# <div class="body" id="content"></div>
# <span style="color:red" class="title"></span>