2011-10-11 4 views
1

일부 웹 페이지를 HTML로 크롤링하고 저장하려고합니다. 수백 개의 인기있는 웹 사이트를 탐색하고 단순히 자신의 FrontPage와 "정보"페이지를 저장하십시오.웹 마이닝 또는 스크래핑 또는 크롤링? 어떤 도구/라이브러리를 사용해야합니까?

많은 질문을 살펴본 결과 웹 크롤링이나 웹 스크랩 질문에서 답변을 찾지 못했습니다.

솔루션을 빌드하는 데 사용해야하는 라이브러리 또는 도구는 무엇입니까? 아니면 이것을 처리 할 수있는 기존 도구가 있습니까?

+0

"정보"페이지는 어떻게 식별합니까? –

+0

URL에있는 "about"에 대한 정규식을 간단히 찾습니다. 일치하면 그냥 두지 말고 저장하십시오. 가짜 부정적인 문제 없습니다. – Flake

+0

@Flake는 안전하고 텍스트와 함께 URL이 내부적으로 링크되어 있습니다. 물론 누군가 "약"이라는 단어가없는 "회사 정보"와 같은 링크 만있을 수 있습니다. – Ali

답변

4

정말 여기에 더 좋은 해결책입니다. Python이 아마도 정규 표현식에 대한 믿을 수 없을만큼 강력한 지원 때문에 시작할 수있는 가장 좋은 방법이라고 생각하는 것처럼 당신 말이 맞습니다.

이런 식으로 구현하려면 검색 엔진의 웹 페이지를 효과적으로 최적화하면 검색 엔진의 작동 방식을 알 수 있으므로 SEO (검색 엔진 최적화)에 대한 강력한 지식이 도움이됩니다. 나는 SEOMoz과 같은 사이트로 시작할 것입니다.

가) 각 페이지에 대한 소개 페이지의 링크를 얻을 크롤러에 공급 :

는 지금까지 "우리에 대해"페이지를 확인하는 등, 당신은 단지 2 가지 옵션이 있습니다.

b) "about us", "about", "learn more"등과 같은 특정 키워드에 대해 링크을 구문 분석하십시오.

옵션 b를 사용할 때 웹 사이트가 여러 번 같은 페이지로 연결되기 때문에 무한 루프에 걸릴 수 있으므로 특히주의하십시오. 특히 링크가 페이지가 머리글 또는 바닥 글에있는 경우 페이지가 다시 링크 될 수 있습니다. 이것을 피하려면 방문한 링크 목록을 만들어 다시 방문하지 않도록해야합니다.

마지막으로 크롤러가 robot.txt 파일에서 지침을 존중하도록 권장하며, 외부 링크에서 주로 사용되는 rel="nofollow" 링크를 따르지 않는 것이 좋습니다. 다시 말하지만, SEO에 대한 정보는이 기사를 읽어보십시오.

감사합니다,

3

시험해보십시오. scrapy. 그것은 파이썬을위한 웹 스크래핑 라이브러리입니다. 간단한 파이썬 스크립트가 필요한 경우 urllib2을 파이썬으로 시도하십시오.

6

파이썬으로 갈 때 mechanizeBeautifulSoup에 관심이있을 수 있습니다.

기계화 일종의 (브라우저 식별, 페이지 리디렉션 등을 날조, 프록시 옵션 포함) 브라우저를 시뮬레이션 및 양식, 링크를 쉽게 인출을 허용 ... 문서는하지만 스파 스/조금 거친입니다.

import mechanize 
br = mechanize.Browser() 
br.open("http://www.example.com/") 
# follow second link with element text matching regular expression 
html_response = br.follow_link(text_regex=r"cheese\s*shop", nr=1) 
print br.title() 
print html_response 

BeautifulSoup로은 아주 쉽게 (당신이 기계화로 인출 할 수) HTML 컨텐츠를 구문 분석 할 수 있으며, 정규 표현식에를 지원

합니다 (기계화 웹 사이트에서) 몇 가지 예제 코드는 당신에게 아이디어를 제공합니다.

일부 예제 코드 :

from BeautifulSoup import BeautifulSoup 
soup = BeautifulSoup(html_response) 

rows = soup.findAll('tr') 
for r in rows[2:]: #ignore first two rows 
    cols = r.findAll('td') 
    print cols[0].renderContents().strip() #print content of first column 

그래서, 위의이 10 선은 거의 웹 사이트에있는 모든 테이블 행의 첫 번째 컬럼의 내용을 인쇄 할 준비가 복사 - 붙여 넣기합니다.

1

Heritrix은 가파른 학습 곡선을 가지지 만 홈 페이지와 정규식 필터를 사용하여 "보이는"페이지가 크롤링되는 방식으로 구성 할 수 있습니다.

더 많은 오픈 소스 자바 (웹) 크롤러 :이 http://java-source.net/open-source/crawlers

2

당신이 (특정 자바)에 필요 크롤러 builld하려는 경우 : 방법의 java.net.URL 및 java.net.URLConnection의 클래스를 사용하는

  1. 알아보기 또는 HTTP 요청/응답 헤더를들을 이해 HttpClient를 라이브러리
  2. 를 사용
  3. 이해 리디렉션 (모두 HTTP, HTML 및 자바 스크립트)
  4. 콘텐츠 인코딩 (문자셋)을 이해
  5. 잘못된 형식의 구문 분석에 좋은 라이브러리를 사용하십시오 (예 : cyberNecko, 여리고, JSoup)
  6. 다른 호스트에 동시 HTTP 요청을 확인하지만 다시 반입 할 필요가 없습니다 있도록, 동일한 호스트에
  7. 당신이 가져온 한 페이지를 지속마다 ~ 5 초보다 더 이상 발행 없는지 확인 그들에게 매일 매일 (HBase가 유용 할 수 있습니다) 자주 변경하지 마십시오.
  8. 너무 다음
  9. 순종의 robots.txt에

에게 다른 물건의 무리를 크롤링 현재 페이지에서 링크를 추출하는 방법입니다.

그다지 어렵지는 않지만 까다로운 가장자리 경우 (예 : 리디렉션, 인코딩 (Tika 체크 아웃) 감지)가 있습니다.

더 기본적인 요구 사항에 대해서는 wget을 사용할 수 있습니다. Heretrix는 또 다른 옵션이지만 학습 할 또 다른 프레임 워크입니다.

회사 소개 확인 페이지 수행 할 수 있습니다 사용하여 다양한 추론 :

  1. 인바운드 링크 텍스트
  2. 페이지 제목
  3. 당신이되고 싶다면
  4. URL

페이지

  • 내용 더 정량적으로 기계 학습과 분류 자 ​​(베이지안 어쩌면)를 사용할 수 있습니다.

    프론트 페이지를 저장하는 것이 분명하지만 프론트 페이지 리디렉션 (때로는 다른 도메인으로, 종종 HTML 메타 리디렉션 태그 또는 JS로 구현되는 경우가 많음)은 매우 일반적이므로이를 처리해야합니다.

  • +0

    안녕하세요, 조엘, 흥미로운 답장을 보내 주셔서 감사합니다. 내 프로필을 통해 저에게 연락하여 웹 크롤러에 대해 더 자세히 이야기하고 싶습니다. 관심이 있다면 더 깊이 대화하고 싶습니다. 고맙습니다. –

    3

    파이썬 ==> 컬 < - 다음 코드는 좋은 서버에 300 초에 10,000 페이지를 크롤링 할 수 있습니다 크롤러

    의 최선의 구현입니다.

    #! /usr/bin/env python 
    # -*- coding: iso-8859-1 -*- 
    # vi:ts=4:et 
    # $Id: retriever-multi.py,v 1.29 2005/07/28 11:04:13 mfx Exp $ 
    
    # 
    # Usage: python retriever-multi.py <file with URLs to fetch> [<# of 
    #   concurrent connections>] 
    # 
    
    import sys 
    import pycurl 
    
    # We should ignore SIGPIPE when using pycurl.NOSIGNAL - see 
    # the libcurl tutorial for more info. 
    try: 
        import signal 
        from signal import SIGPIPE, SIG_IGN 
        signal.signal(signal.SIGPIPE, signal.SIG_IGN) 
    except ImportError: 
        pass 
    
    
    # Get args 
    num_conn = 10 
    try: 
        if sys.argv[1] == "-": 
         urls = sys.stdin.readlines() 
        else: 
         urls = open(sys.argv[1]).readlines() 
        if len(sys.argv) >= 3: 
         num_conn = int(sys.argv[2]) 
    except: 
        print "Usage: %s <file with URLs to fetch> [<# of concurrent connections>]" % sys.argv[0] 
        raise SystemExit 
    
    
    # Make a queue with (url, filename) tuples 
    queue = [] 
    for url in urls: 
        url = url.strip() 
        if not url or url[0] == "#": 
         continue 
        filename = "doc_%03d.dat" % (len(queue) + 1) 
        queue.append((url, filename)) 
    
    
    # Check args 
    assert queue, "no URLs given" 
    num_urls = len(queue) 
    num_conn = min(num_conn, num_urls) 
    assert 1 <= num_conn <= 10000, "invalid number of concurrent connections" 
    print "PycURL %s (compiled against 0x%x)" % (pycurl.version, pycurl.COMPILE_LIBCURL_VERSION_NUM) 
    print "----- Getting", num_urls, "URLs using", num_conn, "connections -----" 
    
    
    # Pre-allocate a list of curl objects 
    m = pycurl.CurlMulti() 
    m.handles = [] 
    for i in range(num_conn): 
        c = pycurl.Curl() 
        c.fp = None 
        c.setopt(pycurl.FOLLOWLOCATION, 1) 
        c.setopt(pycurl.MAXREDIRS, 5) 
        c.setopt(pycurl.CONNECTTIMEOUT, 30) 
        c.setopt(pycurl.TIMEOUT, 300) 
        c.setopt(pycurl.NOSIGNAL, 1) 
        m.handles.append(c) 
    
    
    # Main loop 
    freelist = m.handles[:] 
    num_processed = 0 
    while num_processed < num_urls: 
        # If there is an url to process and a free curl object, add to multi stack 
        while queue and freelist: 
         url, filename = queue.pop(0) 
         c = freelist.pop() 
         c.fp = open(filename, "wb") 
         c.setopt(pycurl.URL, url) 
         c.setopt(pycurl.WRITEDATA, c.fp) 
         m.add_handle(c) 
         # store some info 
         c.filename = filename 
         c.url = url 
        # Run the internal curl state machine for the multi stack 
        while 1: 
         ret, num_handles = m.perform() 
         if ret != pycurl.E_CALL_MULTI_PERFORM: 
          break 
        # Check for curl objects which have terminated, and add them to the freelist 
        while 1: 
         num_q, ok_list, err_list = m.info_read() 
         for c in ok_list: 
          c.fp.close() 
          c.fp = None 
          m.remove_handle(c) 
          print "Success:", c.filename, c.url, c.getinfo(pycurl.EFFECTIVE_URL) 
          freelist.append(c) 
         for c, errno, errmsg in err_list: 
          c.fp.close() 
          c.fp = None 
          m.remove_handle(c) 
          print "Failed: ", c.filename, c.url, errno, errmsg 
          freelist.append(c) 
         num_processed = num_processed + len(ok_list) + len(err_list) 
         if num_q == 0: 
          break 
        # Currently no more I/O is pending, could do something in the meantime 
        # (display a progress bar, etc.). 
        # We just call select() to sleep until some more data is available. 
        m.select(1.0) 
    
    
    # Cleanup 
    for c in m.handles: 
        if c.fp is not None: 
         c.fp.close() 
         c.fp = None 
        c.close() 
    m.close() 
    
    +0

    나는 평행하게 언급 했습니까? – codersofthedark

    관련 문제