Puppeteer로 비동기 스크래핑
fullPage: true
하지 않으면 응답이 없는 것이 있어 계속 처리가 끝나지 않았다.코드
test.jsconst puppeteer = require('puppeteer');
// Unhandled promise rejection
process.on('unhandledRejection', (error) => {
console.error(error);
process.exit(1);
});
const articleUrlList = [
'https://qiita.com/horikeso/items/0bf9a78454b8124a6dfa',
'https://qiita.com/horikeso/items/f87d3e703828aa13e2ff',
'https://qiita.com/horikeso/items/ec34a8e3d6731a94f5f9',
'https://qiita.com/horikeso/items/bb255eede8a051dfa785',
];
(async () => {
try {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--lang=ja,en-US;q=0.9,en;q=0.8',
'--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
]
});
let index = 0;
promiseList = [];
articleUrlList.forEach(targetUrl => {
promiseList.push((async (index) => {
const page = await browser.newPage();
page.setDefaultNavigationTimeout(30000);// default 3000 milliseconds, pass 0 to disable timeout
const response = await page.goto(targetUrl);
await page.waitFor(1000);// 1秒待つ
if (response.status() !== 200) {
return [];
}
console.log(index);
const fileName = index + '.png';
await page.screenshot({path: fileName, fullPage: true});
const result = await page.evaluate(() => {
return [document.querySelector('meta[property="og:title"]').getAttribute('content')];
});
await page.close();
return result;
})(index));
index++;
});
let articleTitleList = [];
await Promise.all(promiseList).then(valueList => {
valueList.forEach(value => {
articleTitleList = articleTitleList.concat(value);
});
}).catch(reject => {
throw reject;
});
console.log(articleTitleList);
await browser.close();
} catch (error) {
throw error;
}
})().catch((error) => {
console.log(error);
process.exit(1);
});
주의사항
MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 Symbol(Connection.Events.Disconnected) listeners added. Use emitter.setMaxListeners() to increase limit
같은 오류가 발생하면
아래에서 MaxListeners
의 상한을 올리거나(서버 스펙에 문제가 없는 경우 나름대로 메모리를 사용하기 때문에)Lodash
이나 Underscore
의 chunk 로 분할 실행하거나 하여 Promise
의 동시 실행수를 줄일 필요가 있을 것 같습니다.
require('events').EventEmitter.defaultMaxListeners = 15;// default 10, Promise等 同時実行制限
goto가 돌아 오지 않는 페이지가 있습니다.
여러가지 페이지를 취득하는 경우는 총당으로 부딪히는 방법이라도 좋을지도 모릅니다.
잘 잡히지 않는 것이 있는 경우는 차례로 해 간다.
timeout은 요조정
const optionList = [
{waitUntil: 'load'},
{waitUntil: 'domcontentloaded'},
{waitUntil: 'networkidle0'},
{waitUntil: 'networkidle2'}
];
let response = null;
for (let optionIndex = 0; optionIndex < optionList.length; optionIndex++) {
if (response) {
break;
}
response = await page.goto(targetUrl, optionList[optionIndex]).catch(error => {
if (optionIndex === optionList.length - 1) {
throw error;
}
});
}
if (response.status() !== 200) {
continue;
}
실행 결과
node test.js
3
0
2
1
[ 'CentOS7でPuppeteerを使う - Qiita',
'Puppeteerのevaluateに引数 - Qiita',
'Puppeteerでステータスコード - Qiita',
'非同期処理を含むループを同期処理 - Qiita' ]
index가 순서가 아니기 때문에 비동기로 되어 있을 것.
생성된 SS
긴...
0.png
1.png
2.png
3.png
Reference
이 문제에 관하여(Puppeteer로 비동기 스크래핑), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/horikeso/items/631e2a8d0d17320d9f4f
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
const puppeteer = require('puppeteer');
// Unhandled promise rejection
process.on('unhandledRejection', (error) => {
console.error(error);
process.exit(1);
});
const articleUrlList = [
'https://qiita.com/horikeso/items/0bf9a78454b8124a6dfa',
'https://qiita.com/horikeso/items/f87d3e703828aa13e2ff',
'https://qiita.com/horikeso/items/ec34a8e3d6731a94f5f9',
'https://qiita.com/horikeso/items/bb255eede8a051dfa785',
];
(async () => {
try {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--lang=ja,en-US;q=0.9,en;q=0.8',
'--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
]
});
let index = 0;
promiseList = [];
articleUrlList.forEach(targetUrl => {
promiseList.push((async (index) => {
const page = await browser.newPage();
page.setDefaultNavigationTimeout(30000);// default 3000 milliseconds, pass 0 to disable timeout
const response = await page.goto(targetUrl);
await page.waitFor(1000);// 1秒待つ
if (response.status() !== 200) {
return [];
}
console.log(index);
const fileName = index + '.png';
await page.screenshot({path: fileName, fullPage: true});
const result = await page.evaluate(() => {
return [document.querySelector('meta[property="og:title"]').getAttribute('content')];
});
await page.close();
return result;
})(index));
index++;
});
let articleTitleList = [];
await Promise.all(promiseList).then(valueList => {
valueList.forEach(value => {
articleTitleList = articleTitleList.concat(value);
});
}).catch(reject => {
throw reject;
});
console.log(articleTitleList);
await browser.close();
} catch (error) {
throw error;
}
})().catch((error) => {
console.log(error);
process.exit(1);
});
MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 Symbol(Connection.Events.Disconnected) listeners added. Use emitter.setMaxListeners() to increase limit
같은 오류가 발생하면
아래에서
MaxListeners
의 상한을 올리거나(서버 스펙에 문제가 없는 경우 나름대로 메모리를 사용하기 때문에)Lodash
이나 Underscore
의 chunk 로 분할 실행하거나 하여 Promise
의 동시 실행수를 줄일 필요가 있을 것 같습니다.require('events').EventEmitter.defaultMaxListeners = 15;// default 10, Promise等 同時実行制限
goto가 돌아 오지 않는 페이지가 있습니다.
여러가지 페이지를 취득하는 경우는 총당으로 부딪히는 방법이라도 좋을지도 모릅니다.
잘 잡히지 않는 것이 있는 경우는 차례로 해 간다.
timeout은 요조정
const optionList = [
{waitUntil: 'load'},
{waitUntil: 'domcontentloaded'},
{waitUntil: 'networkidle0'},
{waitUntil: 'networkidle2'}
];
let response = null;
for (let optionIndex = 0; optionIndex < optionList.length; optionIndex++) {
if (response) {
break;
}
response = await page.goto(targetUrl, optionList[optionIndex]).catch(error => {
if (optionIndex === optionList.length - 1) {
throw error;
}
});
}
if (response.status() !== 200) {
continue;
}
실행 결과
node test.js
3
0
2
1
[ 'CentOS7でPuppeteerを使う - Qiita',
'Puppeteerのevaluateに引数 - Qiita',
'Puppeteerでステータスコード - Qiita',
'非同期処理を含むループを同期処理 - Qiita' ]
index가 순서가 아니기 때문에 비동기로 되어 있을 것.
생성된 SS
긴...
0.png
1.png
2.png
3.png
Reference
이 문제에 관하여(Puppeteer로 비동기 스크래핑), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/horikeso/items/631e2a8d0d17320d9f4f
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
node test.js
3
0
2
1
[ 'CentOS7でPuppeteerを使う - Qiita',
'Puppeteerのevaluateに引数 - Qiita',
'Puppeteerでステータスコード - Qiita',
'非同期処理を含むループを同期処理 - Qiita' ]
긴...
0.png
1.png
2.png
3.png
Reference
이 문제에 관하여(Puppeteer로 비동기 스크래핑), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/horikeso/items/631e2a8d0d17320d9f4f텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)