크롤링과 스크래핑?

크롤링 (Crawling) 뉴스 기사 수집

크롤링은 웹사이트의 모든 페이지를 탐색하며 정보를 수집 구조화하는 과정을 의미합니다.

크롤러가 자동으로 웹사이트의 페이지 링크를 따라가며 데이터를 수집합니다.

스크래핑 (Scraping) 유튜브 구독자 좋아요 등 수집

스크래핑은 웹 페이지의 특정 데이터만 추출하는 작업을 의미합니다.

주로 특정 웹사이트에서 필요한 데이터만을 추출하여 가공하는 데 사용됩니다.

 

  • 크롤링: 웹사이트 전체 또는 다수의 페이지를 대상으로 데이터 수집
  • 스크래핑: 특정 페이지에서 필요한 데이터만 추출

 

스크래핑은 별점과 같은 특정 정보를 가져오는 것을 의미 

 

크롤링은 url을 이동하며 웹페이지를 조작해 데이터를 수집하는 것을 의미

 

url, 작성자, 날짜 등의 정보를 수집하기 위해선 Locator가 필요

Locator DOM 트리에서 특정 요소를 선택하는 데 사용

DOM 문서 객체 모델(Document Object Model) HTML, XML 문서를 표현하고 조작하는 데 사용되는 프로그래밍 인터페이스

 

Locator란 즉, CSS selector, Xpath를 가르킴

 

DOMtree란 html코드의 구조를 계층적으로 나타낸 것을 의미

*****HTML*****

<!DOCTYPE html>
<html>
<head>
    <title>Let's crawling</title>
</head>
<body>
    <h1>crawling Nice</h1>
    <p>crawling</p>
</body>
</html>

*****DOMTREE*****

html
├── head
│   └── title
│       └── "Let's crawling"
└── body
    ├── h1
    │   └── "crawling Nice"
    └── p
        └── "crawling"

 

DOMtree의 요소는 노드로 표시

  1. 루트 노드 (Root Node): 트리의 최상위 노드로, HTML 문서 전체를 나타냅니다.
  2. 요소 노드 (Element Node): HTML 요소를 나타내며, 트리의 가지(branch)에 해당합니다.
  3. 텍스트 노드 (Text Node): HTML 요소의 텍스트 내용을 나타냅니다.

DOMTREE형으로 구조화 하여 css xpath 원하는 요소를 찾는 것이 중요

 

css selector

 

css selector는 컴포넌트화된 환경에서 유일한 선택자를 찾기 어려움.

<div class="container">
    <div class="item">
        <h2>Title</h2>
        <p>Content</p>
    </div>
    <div class="item">
        <h2>text</h2>
        <p>item</p>
    </div>
</div>

 

div.item p -> 텍스트 기반으로 검색할 수 없어 2개의 p태그가 선택됨

이걸 xpath화 시키면

//div[@class="container"]/div[@class="item"]/h2[text()="text"]/following-sibling::p

2번째 p태그를 찾을 수 있음

<xpath>
<css selector>

 

부모 및 자식 선택

  1. ancestor: 현재 노드의 모든 조상 노드를 선택합니다.
  2. descendant: 현재 노드의 모든 후손 노드를 선택합니다.
  • XPath: XPath에서는 // 연산자를 사용하여 문서의 모든 위치에서 요소를 선택할 수 있습니다. 또한 ancestor 및 descendant 축을 사용하여 특정 요소의 조상 또는 후손 요소를 선택할 수 있습니다.
  • CSS 선택자: CSS 선택자는 > 및 공백을 사용하여 특정 요소의 직계 자식 또는 하위 요소를 선택할 수 있습니다. 그러나 CSS 선택자에는 조상요소를 선택하는 방법이 없습니다.
  • 직계 자식 선택: .parent > .child
  • 하위 요소 선택: .container .descendant

형제 선택

  1. following-sibling: 현재 노드의 다음 형제 노드들을 선택합니다.
  2. preceding-sibling: 현재 노드의 이전 형제 노드들을 선택합니다.
  • XPath: XPath에서는 following-sibling 및 preceding-sibling 축을 사용하여 현재 요소의 다음 형제 또는 이전 형제 요소를 선택할 수 있습니다.
  • CSS 선택자: CSS 선택자에서는 + 및 ~ 연산자를 사용하여 현재 요소의 다음 형제 요소를 선택할 수 있습니다. 그러나 이전 형제 요소를 선택하는 방법은 없습니다. (+ 는 다음 요소중 첫번째,  ~ 형제요소중 p 요소)

css selector -> p + span (이전 선택 X)

  • 다음 형제 선택: //p/following-sibling::span[1]
  • 이전 형제 선택: //span/preceding-sibling::p[1]  -> ??? 뭐가 선택될지

자식선택

  • XPath: XPath에서는 child 축을 사용하여 현재 요소의 모든 자식 요소를 선택할 수 있습니다.
  • CSS 선택자: CSS 선택자에서는 공백을 사용하여 현재 요소의 모든 하위 요소를 선택할 수 있습니다.

 

.container .child span:nth-child(2)

 

//div[@class="parent"]/div[@class="child"]/span[2]

or

//div[@class="parent"]/div[@class="child"]/span[text()='두 번째 스팬']

 

xpath 장점

  • 양방향 제어 가능 (부모 자식 상위 하위 검색가능)
  • 축(Axes)/함수를 사용하여 특정 노드 선택가능
  • 최신 및 구식 브라우저도 호환가능

단점

  • shadow DOM에는 사용 불가능(iframe -> 개별화된 DOM tree)
  • 속도가 느리고 복잡함

 

css selector 장점

  • 속도가 빠르고 읽기 쉬우며 배우기 쉬움
  • 단일 제어이므로 안정적

단점

  • 단방향이므로 제한적임
  • 복잡하거나 컴포넌트화 되어있으면 로케이터를 구성하기 어려움
  • 텍스트를 기반으로 selector를 구성하지 못함

 

 

Xpath Vs CSS Selector: Key Differences

XPath vs CSS selector Key differences explained with examples, this blog helps to choose the best locators for the automation framework.

testsigma.com

 

puppyteer를 python에서 사용하기 위해 pyppeteer를 사용하는 중이며

사용하기 위해서 공식 문서를 보며 숙지하는게 좋다.

https://miyakogi.github.io/pyppeteer/

 

Pyppeteer’s documentation — Pyppeteer 0.0.25 documentation

Pyppeteer is to be as similar as puppeteer, but some differences between python and JavaScript make it difficult. These are differences between puppeteer and pyppeteer. Element selector method name ($ -> querySelector) In python, $ is not usable for method

miyakogi.github.io

 

비동기로 크롤링을 하기 때문에 pyppeteer를 사용하게 되었다.

 

주로

await page.goto(url, {"waitUntil": "domcontentloaded"})
  • 'load': 페이지의 'load' 이벤트가 발생할 때까지 기다립니다.
  • 'domcontentloaded': 페이지의 'DOMContentLoaded' 이벤트가 발생할 때까지 기다립니다.
  • 'networkidle0': 네트워크가 사용되지 않는 상태(네트워크 요청이 0개 이하)가 되었을 때까지 기다립니다.
  • 'networkidle2': 네트워크가 0.5초 이상 유휴 상태가 될 때까지 기다립니다.

아무 값 없이 url만 입력하게 되면 네트워크 활동이 없을 때 까지 기다리는 상태

그래서 크롤링을 하기 위해선 domcontentloaded를 주로 사용

 

크롤링하려는 웹사이트의 환경과 조건에 맞게 사용

 

먼저 크롤링을 하기 위해 html을 가져와야 하는데 여러 기능이나 패키지가 있겠지만
BeautifulSoup를 사용하여 전체의 html가져와 데이터 파싱 또는 클릭, 입력 기능을 사용할 수 있게 된다.

 

 

click 을 사용하기 위해서 추가 할 selector를 검색 (xpath는 적용 X)

await page.click(selector)

 

만약 클릭을 해야한다 evaluate를 사용하여 click을 시도하는 방법도 있다.

python안에서 javascript코드를 전달해주는 느낌이다.
예시)  2500만큼 스크롤

async def scroll_page(page):
    await page.evaluate("window.scrollBy(0, 2500);")
    await asyncio.sleep(2)

 

스크롤을 한 후 딜레이를 주어 로드 시간을 기다린다.

 

type은 값을 입력하는 기능

await page.type(selector, email)

위와 같이 텍스트박스나 입력란의 selector를 지정하여 오른쪽에는 저장된 값을 넣어주면 된다.

 

 

원하는 동작

1,2,3은 각자 비동기를 자기 일을 하고 있으면서 일정 횟수가 되면 작업을 중지 한다. 그리고 나머지가 끝날때까지 대기

 

그렇게 while문으로 무한대기중이지만 

3개의 작업이 모두 종료되어 조건이 일치할 때 나오도록 설계하였습니다.

 

여기서 문제점은

1,2,3 중에 하나가 작업이 먼저 종료되어 대기중에 있을 때 나머지도 동작을 멈춘다는것입니다.

 

그 이유는 파이썬은 GIL(Global Interpreter Lock) 한 번에 하나의 스레드만 바이트코드를 실행할 수 있는 조건이라서

해당 스레드 즉, 먼저 작업이 종료된 스레드가 CPU를 점유하고 다른스레드의 자리를  마련할 공간이 없어 계속 멈춘상태로 있는 것입니다.

 

그러기위해선 sleep을 주어 스레드가 실행될 공간을 마련해 주는 것 입니다. 이렇게 공평하게 자리를 나눠갖게 하는 것이 해결방법이었습니다.

 

await asyncio.sleep(3)

'Python > crawling' 카테고리의 다른 글

크롤링 관점에서 바라본 Css selector와 Xpath  (0) 2024.05.13
pyppeteer (goto, click, type) 사용법  (0) 2024.03.22

+ Recent posts