你能用 c++ 加载一个网页,包括 JS 和动态 html 并获取渲染的 DOM 字符串吗?
Posted
技术标签:
【中文标题】你能用 c++ 加载一个网页,包括 JS 和动态 html 并获取渲染的 DOM 字符串吗?【英文标题】:Can you load a web page in c++, including JS and dynamic html and get the rendered DOM string? 【发布时间】:2016-09-06 04:24:56 【问题描述】:是否可以在 c++ 中加载网页并获取渲染的 DOM?不仅是 HTTP 响应,还有在 java 脚本运行后呈现的 DOM(可能在让它运行一段时间后)。特别是可能随时间变化的动态 html?有这个库吗?
或者如果不是c++,你知道有什么其他语言可以做到这一点吗?
编辑这里有一个例子来更好地说明为什么要这样做:
假设您想抓取一个用 Angular 编写的网站。您不能只发出一个 http 请求并使用 HTTP 响应,因为大多数 DOM 是在 javascript/动态 html 操作 DOM 之后呈现的。角度站点的初始 http 响应可能没有所有内容,它稍后通过 javascript/AJAX/dyanmic html 请求和呈现。
【问题讨论】:
微软制造 Internet Explorer,谷歌制造 Chrome 试试看这篇文章codeproject.com/Articles/2425/… 【参考方案1】:由于每个浏览器都以不同的方式实现 DOM,因此您在 C++ 中使用它的方式将因每个浏览器而异。
我将举一个 IE 的例子。您可以使用公开IWebBrowser2 接口的WebBrowser ActiveX 控件。从那里您可以调用 IWebBrowser2::get_Document 来获取 IHTMLDocument2 对象,它是 DOM 的根。
#include "StdAfx.h"
using namespace ATL;
using namespace std;
void ThrowIfFailed(HRESULT hr)
if (FAILED(hr))
throw CAtlException(hr);
int main()
::CoInitialize(nullptr);
try
CComPtr<IWebBrowser2> pWebBrowser;
HRESULT hr = ::CoCreateInstance(CLSID_InternetExplorer, nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&pWebBrowser));
ThrowIfFailed(hr);
hr = pWebBrowser->put_Visible(VARIANT_TRUE);
ThrowIfFailed(hr);
hr = pWebBrowser->GoHome();
ThrowIfFailed(hr);
CComPtr<IDispatch> pDispatch;
hr = pWebBrowser->get_Document(&pDispatch);
ThrowIfFailed(hr);
CComPtr<IHTMLDocument2> pDocument;
hr = pDispatch->QueryInterface(&pDocument);
ThrowIfFailed(hr);
CComBSTR bstrTitle;
hr = pDocument->get_title(&bstrTitle);
ThrowIfFailed(hr);
wcout << bstrTitle.m_str << endl;
catch (const CAtlException& e)
wcout << L"Error (" << hex << e.m_hr << L")" << endl;
::CoUninitialize();
return 0;
此代码只是打开一个 IE 窗口,导航到主页,并将页面标题写入控制台。您还可以通过删除对 IWebBrowser2::put_Visible 的调用来控制 IE 窗口是否可见。
【讨论】:
【参考方案2】:据我了解,您是在问: “如何通过 C++ 操作已经渲染的 HTML 页面的 DOM?”
如果这就是你想问的,这是我的答案:
从技术上讲,您可以通过 C++ 来实现。但是,您需要一个正确的工具/lib/framework/ ... 来执行此操作。
通常,我们通过 Javascript 操作 DOM。
根据我的经验,移动开发人员有用于加载页面的内置控件,通常称为“webview”。 android (Java) 和 ios (Objective-C) 都有。然后他们像这样操作 DOM:"webview.evaluteScript("your javascript").
如果你想用 C++ 来做。我想你可以阅读这些链接:
How to embed WebKit into my C/C++/Win32 application?
How do I embed WebKit in a window?
【讨论】:
我不想操纵它。尽管我只想要浏览器在运行 javascript 后呈现的内容的 dom 字符串。想象一下,你想爬取一个用 Angular 编写的网站。您不能只发出一个 http 请求并使用 HTTP 响应,因为大部分 DOM 是在操作 javascript/动态 html 之后呈现的。 Angular 网站的初始 http 响应可能没有所有内容。 正如我所说:“你可以操纵 DOM”。这意味着您可以这样做:“var myHTML = document.getElementsByTagName("html")[0]; myHTML.textContent" 通过使用“webview”之类的东西,您可以检索“myHTML.textConent”的输出。 还有一件事,您应该重新检查使用:innerHTML、innerText,以替换 textContent。我不记得有什么区别,但其中之一会给你呈现页面的完整 HTML 字符串。 嗯,谢谢你的回答。让大家成为朋友 XD。以上是关于你能用 c++ 加载一个网页,包括 JS 和动态 html 并获取渲染的 DOM 字符串吗?的主要内容,如果未能解决你的问题,请参考以下文章
你能用JavaScript加载jQuery contextMenu吗?
Python爬虫学习——使用selenium和phantomjs爬取js动态加载的网页