Puppeteer를 사용하여 터키에서 공개 구인 광고 가져오기

Puppeteer는 웹 스크래핑, 자동화, 테스트에 적합합니다. 나는 그것으로 연습을하고 싶었다. 목록에서 공개 구인 광고를 가져오는 앱을 만들었습니다.

몇 가지 인형극 방법을 설명하겠습니다.

실행: 브라우저 열기
newPage: 브라우저에 탭을 만듭니다.
goto(url, { waitUntil: 'networkidle0'}): URL을 탐색합니다. (waitUntil: 'networkidle0': 최소 500ms 동안 네트워크 연결이 0개 이하인 경우 탐색이 완료된 것으로 간주합니다.)
waitforSelector: 선택기가 페이지에 나타날 때까지 기다립니다.
$(): document.querySelector()와 같이 선택자 문자열과 일치하는 요소를 선택합니다.
$$(): document.querySelectorAll()과 같이 선택자 문자열과 일치하는 모든 요소를 ​​선택합니다.
$eval(): 먼저 일치하는 요소를 선택하고 함수 매개변수에 전달한 다음 이 함수에서 해당 요소를 처리할 수 있습니다.



먼저 크롤링하려는 웹사이트 코드를 검토해 보겠습니다. 슬라이더가 있고 ul 요소입니다. 클래스 이름은 슬라이드입니다. 그리고 내부에 광고(li 요소)가 있습니다. 우리는 그들을 잡을 수 있습니다.

const slides = await newPage.$$('ul.slides li');




백엔드



index.js

require('dotenv').config();

const PORT = process.env.PORT || 3000;

const express = require('express');
const cors = require('cors');

const app = express();

app.use(cors());
app.use(express.json());

app.use(express.static('public'));

app.use('/ads', require('./routes/ads'),
    (req, res) => res.status(500).send('Internal server error'));

app.listen(PORT, () => console.log(`App started on http://localhost: ${PORT}`));


경로/ads.js

우리는 이러한 요소를 잡고 싶습니다.



const puppeteer = require('puppeteer');
const router = require('express').Router();

router.get('/', async (req, res, next) => {
    try {
        const browser = await puppeteer.launch();
        const newPage = await browser.newPage();

        const adsUrl = process.env.PUBLIC_ADS_URL;

        await newPage.goto(adsUrl, { waitUntil: 'networkidle0' });
        await newPage.waitForSelector('ul.slides');

        const slides = await newPage.$$('ul.slides li');

        const ads = [];

        for (s of slides) {
            const avatar = await s.$eval('.avatar img', el => el.src);
            const organasation = await s.$eval('h5 span.black', el => el.innerText);
            const title = await s.$eval('h5 span.patrol', el => el.innerText);
            const dateRange = await s.$eval('h5 span.h5date', el => el.innerText);
            const link = await s.$eval('a', el => el.href);

            ads.push({
                avatar,
                organasation,
                title,
                dateRange,
                link
            });
        }

        await browser.close();

        return res.status(200).json(ads);
    } catch {
        next();
    }
});

module.exports = router;


결과

Thunder 클라이언트 대 코드 확장을 사용합니다.



프런트엔드



index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Public Ads</title>
    <style>
        a {
            text-decoration: none;
            color: #000;
        }
            a:hover {
                color: #ff0000;
            }

        #publicAdsTable {
            border-collapse: true;
            width: 90%;
        }
            #publicAdsTable th, td {
                padding: 1rem;
                border: 1px solid #ccc;
            }
    </style>
</head>
<body>
    <h1 id="loading">Loading...</h1>
    <table id="publicAdsTable">
        <thead>
            <th></th>
            <th></th>
            <th>Organasation</th>
            <th>Job Ad Title</th>
            <th>Date Range</th>
            <th>Go</th>
        </thead>
        <tbody></tbody>
    </table>

    <script>
        const publicAdsTable = document.getElementById('publicAdsTable');
        const loadingEl = document.getElementById('loading');

        const ads = fetch('http://localhost:5000/ads')
            .then(response => {
                if (response.ok) {
                    loadingEl.style.display = 'none';

                    const tbody = publicAdsTable.querySelector('tbody');

                    response.json().then(json => json.forEach((ad, index) => tbody.innerHTML +=
                        `<tr>
                            <td>${index + 1}</td>
                            <td><img src="${ad.avatar}" alt="${ad.title}"></td>
                            <td>${ad.organasation}</td>
                            <td>${ad.title}</td>
                            <td>${ad.dateRange}</td>
                            <td><a href="${ad.link}" target="blank">Open Ad</a></td>
                        </tr>`
                    ));
                } else {
                    alertError();
                }
            })
            .catch(() => alertError());

        function alertError() {
            alert('Something went wrong! Please Try Again Later.');
        }
    </script>
</body>
</html>


결과



.env 파일

PORT=5000
PUBLIC_ADS_URL = 'https://kamuilan.sbb.gov.tr/'


패키지.json

{
  "name": "publicads",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "nodemon index"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "cors": "^2.8.5",
    "dotenv": "^10.0.0",
    "express": "^4.17.1",
    "puppeteer": "^10.4.0"
  }
}

좋은 웹페이지 즐겨찾기