Electron 기반 파충류 프레임 워 크 Nightmare

저자: William 본문 은 오리지널 문장 으로 전재 되 었 으 니 작가 와 출처 를 밝 혀 주 십시오.
Electron 은 데스크 톱 애플 리 케 이 션 을 만 들 기 위해 순수 자 바스 크 립 트 를 사용 할 수 있 습 니 다.웹 서버 가 아 닌 데스크 톱 애플 리 케 이 션 에 전념 하 는 Node. js 의 변형 으로 볼 수 있 습 니 다.브 라 우 저 를 기반 으로 하 는 응용 방식 은 다양한 응답 식 의 상호작용 을 편리 하 게 할 수 있 습 니 다. 다음은 Electron 에서 파생 된 프레임 워 크 Nightmare 를 소개 합 니 다.
Nightmare 는 Electron 기반 프레임 워 크 로 웹 자동화 테스트 와 파충류 (사실 파충 류 는 여러분 이 직접 이 프레임 워 크 에 추가 한 기능 XD) 를 대상 으로 합 니 다. PlantomJS 와 같은 자동화 테스트 기능 을 가지 고 있 기 때문에 페이지 에서 사용자 의 행동 을 모 의 하여 비동기 데 이 터 를 불 러 올 수도 있 고 Request 라 이브 러 리 와 같이 URL 을 직접 방문 하여 데 이 터 를 캡 처 할 수도 있 습 니 다.또한 페이지 의 지연 시간 을 설정 할 수 있 기 때문에 수 동 으로 스 크 립 트 를 터치 하 든 행동 으로 스 크 립 트 를 터치 하 든 쉽 습 니 다.
Nightmare 사용 하기
NPM 다운 로드 를 더욱 빠르게 사용 하기 위해 타 오 바 오의 미 러 주 소 를 사용 할 수 있다.NPM 에 Nightmare 를 직접 설치 하면 설치 가 완 료 됩 니 다.
간단 한 시작 app. js 쓰기;
const Nightmare = require('nightmare')
const nightmare = new Nightmare({
     show: true,
     openDevTools: {
         mode: 'detach'
     }
 })

 nightmare.goto('https://www.hujiang.com')
   .evaluate(function() {
       //                 window/document,      promise
     console.log('hello nightmare')
     console.log('5 second close window')
   })
   .wait(5000)
   .end()
   .then(()=> {
     console.log('close nightmare')
   })

이 스 크 립 트 는 열 린 브 라 우 저의 디 버 깅 콘 솔 에서 hello nightmare 를 인쇄 하고 5 초 후에 닫 습 니 다. 그 다음 에 실 행 된 이 스 크 립 트 에서 close nightmare 를 출력 합 니 다.
Nightmare 원리
Electron 이 제공 하 는 Browser 환경 을 이용 하여 Node. js 의 I / O 능력 을 갖 추 었 기 때문에 파충류 응용 을 편리 하 게 실현 할 수 있 습 니 다.Nightmare 홈 페이지 에 더 자세 한 소개 가 있 습 니 다.
대체 동작:
  • 브 라 우 저 이벤트: goto, back, forward, refresh,
  • 사용자 이벤트: 클릭, mousedown, mouseup, mouseover, type, insert, select, check, uncheck, selectscrollTo
  • 웹 페이지 에 스 크 립 트 를 주입 합 니 다:. js. css 의 파일 형식 원 리 는 오 일 원숭이 와 차이 가 많 지 않 습 니 다. 자신의 js 코드 를 작성 하여 주입 하 는 것 이 매우 편리 합 니 다
  • wait 함 수 는 지연 시간 이나 dom 요소 에 따라 나타 날 수 있 습 니 다
  • evaluate 는 브 라 우 저의 환경 에서 실행 되 는 스 크 립 트 함수 로 promise 함수
  • 를 되 돌려 줍 니 다.
    완전한 nightmare 파충류 응용 프로그램
    우 리 는 위의 화 제 를 캡 처 하 는 것 을 응용 장면 으로 한다. 필요 한 데 이 터 는 알 고 있 는 화제 정보 로 다음 필드 의 화제 이름 / 화제 의 그림 / 관심 자 수량 / 화제 수량 / 정수 화제 수량 을 포함한다. 그러나 후 세 가 지 는 아버지 화제 에 만 포함 되 기 때문에 먼저 아버지 화 제 를 잡 아야 아들 화 제 를 잡 을 수 있다.또한 이 하위 화 제 는 부모 화제 에서 hover 형식 으로 비동기 로 불 러 옵 니 다. Request / Superagent 로 분석 한 id 를 HTTP 로 전달 해 야 가 져 올 수 있 지만 Nightmare 로 hover 이벤트 로 데 이 터 를 불 러 올 수 있 습 니 다.
    첫 번 째 단 계 는 캡 처 해 야 할 화제 의 깊이 를 얻 습 니 다. 기본 적 인 뿌리 는 현재 알 고 있 는 뿌리 화제 입 니 다.
    /** 
    *           url                
    * @param {string} rootUrl -    url 
    * @param {int} deep -         
    * @param {string} toFile -       
    * @param {Function} cb -        
    */
    async function crawlerTopicsFromRoot (rootUrl, deep, toFile, cb) {
      rootUrl = rootUrl ||'https://www.zhihu.com/topic/19776749/hot'
      toFile = toFile || './topicsTree.json'
      console.time()
      const result = await interactive
          .iAllTopics(rootUrl, deep)
      console.timeEnd()
      util.writeJSONToFile(result['topics'], toFile, cb)
    }
    
    crawlerTopicsFromRoot('', 2, '', _ => {
      console.log('    ')
    })

    그리고 상호작용 함수 의 핵심 함 수 를 진행 합 니 다. 캡 처 를 시작 하기 전에 알 고 있 는 robots. txt 파일 에 가서 캡 처 할 수 있 는 간격 을 확인 하 십시오. 그렇지 않 으 면 timeout 의 오류 가 발생 하기 쉽 습 니 다.
    //           
    const cntObj = queue.shift()
    const url = `https://www.zhihu.com/topic/${cntObj['id']}/hot`
    const topicOriginalInfo = await nightmare
      .goto(url)
      .wait('.zu-main-sidebar') //         
      .evaluate(function () {
       //       
          return document.querySelector('.zu-main-sidebar').innerHTML
      })
    // .....       
    //            
    const hoverElement = `a.zm-item-tag[href$='${childTopics[i]['id']}']`
    const waitElement = `.avatar-link[href$='${childTopics[i]['id']}']`
    const topicAttached = await nightmare
      .mouseover(hoverElement) //   hover  
      .wait(waitElement)
      .evaluate(function () {
          return document.querySelector('.zh-profile-card').innerHTML
      })
      .then(val => {
          return parseRule.crawlerTopicNumbericalAttr(val)
      })
      .catch(error => {
          console.error(error)
      })

    cheerio 는 jQuery 의 selector 라 이브 러 리 로 HTML 세 션 에 적용 되 고 해당 하 는 DOM 요 소 를 얻 을 수 있 습 니 다. 그리고 우 리 는 해당 하 는 DOM 작업 을 할 수 있 습 니 다. - > 삭제 와 검 사 를 할 수 있 습 니 다. 여 기 는 주로 DOM 을 조회 하고 데 이 터 를 얻 는 데 사 용 됩 니 다.
    const $ = require('cheerio')
    /** *           /      /      */
    const crawlerTopicNumbericalAttr = function (html) {
      const $ = cheerio.load(html)
      const keys = ['questions', 'top-answers', 'followers']
      const obj = {}
      obj['avatar'] = $('.Avatar.Avatar--xs').attr('src')
      keys.forEach(key => {
          obj[key] = ($(`div.meta a.item[href$=${key}] .value`).text() || '').trim()
      })
      return obj
    }
    /** *         */
    const crawlerTopics = function (html) {
      const $ = cheerio.load(html)
      const  obj = {}
      const childTopics = crawlerAttachTopic($, '.child-topic')  
      obj['desc'] = $('div.zm-editable-content').text() || ''
      if (childTopics.length > 0) {
          obj['childTopics'] = childTopics
      }
      return obj
    }
    
    /** *         id/   */
    const crawlerAttachTopic = function ($, selector) {
      const topicsSet = []
      $(selector).find('.zm-item-tag').each((index, elm) => {
          const self = $(elm)
          const topic = {}
          topic['id'] = self.attr('data-token')
          topic['value'] = self.text().trim()
          topicsSet.push(topic)
      })
      return topicsSet
    }

    그리고 간단 한 파충류 가 완성 되 었 습 니 다. 최종 적 으로 일부 데이터 형식 을 얻 는 것 은 어 떻 습 니까?
    {
      "value": "rootValue",
      "id": "19776749",
      "fatherId": "-1",
      "desc": "                          。「   」              。          Top1000     。           「   」。            。",
      "cids": [
          "19778317",
          "19776751",
          "19778298",
          "19618774",
          "19778287",
          "19560891"
      ]
    },
    {
      "id": "19778317",
      "value": "  、  、     ",
      "avatar": "https://pic4.zhimg.com/6df49c633_xs.jpg",
      "questions": "3.7M",
      "top-answers": "1000",
      "followers": "91K",
      "fid": "19776749",
      "desc": "                    ,         、  、  、      。",
      "cids": [
          "19551147",
          "19554825",
          "19550453",
          "19552706",
          "19551077",
          "19550434",
          "19552266",
          "19554791",
          "19553622",
          "19553632"
      ]
    },

    총결산
    Nightmare 는 파충류 의 가장 큰 장점 은 데이터 가 있 는 페이지 의 URL 만 알 면 해당 하 는 동기 / 비동기 데 이 터 를 얻 을 수 있 고 HTTP 가 전달 해 야 할 인 자 를 상세 하 게 분석 할 필요 가 없다 는 것 이다.웹 페이지 데 이 터 를 업데이트 할 수 있 는 동작 이 무엇 인지 만 알 면 업 데 이 트 된 HTML 세 션 을 가 져 와 해당 하 는 데 이 터 를 얻 을 수 있 습 니 다. 데모 에 있 는 Nightmare 는 chrome - dev 를 열 어 작 동 하지만 실제 실행 할 때 닫 을 수 있 습 니 다. 닫 으 면 작업 속도 가 어느 정도 올 라 갑 니 다.다음 항목 에는 또 다른 기어 오 르 는 알 수 있 는 움직임 도 포함 되 어 있다.
    데모 소스 주소:https://github.com/williamsta...
    iKcamp 오리지널 신간 '모 바 일 웹 전단 고 효율 개발 실전' 은 이미 아마 존, 경 동, 전당 에서 판매 되 고 있다.
    > > 상해 강 웹 전단 상해 팀 모집 [웹 전단 구조 사], 의향 자 이력서:[email protected] <<
    신청 주소:http://www.huodongxing.com/ev...

    좋은 웹페이지 즐겨찾기