Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

첫 번째 Web Scraper 만들기, 1부

Rubyland에는 지난 몇 년 동안 웹 스크래핑 스포트라이트를 받은 두 가지 보석인 Nokogiri와 Mechanize가 있습니다. 우리는 실용적인 예를 들어 행동으로 옮기기 전에 이들 각각에 대한 기사를 씁니다.

주제

  • 웹 스크래핑?
  • 권한
  • 문제
  • 노코기리
  • 추출?
  • 페이지
  • API
  • 노드 탐색

웹 스크래핑?

웹이나 화면 스크래핑보다 더 멋진 용어가 있습니다. 웹 수집 및 웹 데이터 추출은 무슨 일이 일어나고 있는지 즉시 알려줍니다. 웹 페이지에서 데이터 추출을 자동화할 수 있으며 그렇게 복잡하지도 않습니다.

어떤 면에서 이러한 도구를 사용하면 인간의 웹 브라우징을 모방하고 자동화할 수 있습니다. 관심 있는 종류의 데이터만 추출하는 프로그램을 작성합니다. 특정 데이터를 타겟팅하는 것은 CSS 선택기를 사용하는 것만큼 쉽습니다.

몇 년 전에 나는 백만 개의 짧은 비디오가 있지만 대량으로 다운로드할 수 있는 옵션이 없는 일부 온라인 비디오 코스를 구독했습니다. 모든 링크를 직접 거쳐야 했고 두려운 '다른 이름으로 저장'을 직접 해야 했습니다. 그것은 일종의 인간 웹 스크래핑이었습니다. 우리가 그런 종류의 작업을 자동화할 지식이 부족할 때 종종 해야 하는 일이었습니다. 코스 자체는 괜찮았지만 그 이후로는 더 이상 서비스를 이용하지 않았습니다. 너무 지루했습니다.

오늘은 그런 마음을 녹이는 UX에 대해 그다지 신경 쓰지 않을 것입니다. 나를 위해 다운로드를 수행하는 스크레이퍼는 함께 던지는 데 몇 분 밖에 걸리지 않습니다. 별거 아니야!

시작하기 전에 빠르게 분해하겠습니다. 전체를 몇 단계로 압축할 수 있습니다. 먼저 필요한 데이터가 있는 웹 페이지를 가져옵니다. 그런 다음 해당 페이지를 검색하고 추출하려는 정보를 식별합니다.

마지막 단계는 이러한 비트를 대상으로 하고 필요한 경우 슬라이스한 다음 저장 방법과 위치를 결정하는 것입니다. 잘 작성된 HTML은 종종 이 프로세스를 쉽고 즐겁게 만드는 열쇠입니다. 더 복잡한 추출의 경우 잘못 구성된 마크업을 처리해야 하는 경우 고통스러울 수 있습니다.

API는 어떻습니까? 아주 좋은 질문입니다. API를 사용하여 서비스에 액세스할 수 있는 경우 고유한 스크레이퍼를 작성할 필요가 거의 없는 경우가 많습니다. 이 접근 방식은 대부분 그런 종류의 편리함을 제공하지 않는 웹사이트를 위한 것입니다. API가 없으면 웹 사이트에서 정보 추출을 자동화하는 유일한 방법인 경우가 많습니다.

이 스크래핑 작업이 실제로 어떻게 작동하는지 물을 수 있습니다. 깊은 끝으로 뛰어들지 않고 짧은 대답은 트리 데이터 구조를 순회하는 것입니다. Nokogiri는 사용자가 제공한 문서에서 이러한 데이터 구조를 구축하고 추출할 관심 비트를 대상으로 지정할 수 있습니다. 예를 들어 CSS는 트리 탐색, 트리 데이터 구조 검색을 위해 작성된 언어이며 데이터 추출에 사용할 수 있습니다.

사용할 수 있는 많은 접근 방식과 솔루션이 있습니다. Rubyland에는 몇 년 동안 스포트라이트를 받은 두 개의 보석이 있습니다. 많은 사람들이 HTML 스크래핑 요구 사항에 대해 여전히 Nokogiri 및 Mechanize에 의존합니다. 둘 다 테스트를 거쳐 사용하기 쉬우면서도 성능이 뛰어난 것으로 입증되었습니다. 우리는 둘 다 살펴볼 것입니다. 하지만 그 전에 잠시 시간을 내어 이 짧은 소개 시리즈의 끝에서 해결하려는 문제를 해결하고자 합니다.

권한

스크랩을 시작하기 전에 데이터 추출을 위해 액세스하려는 사이트의 권한이 있는지 확인하십시오. 예를 들어 사이트에 API 또는 RSS 피드가 있는 경우 원하는 콘텐츠를 얻는 것이 더 쉬울 뿐만 아니라 법적 선택이 될 수도 있습니다.

사이트에서 대규모 스크래핑을 수행하면 모든 사람이 감사하는 것은 아닙니다. 당연히 그렇습니다. 관심 있는 특정 사이트에서 교육을 받고 곤경에 빠지지 마십시오. 심각한 피해를 입힐 가능성은 낮지만, 무의식적으로 위험을 감수하는 것은 올바른 방법이 아닙니다.

문제

새로운 팟캐스트를 만들어야 했습니다. 내가 원하는 디자인이 아니었고, 새로운 글을 올리는 방식도 싫었다. 빌어먹을 WYSIWYG들! 약간의 맥락. 약 2년 전에 저는 제 팟캐스트의 첫 번째 버전을 만들었습니다. 아이디어는 Sinatra와 함께 놀면서 초경량 제품을 만드는 것이었습니다. 나는 거의 모든 것을 맞춤 제작했기 때문에 예상치 못한 몇 가지 문제에 부딪쳤습니다.

Rails에서 온 것은 확실히 감사한 교육적 여정이었지만 GitHub 페이지를 통해 GitHub를 통해 배포할 수 있는 정적 사이트를 사용하지 않은 것을 빨리 후회했습니다. 새로운 에피소드를 배포하고 유지 관리하는 데 내가 찾던 단순함이 부족했습니다. 한동안 나는 더 큰 물고기를 튀기기로 결정하고 대신 새로운 팟캐스트 자료를 만드는 데 집중했습니다.

지난 여름에 저는 진지하게 시작했고 GitHub 페이지를 통해 호스팅되는 Middleman 사이트에서 작업했습니다. 시즌 2에서는 신선한 것을 원했습니다. 새롭고 단순화된 디자인, 새로운 에피소드 게시를 위한 Markdown, 그리고 헤로쿠와 주먹다짐이 없습니다. 문제는 Middleman과 함께 작업하기 위해 먼저 가져오고 변환해야 하는 139개의 에피소드가 있다는 것입니다.

게시물의 경우 Middleman은 .markdown을 사용합니다. 기본적으로 내 데이터베이스를 대체하는 데이터에 대한 주요 내용이 있는 파일입니다. 이 전송을 손으로 수행하는 것은 139개의 에피소드에 대한 옵션이 아닙니다. 그것이 바로 계산입니다. 이전 웹사이트의 HTML을 구문 분석하고 관련 콘텐츠를 스크랩하여 Middleman에 새 팟캐스트 에피소드를 게시하는 데 사용하는 블로그 게시물로 전송하는 방법을 찾아야 했습니다.

따라서 다음 세 개의 기사를 통해 이러한 작업을 위해 Rubyland에서 일반적으로 사용되는 도구를 소개하겠습니다. 결국, 우리는 실용적인 것을 보여주기 위해 내 솔루션을 살펴볼 것입니다.

노코기리

Ruby/Rails를 처음 접하더라도 이 작은 보석에 대해 이미 들어봤을 가능성이 매우 높습니다. 이름은 자주 떨어지고 쉽게 붙습니다. 많은 사람들이 노코기리가 "톱"을 뜻하는 일본어라는 것을 알고 있는지 확신할 수 없습니다.

도구의 기능을 이해하면 적절한 이름입니다. 이 보석의 제작자는 사랑스러운 Tenderlove, Aaron Patterson입니다. Nokogiri는 XML 및 HTML 문서를 데이터 구조(더 정확하게는 트리 데이터 구조)로 변환합니다. 이 도구는 빠르고 멋진 인터페이스도 제공합니다. 전반적으로 HTML 스크래핑 요구 사항을 처리하는 매우 강력한 라이브러리입니다.

HTML 구문 분석뿐만 아니라 Nokogiri를 사용할 수 있습니다. XML도 공정한 게임입니다. 로드하는 문서를 탐색하기 위해 XML 경로 언어와 CSS 인터페이스의 옵션을 제공합니다. XML 경로 Language, 줄여서 XPath는 쿼리 언어입니다.

XML 문서에서 노드를 선택할 수 있습니다. CSS 선택기는 초보자에게 더 친숙할 가능성이 큽니다. 작성하는 스타일과 마찬가지로 CSS 선택기를 사용하면 추출하려는 페이지의 특정 섹션을 매우 쉽게 대상으로 지정할 수 있습니다. 특정 목적지를 목표로 할 때 노코기리에게 당신이 무엇을 추구하고 있는지 알려주기만 하면 됩니다.

페이지

항상 시작해야 하는 것은 관심 있는 실제 페이지를 가져오는 것입니다. 구문 분석할 Nokogiri 문서의 종류를 지정합니다(예:XML 또는 HTML).

노코기리::XML노코기리::HTML

some_scraper.rb

require "nokogiri"require "open-uri"page =Nokogiri::XML(File.open("some.xml"))page =Nokogiri::HTML(File.open("some.html")) 

Nokogiri:XMLNokogiri:HTML IO 개체 또는 String 개체를 사용할 수 있습니다. 위에서 일어나는 일은 간단합니다. open-uri를 사용하여 지정된 페이지를 열고 가져옵니다. 그런 다음 해당 구조, XML 또는 HTML을 새 Nokogiri 문서에 로드합니다. XML은 초보자가 자주 다루어야 하는 것이 아닙니다.

따라서 지금은 HTML 구문 분석에 집중하는 것이 좋습니다. open-uri가 필요한 이유 ? Ruby 표준 라이브러리의 이 모듈을 사용하면 큰 소란 없이 사이트를 가져올 수 있습니다. IO 개체는 공정한 게임이므로 open-uri를 쉽게 사용할 수 있습니다. .

API

미니 예제를 통해 이것을 실행해 보겠습니다.

at_css

some_podcast_scraper.rb

require 'nokogiri'require "open-uri"url ='https://betweenscreens.fm/'page =Nokogiri::HTML(open(url))header =page.at_css("h2.post-title" )title =header.textputs "이것은 최신 에피소드의 원시 헤더입니다:#{header}"puts "이것은 최신 에피소드의 제목입니다:#{title}"

여기서 수행한 작업은 일반적으로 웹 스크래핑과 관련된 모든 단계를 나타냅니다. 필요한 URL과 가져와야 하는 사이트를 결정하고 새 Nokogiri 문서에 로드합니다. 그런 다음 해당 페이지를 열고 특정 섹션을 타겟팅합니다.

여기에서는 최신 에피소드의 제목만 알고 싶었습니다. at_css 사용 h2.post-title 메소드 및 CSS 선택기 추출 지점을 목표로 삼는 데 필요한 전부였습니다. 이 방법을 사용하면 이 단일 요소만 긁을 것입니다. 이것은 우리에게 전체 선택기를 제공합니다. 이것은 대부분 우리가 필요로 하는 것이 아닙니다. 따라서 text를 통해 이 노드의 내부 텍스트 부분만 추출합니다. 방법. 비교를 위해 아래의 헤더와 텍스트 모두에 대한 출력을 확인할 수 있습니다.

출력

최신 에피소드의 원본 제목입니다. 

David Heinemeier Hansson

다음 에피소드의 제목입니다. 최신 에피소드:David Heinemeier Hansson

이 예제는 응용 프로그램이 매우 제한되어 있지만 모든 구성 요소와 이해해야 하는 모든 단계를 포함하고 있습니다. 이렇게 간단해서 좋은 것 같아요. 이 예에서는 명확하지 않을 수 있으므로 이 도구가 얼마나 강력한지 지적하고 싶습니다. Nokogiri 스크립트로 할 수 있는 다른 작업을 살펴보겠습니다.

주의!

초보자이고 이에 필요한 HTML을 타겟팅하는 방법을 잘 모르는 경우 온라인에서 검색하여 브라우저에서 웹사이트의 콘텐츠를 검사하는 방법을 찾는 것이 좋습니다. 기본적으로 모든 주요 브라우저는 요즘 이 프로세스를 정말 쉽게 만듭니다.

Chrome에서는 웹사이트의 요소를 마우스 오른쪽 버튼으로 클릭하고 검사 옵션을 선택하기만 하면 됩니다. 그러면 브라우저 하단에 사이트 DOM의 엑스레이와 같은 것을 보여주는 작은 창이 열립니다. 더 많은 옵션이 있으므로 Google에서 시간을 내어 스스로 학습하는 것이 좋습니다. 현명하게 보내는 시간입니다!

css

css 메소드는 선택의 단일 요소뿐만 아니라 페이지의 검색 기준과 일치하는 모든 요소를 ​​제공합니다. 꽤 깔끔하고 직설적!

some_scraper.rb

require 'nokogiri'require "open-uri"url ='https://betweenscreens.fm/'page =Nokogiri::HTML(open(url))headers =page.css("h2.post-title" )headers.each 할 |헤더| puts "최신 에피소드의 원본 제목입니다. #{header}"endheaders.each do |header| puts "이것은 최신 에피소드의 제목입니다:#{header.text}"end

출력

최신 에피소드의 원본 제목입니다. 

David Heinemeier Hansson

원본 제목입니다. 최신 에피소드의 제목:

Zach Holman

최신 에피소드의 원본 제목입니다.

Joel Glovier

최신 에피소드의 원본 제목입니다.

João Ferreira

최신 에피소드의 원본 제목입니다.

Corwin Harrell

최신 에피소드의 원본 제목입니다.

Roberto Machado

최신 에피소드의 원본 제목입니다.

James Edward Gray II

최신 에피소드의 제목입니다. 에피소드:David Heinemeier Hansson최신 에피소드 제목:Zach Holman최신 에피소드 제목:Joel Glovier입니다. 최신 에피소드 제목:João Ferreira최신 에피소드 제목:Corwin Harrell최신 에피소드 제목:Roberto Machado최신 에피소드 제목:James Edward Gray II

이 예제에서 유일한 약간의 차이점은 원시 헤더를 먼저 반복한다는 것입니다. 또한 text로 내부 텍스트를 추출했습니다. 방법. Nokogiri는 페이지 끝에서 자동으로 멈추고 자동으로 페이지 매김을 따르려고 시도하지 않습니다.

각 에피소드의 날짜와 자막과 같이 좀 더 많은 정보를 원한다고 가정해 보겠습니다. 위의 예를 간단히 확장할 수 있습니다. 어쨌든 이 단계를 단계적으로 수행하는 것이 좋습니다. 약간의 작업을 수행하고 그 과정에서 더 많은 복잡성을 추가하십시오.

some_scraper.rb

require 'nokogiri'require "open-uri"url ='https://betweenscreens.fm/'page =Nokogiri::HTML(open(url))articles =page.css("article.index-article" )articles.each 할 |기사| header =article.at_css("h2.post-title") date =article.at_css(".post-date") subtitle =article.at_css(".topic-list") puts "이것은 원시 헤더입니다:#{ header}" puts "이것은 원시 날짜:#{date}" puts "이것은 원시 자막입니다:#{subtitle}\n\n" puts "텍스트 헤더:#{header.text}" puts " 이것은 텍스트 날짜입니다:#{date.text}" puts "텍스트 자막입니다:#{subtitle.text}\n\n"end

출력

이것은 원시 헤더입니다:

David Heinemeier Hansson

이것은 원시 날짜입니다:다음은 원본 자막입니다.

Rails 커뮤니티 | 톤 | 기술적 불일치 | 지역사회 치안 | 배은망덕함 | 허용되지 않는 멍청이 | 베이스캠프 | 오픈 소스 페르소나 | 포부 | 동기 보호 | 청중 다루기 | 압력 | 정직 | 다양한 의견 | 잡담

텍스트 헤더입니다:David Heinemeier Hansson텍스트 날짜:10월 18일 | 2016텍스트 부제:Rails 커뮤니티 | 톤 | 기술적 불일치 | 지역사회 치안 | 배은망덕함 | 허용되지 않는 멍청이 | 베이스캠프 | 오픈 소스 페르소나 | 포부 | 동기 보호 | 청중 다루기 | 압력 | 정직 | 다양한 의견 | 잡담 이것은 원시 헤더입니다.

Zach Holman

이것은 원시 날짜입니다:10월 12일 | 2016이것은 원본 자막입니다.

해고당하기 | 금기 | 투명도 | 다른 관점 | 타이밍 | 성장 단계 | 고용 및 데이트 | 관리자 | 임의취업 | 기술 산업 | 유럽 ​​| 낮은 교수형 과일 | 성과개선 방안 | 목표 달성 | 깜짝 발사 | 빠른 발사 | 실수 | 기업문화 | 커뮤니케이션

텍스트 헤더입니다:Zach Holman텍스트 날짜:10월 12일 | 2016텍스트 부제:해고당하기 | 금기 | 투명도 | 다른 관점 | 타이밍 | 성장 단계 | 취업 및 데이트 | 관리자 | 임의취업 | 기술 산업 | 유럽 ​​| 낮은 교수형 과일 | 성과개선 방안 | 목표 달성 | 깜짝 발사 | 빠른 발사 | 실수 | 기업문화 | CommunicationThis는 원시 헤더입니다:

Joel Glovier

이것은 원시 날짜입니다:10월 10일 | 2016이것은 원본 자막입니다.

디지털 제품 디자인 | 제품 디자인 @ GitHub | 사랑의 디자인 | 주문 및 혼돈 | 그리기 | 웹 디자인 | 병원런 | 다양성 | 창업문화 | 삶의 질 향상 | 큐어인터내셔널 | 엠버 | 오프라인 우선 | 병원정보시스템 | 디자이너 & 오픈 소스

텍스트 헤더입니다:Joel Glovier텍스트 날짜:10월 10일 | 2016텍스트 부제:디지털 제품 디자인 | 제품 디자인 @ GitHub | 사랑의 디자인 | 질서와 혼돈 | 그리기 | 웹 디자인 | 병원런 | 다양성 | 창업문화 | 삶의 질 향상 | 큐어인터내셔널 | 엠버 | 오프라인 우선 | 병원정보시스템 | 디자이너 및 오픈 소스이것은 원시 헤더입니다.

João Ferreira

이것은 원시 날짜입니다:원본 자막입니다.

Masters @ Work | 서브비주얼 | 마감일 | 디자인 개성 | 디자인 문제 | 팀 | 밀고 봉투 | 즐거운 경험 | 완벽한 디테일 | 회사 가치

텍스트 헤더:João Ferreira텍스트 날짜:8월 26일 | 2015텍스트 부제:Masters @ Work | 서브비주얼 | 마감일 | 디자인 개성 | 디자인 문제 | 팀 | 밀고 봉투 | 즐거운 경험 | 완벽한 디테일 | 회사 값이것은 원시 헤더입니다.

Corwin Harrell

이것은 원시 날짜입니다:8월 6일 | 2015원본 자막입니다.

Q&A | 01 | 대학 | 그래픽 디자인 | 디자인 설정 | 숭고한 | 원자 | 생각봇 | 근무지 | 협업 및 페어링 | Vim 옹호자 | 일상 | 스탠드업 | 클라이언트 | 커피 산책 | Investment Fridays |

텍스트 헤더입니다:Corwin Harrell텍스트 날짜:Aug 06 | 2015텍스트 부제:Q&A | 01 | 대학 | 그래픽 디자인 | 디자인 설정 | 숭고한 | 원자 | 생각봇 | 근무지 | 협업 및 페어링 | Vim 옹호자 | 일상 | 스탠드업 | 클라이언트 | 커피 산책 | 투자 금요일 |이것은 원시 헤더입니다:

Roberto Machado

이것은 원시 날짜입니다:원본 자막입니다.

CEO @ Subvisual | RubyConf 포르투갈 | 크리에이터 스쿨 | 컨설팅 | 회사의 롤모델 | 그룹 친구 | 포르투갈 스타트업 | 브랜드 변경 | 사용된 기술 | JS 프레임워크 | TDD& BDD | 시작 실수 | 학습 문화 | 젊은 기업가

텍스트 헤더입니다:Roberto Machado텍스트 날짜:Aug 03 | 2015텍스트 자막입니다. CEO @ Subvisual | RubyConf 포르투갈 | 크리에이터 스쿨 | 컨설팅 | 회사의 롤모델 | 그룹 친구 | 포르투갈 스타트업 | 브랜드 변경 | 사용된 기술 | JS 프레임워크 | TDD 및 BDD | 시작 실수 | 학습 문화 | 젊은 기업가 이것은 원시 헤더입니다.

James Edward Gray II

이것은 원시 날짜입니다:이것은 원본 자막입니다:

스크린캐스팅 | 적은 코드 | 코드 읽기 | 막히기 | Rails의 코드베이스 | 코드뉴비 | 작은 예 | 향후 계획 | 엿보기 코드 | 주파수 및 가격

텍스트 헤더:James Edward Gray II텍스트 날짜:7월 30일 | 2015텍스트 자막입니다. Screencasting | 적은 코드 | 코드 읽기 | 막히기 | Rails의 코드베이스 | 코드뉴비 | 작은 예 | 향후 계획 | 엿보기 코드 | 빈도 및 가격

이 시점에서 우리는 이미 가지고 놀 데이터가 있습니다. 원하는 방식으로 구조화하거나 도살할 수 있습니다. 위의 내용은 단순히 읽을 수 있는 방식으로 우리가 가진 것을 보여주어야 합니다. 물론 text와 함께 정규식을 사용하여 이들 각각에 대해 더 깊이 파고들 수 있습니다. 방법.

실제 팟캐스트 문제를 해결할 때 이에 대해 더 자세히 살펴보겠습니다. 정규 표현식에 대한 수업은 아니지만 더 많은 작업이 실행되는 것을 볼 수 있습니다. 하지만 걱정할 필요는 없습니다.

속성

이 단계에서 유용할 수 있는 것은 href를 추출하는 것입니다. 개별 에피소드에도 적용됩니다. 이보다 더 간단할 수 없습니다.

some_scraper.rb

require 'nokogiri'require "open-uri"url ='https://betweenscreens.fm/'page =Nokogiri::HTML(open(url))articles =page.css("article.index-article" )articles.each 할 |기사| 헤더 =article.at_css("h2.post-title") 날짜 =article.at_css(".post-date") 자막 =article.at_css(".topic-list") 링크 =article.at_css("h2.post -title a") podcast_url ="https://betweenscreens.fm/" puts "이것은 원시 헤더입니다:#{header}" puts "이것은 원시 날짜입니다:#{date}" puts "이것은 원시 자막입니다 :#{subtitle}" puts "원본 링크:#{link}\n\n" puts "텍스트 헤더:#{header.text}" puts "텍스트 날짜:#{날짜. text}" puts "이것은 텍스트 자막입니다:#{subtitle.text}" puts "이것은 원시 링크입니다:#{podcast_url}#{link[:href]}\n\n"end

여기서 주의해야 할 가장 중요한 부분은 [:href]입니다. 및 podcast_url . [:]에 태그를 지정하면 대상 선택기에서 속성을 간단히 추출할 수 있습니다. 조금 더 추상화했지만 아래에서 어떻게 작동하는지 더 명확하게 볼 수 있습니다.

...href =article.at_css("h2.post-title a")[:href]...

완전하고 유용한 URL을 얻기 위해 루트 도메인을 변수에 저장하고 각 에피소드에 대한 전체 URL을 구성했습니다.

...podcast_url ="https://betweenscreens.fm/"puts "이것은 원시 링크입니다:#{podcast_url}#{link[:href]}\n\n"...

출력을 간단히 살펴보겠습니다.

출력

이것은 원시 헤더입니다:

Jason Long

이것은 원시 날짜입니다:이것은 원본 자막입니다.

오픈 소스 | 공감 | 낮은 장벽 | 학습 도구 | 디자인 기여 | 힘내 웹사이트 | 브랜딩 | 깃허브 | 네오빔 | 티먹스 | 디자인 사랑 | 청중 알기 | 작품을 보여주는 | 드리블 | 진행 | 아이디어

원본 링크입니다. Jason Long 텍스트 헤더입니다. Jason Long텍스트 날짜:10월 25일 | 2016텍스트 자막입니다:오픈 소스 | 공감 | 낮은 장벽 | 학습 도구 | 디자인 기여 | 힘내 웹사이트 | 브랜딩 | 깃허브 | 네오빔 | 티먹스 | 디자인 사랑 | 청중 알기 | 작품을 보여주는 | 드리블 | 진행 | IdeasThe href:https://betweenscreens.fm/episodes/143/이것은 원시 헤더입니다:

David Heinemeier Hansson

원시 날짜입니다. 다음은 원본 자막입니다.

Rails 커뮤니티 | 톤 | 기술적 불일치 | 지역사회 치안 | 배은망덕함 | 허용되지 않는 멍청이 | 베이스캠프 | 오픈 소스 페르소나 | 포부 | 동기 보호 | 청중 다루기 | 압력 | 정직 | 다양한 의견 | 잡담

원본 링크입니다. David Heinemeier Hansson 텍스트 헤더입니다. David Heinemeier Hansson텍스트 날짜입니다:10월 18일 | 2016텍스트 부제:Rails 커뮤니티 | 톤 | 기술적 불일치 | 지역사회 치안 | 배은망덕함 | 허용되지 않는 멍청이 | 베이스캠프 | 오픈 소스 페르소나 | 포부 | 동기 보호 | 청중 다루기 | 압력 | 정직 | 다양한 의견 | 잡담 이것은 href입니다:https://betweenscreens.fm/episodes/142/이것은 원시 헤더입니다:

Zach Holman

이것은 원시 날짜입니다. 이것은 원본 자막입니다.

해고당하기 | 금기 | 투명도 | 다른 관점 | 타이밍 | 성장 단계 | 고용 및 데이트 | 관리자 | 임의취업 | 기술 산업 | 유럽 ​​| 낮은 교수형 과일 | 성과개선 방안 | 목표 달성 | 깜짝 발사 | 빠른 발사 | 실수 | 기업문화 | 커뮤니케이션

원본 링크입니다. Zach Holman 텍스트 헤더입니다. Zach Holman텍스트 날짜입니다. 10월 12일 | 2016텍스트 부제:해고당하기 | 금기 | 투명도 | 다른 관점 | 타이밍 | 성장 단계 | 취업 및 데이트 | 관리자 | 임의취업 | 기술 산업 | 유럽 ​​| 낮은 교수형 과일 | 성과개선 방안 | 목표 달성 | 깜짝 발사 | 빠른 발사 | 실수 | 기업문화 | CommunicationThis is href:https://betweenscreens.fm/episodes/141/이것은 원시 헤더입니다:

Joel Glovier

이것은 원시 날짜입니다:이것은 원본 자막입니다.

디지털 제품 디자인 | 제품 디자인 @ GitHub | 사랑의 디자인 | 주문 및 혼돈 | 그리기 | 웹 디자인 | 병원런 | 다양성 | 창업문화 | 삶의 질 향상 | 큐어인터내셔널 | 엠버 | 오프라인 우선 | 병원정보시스템 | 디자이너 & 오픈 소스

원본 링크입니다. Joel Glovier 텍스트 헤더입니다:Joel Glovier텍스트 날짜:10월 10일 | 2016텍스트 부제:디지털 제품 디자인 | 제품 디자인 @ GitHub | 사랑의 디자인 | 질서와 혼돈 | 그리기 | 웹 디자인 | 병원런 | 다양성 | 창업문화 | 삶의 질 향상 | 큐어인터내셔널 | 엠버 | 오프라인 우선 | 병원정보시스템 | 디자이너 및 오픈 소스이것은 href입니다:https://betweenscreens.fm/episodes/140/이것은 원시 헤더입니다:

João Ferreira

이것은 원시 날짜입니다:원본 자막입니다.

Masters @ Work | 서브비주얼 | 마감일 | 디자인 개성 | 디자인 문제 | 팀 | 밀고 봉투 | 즐거운 경험 | 완벽한 디테일 | 회사 가치

다음은 원시 링크입니다. João Ferreira 텍스트 헤더입니다:João Ferreira텍스트 날짜:8월 26일 | 2015텍스트 부제:Masters @ Work | 서브비주얼 | 마감일 | 디자인 개성 | 디자인 문제 | 팀 | 밀고 봉투 | 즐거운 경험 | 완벽한 디테일 | 회사 가치 이것은 href입니다:https://betweenscreens.fm/episodes/139/이것은 원시 헤더입니다:

Corwin Harrell

이것은 원시 날짜입니다. 원본 자막입니다.

Q&A | 01 | 대학 | 그래픽 디자인 | 디자인 설정 | 숭고한 | 원자 | 생각봇 | 근무지 | 협업 및 페어링 | Vim 옹호자 | 일상 | 스탠드업 | 클라이언트 | 커피 산책 | Investment Fridays |

원본 링크입니다. Corwin Harrell 텍스트 헤더입니다. Corwin Harrell텍스트 날짜:8월 6일 | 2015텍스트 부제:Q&A | 01 | 대학 | 그래픽 디자인 | 디자인 설정 | 숭고한 | 원자 | 생각봇 | 근무지 | 협업 및 페어링 | Vim 옹호자 | 일상 | 스탠드업 | 클라이언트 | 커피 산책 | 투자 금요일 |이것은 href입니다:https://betweenscreens.fm/episodes/138/이것은 원시 헤더입니다:

Roberto Machado

이것은 원시 날짜입니다:원본 자막입니다.

CEO @ Subvisual | RubyConf 포르투갈 | 크리에이터 스쿨 | 컨설팅 | 회사의 롤모델 | 그룹 친구 | 포르투갈 스타트업 | 브랜드 변경 | 사용된 기술 | JS 프레임워크 | TDD& BDD | 시작 실수 | 학습 문화 | 젊은 기업가

원본 링크입니다. Roberto Machado 텍스트 헤더입니다. Roberto Machado텍스트 날짜:Aug 03 | 2015텍스트 자막입니다. CEO @ Subvisual | RubyConf 포르투갈 | 크리에이터 스쿨 | 컨설팅 | 회사의 롤모델 | 그룹 친구 | 포르투갈 스타트업 | 브랜드 변경 | 사용된 기술 | JS 프레임워크 | TDD 및 BDD | 시작 실수 | 학습 문화 | 젊은 기업가 이것은 href:https://betweenscreens.fm/episodes/137/

깔끔하지 않나요? 동일한 작업을 수행하여 [:class]를 추출할 수 있습니다. 선택기입니다.

require 'nokogiri'require "open-uri"url ='https://betweenscreens.fm/'page =Nokogiri::HTML(open(url))body_classes =page.at_css("body")[:class ]

해당 노드에 둘 이상의 클래스가 있는 경우 모든 클래스의 목록이 표시됩니다.

노드 탐색

  • 부모
  • 어린이
  • 이전_형제님
  • 다음 형제자매

우리는 CSS나 jQuery에서 트리 구조를 다루는 데 익숙합니다. Nokogiri가 이러한 나무 내에서 이동할 수 있는 편리한 API를 제공하지 않으면 고통스러울 것입니다.

some_scraper.rb

require 'nokogiri'require "open-uri"url ='https://betweenscreens.fm/'page =Nokogiri::HTML(open(url))header =page.at_css("h2.post-title" )header_children =page.at_css("h2.post-title").childrenheader_parent =page.at_css("h2.post-title").parentheader_prev_sibling =page.at_css("h2.post-title").previous_siblingputs "#{ 헤더}\n\n"입력 "#{header_children}\n\n"입력 "#{header_parent}\n\n"입력 "#{header_prev_sibling}\n\n"

출력

#header

제이슨 롱

#header_children제이슨 긴 #header_parent

제이슨 롱

오픈 소스 | 공감 | 낮은 장벽 | 학습 도구 | 디자인 기여 | 힘내 웹사이트 | 브랜딩 | 깃허브 | 네오빔 | 티먹스 | 디자인 사랑 | 청중 알기 | 작품을 보여주는 | 드리블 | 진행 | 아이디어

#header_previous_sibling

직접 볼 수 있듯이 이것은 매우 강력한 기능입니다. 특히 .parent 한번에 모을 수 있었다. 많은 노드를 손으로 정의하는 대신 도매로 수집할 수 있습니다.

더 복잡한 순회를 위해 이들을 연결할 수도 있습니다. 물론 원하는 만큼 복잡하게 할 수 있지만 간단하게 유지하도록 주의하겠습니다. 그것은 곧 조금 다루기 힘들고 이해하기 어려워질 수 있습니다. "간단히 해, 바보야!"를 기억하십시오.

...header_parent_parent =page.at_css("h2.post-title").parent.parentheader_prev_sibling_parent_children =page.at_css("h2.post-title").previous_sibling.parent.children...

some_scraper.rb

require 'nokogiri'require "open-uri"url ='https://betweenscreens.fm/'page =Nokogiri::HTML(open(url))header =page.at_css("h2.post-title" )header_prev_sibling_children =page.at_css("h2.post-title").previous_sibling.childrenheader_parent_parent =page.at_css("h2.post-title").parent.parentheader_prev_sibling_parent =page.at_css("h2.post-title"). previous_sibling.parentheader_prev_sibling_parent_children =page.at_css("h2.post-title").previous_sibling.parent.childrenputs "#{header}\n\n" "#{header_prev_sibling_children}\n\n" "#{header_parent_parent}\ n\n" "#{header_prev_sibling_parent}\n\n"입력 "#{header_prev_sibling_parent_children}\n\n"

출력

#header

제이슨 롱

#header_previous_sibling_children10월 25일 | 2016#header_parent_parent
  • 제이슨 롱

    오픈 소스 | 공감 | 낮은 장벽 | 학습 도구 | 디자인 기여 | 힘내 웹사이트 | 브랜딩 | 깃허브 | 네오빔 | 티먹스 | 디자인 사랑 | 청중 알기 | 작품을 보여주는 | 드리블 | 진행 | 아이디어

  • #header_previous_sibling_parent

    Jason Long

    Open source | Empathy | Lower barriers | Learning tool | Design contributions | Git website | Branding | GitHub | Neovim | Tmux | Design love | Knowing audiences | Showing work | Dribbble | Progressions | Ideas

    #header_previous_sibling_parent_children

    Jason Long

    Open source | Empathy | Lower barriers | Learning tool | Design contributions | Git website | Branding | GitHub | Neovim | Tmux | Design love | Knowing audiences | Showing work | Dribbble | Progressions | Ideas

    Final Thoughts

    Nokogiri is not a huge library, but it has a lot to offer. I recommend you play with what you have learned thus far and expand your knowledge through its documentation when you hit a wall. But don’t get yourself into trouble!

    This little intro should get you well on your way to understanding what you can do and how it works. I hope you will explore it a bit more on your own and have some fun with it. As you will find out on your own, it’s a rich tool that keeps on giving.