如何修复 puppeteer 抓取失败
How to fix puppeteer scrape fail
我想用 node.js 和 puppeteer 保存网页的 HTML 代码。
当我用 'headless-browser: false' 启动程序时,我可以看到页面完全加载,所有数据都在那里。但是如果我尝试保存 HTML,我只会得到这个:
<!DOCTYPE html><html><head>
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
<meta http-equiv="cache-control" content="max-age=0">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="refresh" content="10; url=/distil_r_captcha.html?requestId=16a-84c6-42b6-9023-a45b3854e34c&httpReferrer=%2Fli">
<script type="text/javascript">
(function(window){
try {
if (typeof sessionStorage !== 'undefined'){
sessionStorage.setItem('distil_referrer', document.referrer);
}
} catch (e){}
})(window);
</script>
<script type="text/javascript" src="/elrhculcipoedjwh.js" defer=""></script><style type="text/css">#d__fFH{position:absolute;top:-5000px;left:-5000px}#d__fF{font-family:serif;font-size:200px;visibility:hidden}#xaqctssquudxqdqxzveurrreayw{display:none!important}</style></head>
<body>
<div id="distilIdentificationBlock"> </div>
</body></html>
所以我有点困惑:如果网页知道请求来自机器人(=所以我只能下载这个被阻止的 HTML 代码)那么为什么会显示内容?
或者换个角度:
如果网页不知道请求来自机器人(=所以内容显示)那么为什么我只能下载这个被阻止的 HTML?
我的代码:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ headless: false });
const context = await browser.createIncognitoBrowserContext();
const page = await context.newPage();
await page.evaluateOnNewDocument(() => {
Object.defineProperty(navigator, 'webdriver', {
get: () => false,
});
});
await page.evaluateOnNewDocument(() => {
window.navigator.chrome = {
runtime: {},
};
});
await page.evaluateOnNewDocument(() => {
const originalQuery = window.navigator.permissions.query;
return window.navigator.permissions.query = (parameters) => (
parameters.name === 'notifications' ?
Promise.resolve({
state: Notification.permission
}) :
originalQuery(parameters)
);
});
await page.evaluateOnNewDocument(() => {
Object.defineProperty(navigator, 'plugins', {
get: () => [1, 2, 3, 4, 5],
});
});
await page.evaluateOnNewDocument(() => {
Object.defineProperty(navigator, 'languages', {
get: () => ['en-EN', 'en'],
});
});
await page.setViewport({
'width': 1024,
'height': 768,
'deviceScaleFactor': 1,
'isMobile': false,
'hasTouch': false,
'isLandscape': false
});
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36');
await page.goto(url, { waitUntil: 'load' });
const html = await page.content();
console.log(html);
await browser.close();
})();
我该如何解决这个问题?也许我过早地尝试保存 HTML 代码?
提前致谢。
我想我找到了解决办法。
由于目标网页有一些反机器人系统,当它加载时,首先它呈现一个 "empty" 页面,只有一个 div。之后它重定向到内容。
所以我不得不添加
await page.waitFor(5000)
等待页面完全加载。
我想用 node.js 和 puppeteer 保存网页的 HTML 代码。 当我用 'headless-browser: false' 启动程序时,我可以看到页面完全加载,所有数据都在那里。但是如果我尝试保存 HTML,我只会得到这个:
<!DOCTYPE html><html><head>
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
<meta http-equiv="cache-control" content="max-age=0">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="refresh" content="10; url=/distil_r_captcha.html?requestId=16a-84c6-42b6-9023-a45b3854e34c&httpReferrer=%2Fli">
<script type="text/javascript">
(function(window){
try {
if (typeof sessionStorage !== 'undefined'){
sessionStorage.setItem('distil_referrer', document.referrer);
}
} catch (e){}
})(window);
</script>
<script type="text/javascript" src="/elrhculcipoedjwh.js" defer=""></script><style type="text/css">#d__fFH{position:absolute;top:-5000px;left:-5000px}#d__fF{font-family:serif;font-size:200px;visibility:hidden}#xaqctssquudxqdqxzveurrreayw{display:none!important}</style></head>
<body>
<div id="distilIdentificationBlock"> </div>
</body></html>
所以我有点困惑:如果网页知道请求来自机器人(=所以我只能下载这个被阻止的 HTML 代码)那么为什么会显示内容? 或者换个角度: 如果网页不知道请求来自机器人(=所以内容显示)那么为什么我只能下载这个被阻止的 HTML?
我的代码:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ headless: false });
const context = await browser.createIncognitoBrowserContext();
const page = await context.newPage();
await page.evaluateOnNewDocument(() => {
Object.defineProperty(navigator, 'webdriver', {
get: () => false,
});
});
await page.evaluateOnNewDocument(() => {
window.navigator.chrome = {
runtime: {},
};
});
await page.evaluateOnNewDocument(() => {
const originalQuery = window.navigator.permissions.query;
return window.navigator.permissions.query = (parameters) => (
parameters.name === 'notifications' ?
Promise.resolve({
state: Notification.permission
}) :
originalQuery(parameters)
);
});
await page.evaluateOnNewDocument(() => {
Object.defineProperty(navigator, 'plugins', {
get: () => [1, 2, 3, 4, 5],
});
});
await page.evaluateOnNewDocument(() => {
Object.defineProperty(navigator, 'languages', {
get: () => ['en-EN', 'en'],
});
});
await page.setViewport({
'width': 1024,
'height': 768,
'deviceScaleFactor': 1,
'isMobile': false,
'hasTouch': false,
'isLandscape': false
});
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36');
await page.goto(url, { waitUntil: 'load' });
const html = await page.content();
console.log(html);
await browser.close();
})();
我该如何解决这个问题?也许我过早地尝试保存 HTML 代码? 提前致谢。
我想我找到了解决办法。 由于目标网页有一些反机器人系统,当它加载时,首先它呈现一个 "empty" 页面,只有一个 div。之后它重定向到内容。 所以我不得不添加
await page.waitFor(5000)
等待页面完全加载。