scrape.py는 웹페이지에서 웹소를 긁어 오기 위한 파이썬 모듈이다. 손쉽게 페이지를 가져올 수 있고, 링크를 따라가고, 폼을 제출할 수 있다. 쿠키와 방향전환 그리고 SSL은 자동으로 처리된다. (SSL을 위해서는 파이썬에 socket.ssl 함수가 갖추어져 있거나, curl 명령-줄 유틸리티가 있어야 한다.)
scrape.py는 페이지를 완전하게 해석 트리로 바꾸지 않는다. 그래서 느슨하게 페이지를 다룰 수 있다. 마음대로 근처의 텍스트나 태그 또는 주석에 맞게 웹소를 찾을 수 있다.
모듈을 내려받거나 또는 문서 페이지를 읽어 보실 수 있다. 이 코드는 GNU 일반 공개 라이센스 버전 2 아래에서 배포된다.
다음에 간략하게 소개한다.
웹 페이지 가져오기
페이지를 가져오려면, go(url) 메쏘드를 Session 객체에 사용하면 된다. 이 모듈은 기본 세션 객체를 s라는 변수에 제공한다.
>>> from scrape import * >>> s.go('http://zesty.ca/') <Region 0:17780>
결과는 Region 객체로서 열람된 전체 문서를 아우른다 (모두 17780 바이트). Region 객체는 HTML 문서 안을 돌아다니는데 사용한다; Region 객체는 HTML 소스 코드에서 시작 지점과 끝 지점으로 텍스트 구역을 나타낸다.
성공적으로 가져오면, 세션의 doc 속성도 그 문서를 보유한다. headers 속성에는 수신된 헤더들이 담기며, url 속성에는 수신된 URL이 담긴다 (이 값들은 방향전환이 일어나면 요청한 URL과 다르다.).
>>> s.doc <Region 0:17780> >>> s.headers {'date': 'Sat, 05 Jul 2008 11:25:04 GMT', 'accept-ranges': 'bytes', 'content-type': 'text/html; charset=UTF-8', 'connection': 'close', 'server': 'Apache/2.0.46 (Red Hat)'} >>> s.url 'http://zesty.ca/'
Region 객체에서, 날 웹소는 content 속성에서 얻을 수 있고 평범한 텍스트는 text 속성에서 얻을 수 있다. (이 경우, 둘 모두 유니코드 문자열이다. 유니코드 인코딩을 서버에서 지정했기 때문이다.)
>>> d = s.doc >>> print d.content[:70] <!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"> <html >>> d.text[:30] u'Ka-Ping Yee\nKa-Ping Yee pingze'
웹소 추출하기
Region 객체는 마치 문자열처럼 조각썰기가 가능하다. 이 객체는 원래 문서에서 시작 위치와 끝 위치를 기억한다. 그러나 공급된 지표는 무엇이든 그 구역 자체에 관련되어 있다.
>>> d <Region 0:17780> >>> r = d[1400:1450] >>> r <Region 1400:1450> >>> len(r) 50 >>> r.start 1400 >>> r.end 1450 >>> r.content u'd voting system security.\nOr check out my\n<a href=' >>> r[-15:] <Region 1435:1450>
지정한 태그 이름의 시작 태그와 끝태그에 부합하는 첫 블록을 (구역 안에서) 찾으려면 first(tagname)을 Region 객체에 요청하자. 결과 Region 객체에 그 태그에 관한 정보가 유지된다; 사전 스타일로 속성에 접근할 수 있다. 구역은 시작 태그 바로 다음에서 시작하여 끝 태그 바로 앞에서 끝난다.
>>> t = d.first('title') >>> t <Region 247:258 title> >>> t.tagname 'title' >>> t.text u'Ka-Ping Yee' >>> s = d.first('span') >>> s <Region 2212:2213 span class='flag'> >>> s.keys() ['class'] >>> s['class'] 'flag'
last(tagname)은 구역 안에서 마지막 블록을 찾는다; next(tagname)은 구역의 끝 바로 다음에 시작하는 첫 블록을 찾는다; 그리고 previous(tagname)은 구역의 시작 바로 앞에서 끝나는 블록을 찾는다.
기본 탐색법
링크 앵커의 정확한 텍스트를 알고 있다면, follow(anchor)는 그 링크를 찾아서, 해석한 다음, 그를 따라간다. 홈페이지에 "CV"라는 링크가 있다면,
>>> s.follow('CV') <Region 0:19843> >>> s.headers {'date': 'Sat, 05 Jul 2008 11:25:04 GMT', 'accept-ranges': 'bytes', 'content-type': 'text/html; charset=UTF-8', 'connection': 'close', 'server': 'Apache/2.0.46 (Red Hat)'} >>> s.url 'http://zesty.ca/cv.html' >>> s.doc <Region 0:19843>
doc 속성은 열람된 문서를 보유한다 (go()나 submit() 또는 follow()도 같은 것을 돌려준다.).
정확한 앵커 텍스트 대신에, 정규 표현식을 앵커로 공급할 수 있다. 본인의 CV에 Waterloo 대학으로 가는 링크가 있지만, 텍스트가 정확하게 "Waterloo"는 아니다. 그렇지만 "Waterloo"로 끝나는 것은 확실하다.
>>> s.follow('Waterloo') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Users/ping/python/scrape.py", line 243, in follow raise ScrapeError('link %r not found' % anchor) scrape.ScrapeError: link 'Waterloo' not found >>> s.follow(re.compile('.*waterloo', re.I)) <Region 0:10851>
back()을 호출하면 다시 CV 페이지로 돌아온다.
>>> s.url 'http://www.uwaterloo.ca/' >>> s.doc <Region 0:10851> >>> s.back() 'http://zesty.ca/cv.html' >>> s.doc <Region 0:10851>
Region 객체는 HTML 요소와 연루시킬 수 있다. 이 경우 시작점은 그냥 시작 태그 바로 뒤이고 끝 지점은 끝 태그 바로 앞이다; 또는 개별 태그에 연루시킬 수 있다. 이 경우 시작 점은 "<" 바로 앞이고 끝 지점은 ">" 바로 뒤이다.
>>> from scrape import * >>> s.go('http://zesty.ca/') <Region 0:17780>