谷歌抓取网页视频教程(插件支持:Adobe和Google联合开发内核还没太大关系(组图))
优采云 发布时间: 2021-10-02 03:13谷歌抓取网页视频教程(插件支持:Adobe和Google联合开发内核还没太大关系(组图))
前言
最近在研究谷歌浏览器内核。Google Chrome 内核已开源并进行维护和更新。其开源项目内核更新速度与Chrome浏览器版本更新进度一致!而且它不同于WebKit(值得一提的是谷歌浏览器不再使用WebKit核心),它提供的不仅仅是页面渲染,而是一个完整的浏览器解决方案和插件规则。
使用方便:我们给它一个“表单”(操作系统或系统资源管理器中的本地表单,本系列以Win32平台为例)和一些配置参数,它可以给你需要渲染的页面完美显示在固定窗口。
插件支持:Adobe与谷歌联合开发的pepperflashplayer功能齐全,如果我们将其作为进程外插件安装,则无需考虑其自动升级给用户或系统带来麻烦我们正在开发的版本更改。而且只需要一句代码就可以完成插件的激活,插件的获取和升级方式也很简单(先在电脑上安装一个chrome浏览器,到安装目录复制:-_-)。Google 的 pdf 插件也可以这样做。
本系列文章主要使用Java给谷歌一个shell。因为cef(即“谷歌Chrome Chromium嵌入式框架”,下文简称cef,本系列使用cef3)用c/c++编写,不直接提供Java语言API,虽然有Java A维护版的版本,不过我觉得不太好用。
获取 AWT 表单句柄
我们今天要做的与cef内核无关。我们先解决一个问题:获取Java表单的句柄。
我们都知道Java语言提供的GUI支持是基于操作系统资源管理系统(或桌面环境)的支持(在Java 2D/GUI中,最外层的窗口一定是操作系统相关的),所以简单的事实是,我们可以使用一些 JNI API 来获取表单句柄。
JNI是Java语言提供的本地化代码调用接口(在Java虚拟机中,其实并不关心下一个方法入口是内部指针还是外部操作系统指针),我们可以写ac/c++函数找到窗口句柄,然后返回Java虚拟机,让我们也知道虚拟机内部的操作系统分配的某个Java窗口的句柄。
Java官方已经考虑到了我们的需求,提供了一个接口:jawt。包括一系列c/c++ include(头文件.h,平台相关)和一系列c/c++静态库文件。
具体包括jawt.h、jawt_md.h、jawt.lib(另外jni.h和jni_md.h是使用jni所必须的)
编写动态链接库(dll),需要使用c/c++头文件和c/++源文件共同编译。我们首先使用JDK自带的javah工具(javah.exe)生成头文件并实现。
当然,我们先写一个Java类,并注解它的native方法。
1 /*
2 * Copyright 2014 JootMir Project
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 *
15 * Support: http://www.cnblogs.com/johness
16 */
17 package johness.jcef3.util;
18
19 import javax.swing.JFrame;
20
21 /**
22 * AWT工具集
23 *
24 * @author ShawRyan
25 */
26 public final class AWTUtil {
27 /**
28 * 获取某个窗体句柄(在Windows平台下)
29 *
30 * @param window
31 * 需要获取句柄的窗体对象
32 * @return 窗体应用句柄
33 */
34 public static native int getWindowHandleInWindows(JFrame window);
35 }
AWT实用程序
然后使用javah生成对应的头文件。
头文件的内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class johness_jcef3_util_AWTUtil */
#ifndef _Included_johness_jcef3_util_AWTUtil
#define _Included_johness_jcef3_util_AWTUtil
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: johness_jcef3_util_AWTUtil
* Method: getWindowHandleInWindows
* Signature: (Ljavax/swing/JFrame;)I
*/
JNIEXPORT jint JNICALL Java_johness_jcef3_util_AWTUtil_getWindowHandleInWindows
(JNIEnv *, jclass, jobject);
#ifdef __cplusplus
}
#endif
#endif
我不会详细介绍 jni 规则。
接下来我们用c++代码实现接口函数,编译成动态链接库。
我不喜欢使用经典的VC++6.0 或优秀的Dev C++,我将使用Visual Studio 2012 编写和编译它。
创建项目
删除所有我们不需要的(我们没有 -_-)文件
将jni和jawt相关的头文件和库文件复制到项目中(是否值得询问是否要复制粘贴到vs表单中,但实际复制到你的c++项目文件夹中)
%JAVA_HOME%\include\jni.h
%JAVA_HOME%\include\jawt.h
%JAVA_HOME%\include\jni_md.h
%JAVA_HOME%\include\jawt_md.h
%JAVA_HOME%\lib\jawt.lib
项目中的头文件
配置项
将项目配置为 Release
配置项目使用jawt.lib静态库
更改头文件,将#include 改为#include "jni.h"
(后面的竖线是光标)
写入源文件
(在创建源文件并准备开始编写代码之前取消源文件预编译头)
开始编码
1 #include "jni.h"
2 #include "jawt_md.h"
3 #include "johness_jcef3_util_AWTUtil.h"
4
5 JNIEXPORT jint JNICALL Java_johness_jcef3_util_AWTUtil_getWindowHandleInWindows (JNIEnv *env, jclass sender, jobject window) {
6 HWND hwnd = NULL;
7
8 JAWT_DrawingSurface *ds;
9 JAWT_DrawingSurfaceInfo *dsi;
10 JAWT_Win32DrawingSurfaceInfo *win;
11
12 JAWT awt;
13 awt.version = JAWT_VERSION_1_3;
14
15 jboolean result = JAWT_GetAWT(env, &awt);
16 if (result == JNI_TRUE) {
17 ds = awt.GetDrawingSurface(env, window);
18 jint lock = ds -> Lock(ds);
19 if (lock != JAWT_LOCK_ERROR) {
20 dsi = ds -> GetDrawingSurfaceInfo(ds);
21 win = (JAWT_Win32DrawingSurfaceInfo *) dsi -> platformInfo;
22
23 hwnd = win -> hwnd;
24
25 ds -> FreeDrawingSurfaceInfo(dsi);
26 ds -> Unlock(ds);
27 awt.FreeDrawingSurface(ds);
28 return jint(hwnd);
29 }
30 return 0;
31 }
32 return 0;
33 }
johness_jcef3_util_AWTUtil
编译生成
将生成的dll拷贝到Java项目中,在项目配置中配置librarypath,然后编写测试代码。
测试代码也很简单:
package johness.jcef3.util;
import javax.swing.JFrame;
public class Main {
public static void main(String[] args) {
System.loadLibrary("jawt");
System.loadLibrary("JCEF3");
JFrame frame = new JFrame();
frame.setSize(400, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
System.out.println(AWTUtil.getWindowHandleInWindows(frame));
}
}
最终总结
使用 Visual Studio 进行编译时,请注意不要使用预编译的文件头。当然,如果你对vc++有一点了解,可能就不那么麻烦了。
使用visual studio生成的dll需要运行环境,如msvcr110.dll。如果您还没有在您的机器上安装它,您可能会收到类似“找不到相关库”这样的错误消息。您可以打包这些运行时环境库。
写于 2016-03-29
本来想自己做java-cef,但是官方已经做了
写于 2019-11-28
java-cef 不再维护并且有很多错误。几年前,我自己维护了该项目的 Maven 版本。但是已经不更新了。注意这是几年前的东西,请不要使用它,尽量使用流行的开源组件。如果一个项目超过一个月没有活跃(发布版本、提交代码等),那么你最好不要使用它。
联系我一起交流
欢迎您加入我们的交流群。无聊的时候,我们一起打发时间:
或通过QQ联系我:
(上次编辑 2016-03-2910:26:41)