자바 콩잎 영화 파충류-작은 파충류 성장 기(소스 코드)

20208 단어 Java파충
이전에 도 파충 류 를 사용 한 적 이 있다.예 를 들 어 nutch 를 이용 하여 지 정 된 씨앗 을 기어 오 르 고 기어 오 른 데 이 터 를 바탕 으로 검색 을 했 으 며 소스 코드 도 대충 보 았 다.물론,nutch 는 파충류 에 대해 매우 전면적 이 고 세밀 하 게 고려한다.스크린 에서 찍찍 거 리 며 기어 오 르 는 홈 페이지 정보 와 정 보 를 볼 때마다 블랙 테 크 놀 로 지 라 는 느낌 이 든다.마침 이번에 Spring MVC 를 정리 하 는 기 회 를 빌려 스스로 작은 파충 류 를 만 들 고 싶 습 니 다.간단 해도 괜 찮 습 니 다.어떤 작은 bug 도 괜 찮 습 니 다.제 가 필요 한 것 은 특정한 피 드 사 이 트 를 대상 으로 제 가 원 하 는 정 보 를 얻 을 수 있 으 면 됩 니 다.Exception 이 있 으 면 해결 합 니 다.일부 API 의 사용 이 부당 할 수도 있 고 http 요청 상태 가 이상 하거나 데이터 베 이 스 를 읽 고 쓰 는 데 문제 가 있 을 수도 있 습 니 다.바로 이 신문 exception 과 exception 을 해결 하 는 과정 에서 JewelCrawler(아들 의 이름)는 독립 적 으로 데 이 터 를 얻 을 수 있 고 Word2Vec 알고리즘 을 바탕 으로 감정 분석 을 하 는 작은 기능 도 있 습 니 다.
그 다음 에 알 수 없 는 Exception 이 해결 되 기 를 기다 리 고 있 을 수도 있 고 일부 성능 도 최적화 되 어야 한다.예 를 들 어 데이터 베이스 와 의 상호작용,데이터 의 읽 기와 쓰기 등 이다.하지만 연내 에 이 위 에 신경 을 많이 쓰 지 않 았 기 때문에 오늘 은 간단 한 정 리 를 하 겠 습 니 다.그리고 앞의 두 편 은 주로 기능 과 결과 에 중심 을 두 었 습 니 다.이 편 은 JewelCrawler 가 어떻게 태 어 났 는 지,그리고 코드 를 Github 에 올 려 놓 았 습 니 다.(소스 주 소 는 글 의 마지막 에 있 습 니 다)관심 있 는 것 은 주목 하 셔 도 됩 니 다.덜 상처
 환경 소개
개발 도구:Intellij idea 14
데이터베이스:Mysql 5.5+데이터베이스 관리 도구 Navicat(데이터베이스 연결 가능)

언어:자바
Jar 가방 관리:Maven
버 전 관리:Git 
디 렉 터 리 구조

그 속
com.ansj.vec 는 Word2Vec 알고리즘 의 자바 버 전 구현
com.jackie.crawler.doubanmovie 는 파충류 실현 모듈 로 그 중에서 도 포함 된다.

어떤 가방 들 은 비어 있다.왜냐하면 이 모듈 들 은 아직 사용 되 지 않 았 기 때문이다.
4.567917.constants 가방 은 상수 류 를 저장 합 니 다크롤 백 파충류 입구 보관 프로그램entity 패키지 매 핑 데이터베이스 테이블 의 실체 클래스테스트 패키지 저장 테스트 클래스
utils 패키지 저장 도구 류
 resource 모듈 은 설정 파일 과 자원 파일 을 저장 합 니 다.예 를 들 어
  • beans.xml:Spring 컨 텍스트 의 설정 파일
  • seed.properties:피 드 파일stopwords.dic:사용 정지 라 이브 러 리댓 글 12031715.txt:올 라 간 단평 데이터
  • tokenizer Result.txt:IKAnalyzer 단 어 를 사용 한 결과 파일
  • vector.mod:Word2Vec 알고리즘 을 바탕 으로 훈련 한 모델 데이터
  • test 모듈 은 테스트 모듈 로 UT 를 작성 하 는 데 사 용 됩 니 다.
     데이터베이스 설정
    1.의존 하 는 가방 추가
    JewelCrawler 가 사용 하 는 maven 관리 이기 때문에 pom.xml 에 해당 하 는 의존 도 를 추가 하면 됩 니 다.
    
    <dependency>
    
      <groupId>org.springframework</groupId>
    
      <artifactId>spring-jdbc</artifactId>
    
      <version>4.1.1.RELEASE</version>
    
    </dependency>
    
    <dependency>
    
      <groupId>commons-pool</groupId>
    
      <artifactId>commons-pool</artifactId>
    
      <version>1.6</version>
    
    </dependency>
    
    <dependency>
    
      <groupId>commons-dbcp</groupId>
    
      <artifactId>commons-dbcp</artifactId>
    
      <version>1.4</version>
    
    </dependency>
    
    <dependency>
    
      <groupId>mysql</groupId>
    
      <artifactId>mysql-connector-java</artifactId>
    
      <version>5.1.38</version>
    
    </dependency>
    
    <dependency>
    
      <groupId>mysql</groupId>
    
      <artifactId>mysql-connector-java</artifactId>
    
      <version>5.1.38</version>
    
    </dependency> 
    
    2.데이터 원본 bean 설명
    저 희 는 beans.xml 에서 데이터 원본 을 설명 하 는 bean 이 필요 합 니 다.
    
     <context:property-placeholder location="classpath*:*.properties"/>
    
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    
      <property name="driverClassName" value="${jdbc.driver}"/>
    
      <property name="url" value="${jdbc.url}"/>
    
      <property name="username" value="${jdbc.username}"/>
    
      <property name="password" value="${jdbc.password}"/>
    
    </bean> 
    
    메모:외부 프로필 jdbc.properties 를 연결 하 였 습 니 다.구체 적 인 데이터 원본 의 매개 변 수 는 이 파일 에서 읽 습 니 다.
    문제 가 발생 하면"SQL[insert into user(id)values(?)];Field 'name' doesn't  have a default value;”해결 방법 은 표 의 해당 필드 를 자체 성장 필드 로 설정 하 는 것 이다.
    질문
    기어 오 르 는 웹 페이지 데 이 터 는 dom 구 조 를 분석 하고 원 하 는 데 이 터 를 가 져 와 야 합 니 다.그 동안 다음 과 같은 오류 가 발생 했 습 니 다.
    org.htmlparser.Node 인식 되 지 않 음
    해결 방법:jar 패키지 의존 추가
    
    <dependency>
    
      <groupId>org.htmlparser</groupId>
    
      <artifactId>htmlparser</artifactId>
    
      <version>1.6</version>
    
    </dependency> 
    
    
    org.apache.http.HttpEntity 인식 되 지 않 음
    해결 방법:jar 패키지 의존 추가
    
    <dependency>
    
      <groupId>org.apache.httpcomponents</groupId>
    
      <artifactId>httpclient</artifactId>
    
      <version>4.5.2</version>
    
    </dependency> 
    
    
    물론 그동안 겪 었 던 문제 이 고 마지막 으로 Jsoup 이 만 든 페이지 로 해석 했다.
     maven 창고 다운로드 속도 가 느 립 니 다.
    이전 에는 기본 maven 중앙 창 고 를 사 용 했 습 니 다.jar 가방 을 다운로드 하 는 속도 가 느 렸 습 니 다.제 네트워크 문제 인지 다른 원인 인지 모 르 겠 습 니 다.나중에 인터넷 에서 아 리 클 라 우 드 의 maven 창 고 를 찾 았 습 니 다.업 데 이 트 된 후 이전 보다 초 단위 로 피 를 토 하 는 것 을 추천 합 니 다.
    
    <mirrors>
    
      <mirror>
    
       <id>alimaven</id>
    
       <name>aliyun maven</name>
    
       <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    
       <mirrorOf>central</mirrorOf>    
    
      </mirror>
    
    </mirrors> 
    
    Maven 의 settings.xml 파일 을 찾 으 면 이 미 러 를 추가 하면 됩 니 다.
    resource 모듈 에서 파일 을 읽 는 방법
    예 를 들 어 seed.properties 파일 읽 기
    
    @Test
    
      public void testFile(){
    
        File seedFile = new File(this.getClass().getResource("/seed.properties").getPath());
    
        System.out.print("===========" + seedFile.length() + "===========" );
    
      }
    
    
    정규 표현 식
    regrex 정규 표현 식 을 사용 할 때 정 의 된 Pattern 과 일치 하면 matcher 의 find 방법 을 먼저 호출 한 다음 에 group 방법 으로 하위 문자열 을 찾 을 수 있 습 니 다.그룹 을 직접 호출 하 는 방법 은 당신 이 원 하 는 결 과 를 찾 을 수 없습니다.
    위 에 Matcher 류 의 소스 코드 를 봤 어 요. 
    
    package java.util.regex;
    
    import java.util.Objects;
    
    public final class Matcher implements MatchResult {
    
      /**
    
       * The Pattern object that created this Matcher.
    
       */
    
      Pattern parentPattern;
    
     
    
      /**
    
       * The storage used by groups. They may contain invalid values if
    
       * a group was skipped during the matching.
    
       */
    
      int[] groups;
    
     
    
      /**
    
       * The range within the sequence that is to be matched. Anchors
    
       * will match at these "hard" boundaries. Changing the region
    
       * changes these values.
    
       */
    
      int from, to;
    
     
    
      /**
    
       * Lookbehind uses this value to ensure that the subexpression
    
       * match ends at the point where the lookbehind was encountered.
    
       */
    
      int lookbehindTo;
    
     
    
      /**
    
       * The original string being matched.
    
       */
    
      CharSequence text;
    
     
    
      /**
    
       * Matcher state used by the last node. NOANCHOR is used when a
    
       * match does not have to consume all of the input. ENDANCHOR is
    
       * the mode used for matching all the input.
    
       */
    
      static final int ENDANCHOR = 1;
    
      static final int NOANCHOR = 0;
    
      int acceptMode = NOANCHOR;
    
     
    
      /**
    
       * The range of string that last matched the pattern. If the last
    
       * match failed then first is -1; last initially holds 0 then it
    
       * holds the index of the end of the last match (which is where the
    
       * next search starts).
    
       */
    
      int first = -1, last = 0;
    
     
    
      /**
    
       * The end index of what matched in the last match operation.
    
       */
    
      int oldLast = -1;
    
     
    
      /**
    
       * The index of the last position appended in a substitution.
    
       */
    
      int lastAppendPosition = 0;
    
     
    
      /**
    
       * Storage used by nodes to tell what repetition they are on in
    
       * a pattern, and where groups begin. The nodes themselves are stateless,
    
       * so they rely on this field to hold state during a match.
    
       */
    
      int[] locals;
    
     
    
      /**
    
       * Boolean indicating whether or not more input could change
    
       * the results of the last match.
    
       *
    
       * If hitEnd is true, and a match was found, then more input
    
       * might cause a different match to be found.
    
       * If hitEnd is true and a match was not found, then more
    
       * input could cause a match to be found.
    
       * If hitEnd is false and a match was found, then more input
    
       * will not change the match.
    
       * If hitEnd is false and a match was not found, then more
    
       * input will not cause a match to be found.
    
       */
    
      boolean hitEnd;
    
     
    
      /**
    
       * Boolean indicating whether or not more input could change
    
       * a positive match into a negative one.
    
       *
    
       * If requireEnd is true, and a match was found, then more
    
       * input could cause the match to be lost.
    
       * If requireEnd is false and a match was found, then more
    
       * input might change the match but the match won't be lost.
    
       * If a match was not found, then requireEnd has no meaning.
    
       */
    
      boolean requireEnd;
    
     
    
      /**
    
       * If transparentBounds is true then the boundaries of this
    
       * matcher's region are transparent to lookahead, lookbehind,
    
       * and boundary matching constructs that try to see beyond them.
    
       */
    
      boolean transparentBounds = false;
    
     
    
      /**
    
       * If anchoringBounds is true then the boundaries of this
    
       * matcher's region match anchors such as ^ and $.
    
       */
    
      boolean anchoringBounds = true;
    
     
    
      /**
    
       * No default constructor.
    
       */
    
      Matcher() {
    
      }
    
     
    
    /**
    
     * All matchers have the state used by Pattern during a match.
    
     */
    
    Matcher(Pattern parent, CharSequence text) {
    
      this.parentPattern = parent;
    
      this.text = text;
    
     
    
      // Allocate state storage
    
      int parentGroupCount = Math.max(parent.capturingGroupCount, 10);
    
      groups = new int[parentGroupCount * 2];
    
      locals = new int[parent.localCount];
    
     
    
      // Put fields into initial states
    
      reset();
    
    }
    
    ....
    
    /**
    
     * Returns the input subsequence matched by the previous match.
    
     *
    
     * <p> For a matcher <i>m</i> with input sequence <i>s</i>,
    
     * the expressions <i>m.</i><tt>group()</tt> and
    
     * <i>s.</i><tt>substring(</tt><i>m.</i><tt>start(),</tt> <i>m.</i><tt>end())</tt>
    
     * are equivalent. </p>
    
     *
    
     * <p> Note that some patterns, for example <tt>a*</tt>, match the empty
    
     * string. This method will return the empty string when the pattern
    
     * successfully matches the empty string in the input. </p>
    
     *
    
     * @return The (possibly empty) subsequence matched by the previous match,
    
     *     in string form
    
     *
    
     * @throws IllegalStateException
    
     *     If no match has yet been attempted,
    
     *     or if the previous match operation failed
    
     */
    
    public String group() {
    
      return group(0);
    
    }
    
    /**
    
     * Returns the input subsequence captured by the given group during the
    
     * previous match operation.
    
     *
    
     * <p> For a matcher <i>m</i>, input sequence <i>s</i>, and group index
    
     * <i>g</i>, the expressions <i>m.</i><tt>group(</tt><i>g</i><tt>)</tt> and
    
     * <i>s.</i><tt>substring(</tt><i>m.</i><tt>start(</tt><i>g</i><tt>),</tt> <i>m.</i><tt>end(</tt><i>g</i><tt>))</tt>
    
     * are equivalent. </p>
    
     *
    
     * <p> <a href="Pattern.html#cg">Capturing groups</a> are indexed from left
    
     * to right, starting at one. Group zero denotes the entire pattern, so
    
     * the expression <tt>m.group(0)</tt> is equivalent to <tt>m.group()</tt>.
    
     * </p>
    
     *
    
     * <p> If the match was successful but the group specified failed to match
    
     * any part of the input sequence, then <tt>null</tt> is returned. Note
    
     * that some groups, for example <tt>(a*)</tt>, match the empty string.
    
     * This method will return the empty string when such a group successfully
    
     * matches the empty string in the input. </p>
    
     *
    
     * @param group
    
     *     The index of a capturing group in this matcher's pattern
    
     *
    
     * @return The (possibly empty) subsequence captured by the group
    
     *     during the previous match, or <tt>null</tt> if the group
    
     *     failed to match part of the input
    
     *
    
     * @throws IllegalStateException
    
     *     If no match has yet been attempted,
    
     *     or if the previous match operation failed
    
     *
    
     * @throws IndexOutOfBoundsException
    
     *     If there is no capturing group in the pattern
    
     *     with the given index
    
     */
    
    public String group(int group) {
    
      if (first < 0)
    
        throw new IllegalStateException("No match found");
    
      if (group < 0 || group > groupCount())
    
        throw new IndexOutOfBoundsException("No group " + group);
    
      if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
    
        return null;
    
      return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
    
    }
    
    /**
    
     * Attempts to find the next subsequence of the input sequence that matches
    
     * the pattern.
    
     *
    
     * <p> This method starts at the beginning of this matcher's region, or, if
    
     * a previous invocation of the method was successful and the matcher has
    
     * not since been reset, at the first character not matched by the previous
    
     * match.
    
     *
    
     * <p> If the match succeeds then more information can be obtained via the
    
     * <tt>start</tt>, <tt>end</tt>, and <tt>group</tt> methods. </p>
    
     *
    
     * @return <tt>true</tt> if, and only if, a subsequence of the input
    
     *     sequence matches this matcher's pattern
    
     */
    
    public boolean find() {
    
      int nextSearchIndex = last;
    
      if (nextSearchIndex == first)
    
        nextSearchIndex++;
    
     
    
      // If next search starts before region, start it at region
    
      if (nextSearchIndex < from)
    
        nextSearchIndex = from;
    
     
    
      // If next search starts beyond region then it fails
    
      if (nextSearchIndex > to) {
    
        for (int i = 0; i < groups.length; i++)
    
          groups[i] = -1;
    
        return false;
    
      }
    
      return search(nextSearchIndex);
    
    }
    
     
    
    /**
    
     * Initiates a search to find a Pattern within the given bounds.
    
     * The groups are filled with default values and the match of the root
    
     * of the state machine is called. The state machine will hold the state
    
     * of the match as it proceeds in this matcher.
    
     *
    
     * Matcher.from is not set here, because it is the "hard" boundary
    
     * of the start of the search which anchors will set to. The from param
    
     * is the "soft" boundary of the start of the search, meaning that the
    
     * regex tries to match at that index but ^ won't match there. Subsequent
    
     * calls to the search methods start at a new "soft" boundary which is
    
     * the end of the previous match.
    
     */
    
    boolean search(int from) {
    
      this.hitEnd = false;
    
      this.requireEnd = false;
    
      from    = from < 0 ? 0 : from;
    
      this.first = from;
    
      this.oldLast = oldLast < 0 ? from : oldLast;
    
      for (int i = 0; i < groups.length; i++)
    
        groups[i] = -1;
    
      acceptMode = NOANCHOR;
    
      boolean result = parentPattern.root.match(this, from, text);
    
      if (!result)
    
        this.first = -1;
    
      this.oldLast = this.last;
    
      return result;
    
    }
    
    ...
    
    } 
    
    
    그 이 유 는 다음 과 같 습 니 다.여기 서 find 방법 을 먼저 호출 하지 않 고 group 을 직접 호출 하면 group 방법 이 group(int group)을 호출 하 는 것 을 발견 할 수 있 습 니 다.이 방법 은 if first<0 이 있 습 니 다.여기 서 이 조건 이 성립 된 것 이 분명 합 니 다.first 의 초기 값 이-1 이기 때문에 여기 서 이상 을 던 집 니 다.그러나 find 방법 을 호출 하면 최종 적 으로 search(nextSearch Index)를 호출 합 니 다.여기 있 는 nextSearch Index 는 last 에 의 해 할당 되 었 고 last 의 값 은 0 이 며 search 방법 으로 이동 합 니 다.
    
    boolean search(int from) {
    
      this.hitEnd = false;
    
      this.requireEnd = false;
    
      from    = from < 0 ? 0 : from;
    
      this.first = from;
    
      this.oldLast = oldLast < 0 ? from : oldLast;
    
      for (int i = 0; i < groups.length; i++)
    
        groups[i] = -1;
    
      acceptMode = NOANCHOR;
    
      boolean result = parentPattern.root.match(this, from, text);
    
      if (!result)
    
        this.first = -1;
    
      this.oldLast = this.last;
    
      return result;
    
    } 
    
    
    이 next SearchIndex 는 from 에 전 달 했 고 from 은 방법 체 에서 first 에 할당 되 었 기 때문에 find 방법 을 호출 한 후에 이 first 는-1 이 아니 라 이상 을 던 지 는 것 이 아 닙 니 다.
    원본 코드 가 바 이 두 네트워크 에 업로드 되 었 습 니 다http://pan.baidu.com/s/1dFwtvNz
    이상 에서 말 한 문 제 는 비교적 깨 져 있 는데 모두 문제 에 부 딪 히 고 문 제 를 해결 할 때 정리 한 것 이다.구체 적 으로 조작 할 때 다른 문제 가 발생 할 수 있 습 니 다.문제 나 건의 가 있 으 면 말씀 해 주세요^^.
    마지막 으로 지금까지 기어 오 른 데 이 터 를 몇 장 넣 습 니 다.
    레코드 테이블

    그 중 에 저 장 된 것 은 79032 건 이 고,오 른 웹 페이지 는 48471 건 이다.
    영화 표

    현재 2964 편의 영화 와 드라마 작품 을 얻 었 다.
    코 멘 트

    29711 개의 기록 을 얻 었 다.
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기