javascript - Puppeteer 不会在无头模式下返回 HTML 标记,但在不处于无头模式时会返回 - 为什么会这样?
问题描述
我最近开始在 JavaScript 中尝试使用 Puppeteer 进行网页抓取,并注意到当我使用无头 Puppeteer 实例运行我的代码时,它不会返回我正在寻找的标签,而是会返回[]
. 但是,当关闭无头模式时,代码返回标签就好了。它返回的标签是
[ ElementHandle {
_context:
ExecutionContext { _client: [CDPSession], _world: [DOMWorld], _contextId: 3 },
_client:
CDPSession {
_events: [Object],
_eventsCount: 27,
_maxListeners: undefined,
_callbacks: Map {},
_connection: [Connection],
_targetType: 'page',
_sessionId: '6950CA7711045DA500204C2EFDAFC5B3' },
_remoteObject:
{ type: 'object',
subtype: 'node',
className: 'HTMLHeadingElement',
description: 'h1',
objectId: '{"injectedScriptId":3,"id":3}' },
_disposed: false,
_page:
Page {
_events: {},
_eventsCount: 0,
_maxListeners: undefined,
_closed: false,
_client: [CDPSession],
_target: [Target],
_keyboard: [Keyboard],
_mouse: [Mouse],
_timeoutSettings: [TimeoutSettings],
_touchscreen: [Touchscreen],
_accessibility: [Accessibility],
_networkManager: [NetworkManager],
_frameManager: [FrameManager],
_emulationManager: [EmulationManager],
_tracing: [Tracing],
_pageBindings: Map {},
_ignoreHTTPSErrors: false,
_coverage: [Coverage],
_javascriptEnabled: true,
_viewport: [Object],
_screenshotTaskQueue: [TaskQueue],
_workers: Map {} },
_frameManager:
FrameManager {
_events: [Object],
_eventsCount: 3,
_maxListeners: undefined,
_client: [CDPSession],
_page: [Page],
_networkManager: [NetworkManager],
_timeoutSettings: [TimeoutSettings],
_frames: [Map],
_contextIdToContext: [Map],
_isolatedWorlds: [Set],
_mainFrame: [Frame] } } ]
我曾尝试使用await page.goto(url, {"waitUntil" : "networkidle0"});
让程序等到页面完全加载后再返回标签,但再次没有运气。这是我功能失调的代码:
const initializeBrowserTask = async (proxy) => {
console.log("Initializing browser task...");
if (proxy == '') {
console.log('No proxy.')
const browser = await puppeteer.launch({ headless: false });
return browser;
} else {
const browser = await puppeteer.launch({
'args': ['--proxy-server=`${proxy}`']
});
console.log("Proxy: `${proxy}`")
return browser;
};
}
const browserTask = async (proxy, url) => {
const browser = await initializeBrowserTask(proxy);
let check = 0
const page = await browser.newPage();
console.log('Running...')
await page.goto(url);
console.log("Arrived at URL!")
let status = await page.$x('//*[@id="app"]/div[1]/div/div[1]/h1');
console.log(status)
};
browserTask('', 'http://adidas.com/yeezy')
我确实删除了{"waitUntil" : "networkidle0"}
前面提到的,因为它没有解决问题。出于某种原因,当浏览器不是无头时,此代码将起作用,但在无头[]
时会返回。为什么会出现这个问题,我该如何解决?
解决方案
刚刚弄清楚我的代码出了什么问题。显然,我试图抓取的网站(adidas.com)根据标题过滤掉了请求。我没有意识到的是,在无头模式下,我实际上到达了阿迪达斯的 403 Access Denied 页面,这就是我想要找到的标签不存在的原因。我猜 headless puppeteer 只是另一种发送 HTTP 请求的方式,而 non-headless 更像是一个实际的 webdriver,这就是为什么非 headless 模式没有被 Adidas 阻止的原因。
为了修复无头模式并添加适当的标题,我在 `page.goto(url);' 之前使用了这行代码 线:
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36');
事实证明,我所缺少的只是欺骗阿迪达斯网站不阻止我的标题。
推荐阅读
- java - Spring - 如何正确使用@Autowired?
- java - 无法为我的发帖请求提供用户名密码
- nuget - 如何将 .net 核心控制台应用程序发布到(私有)nuget 存储库并使用巧克力安装它?
- ag-grid - ImmutableService 需要实现 getRowNodeId() 回调,您的行数据需要 ID
- android - 从 Firebase 实时数据库中检索 listView 值到 longclicklistner 上的 Alertdialog
- python - 我想在未找到密钥时返回 0,而不是 Pandas 数据框中的“未找到密钥”错误
- android - Android - 在 SettingsActivity 屏幕底部包含一个 ButtonBar?
- reactjs - 将 TypeScript 添加到现有的创建反应应用程序时无法解析文件路径
- android-studio - 如何修复 gradle 同步新的 android studio 失败
- bash - 如何使用 bash 和 printf 转换日期格式?