Exploring
首页
  • Java

    • 面向对象的思想OOP
    • 浅谈Java反射原理
    • endorsed覆盖JDK中的类
  • 认证与授权

    • LDAP概念和原理介绍
    • OAuth2介绍
  • Impala

    • Impala 介绍
  • MySQL

    • 关于MySQL的一些面试题
    • 解决MySQL不到中文数据
    • 数据库之事务与实现原理
  • Oracle

    • oracle的表空间,用户管理,表操作,函数
    • oracle的查询、视图、索引
    • plsql简单入门
  • Redis

    • 数据类型详解
    • 跳越表
    • 数据持久化的两种方式
  • 共识算法

    • gossip
  • RPC

    • GRPC初识与快速入门
    • ProtocolBuffer基本语法
  • RabbitMQ

    • RabbitMQ入门程序之HelloWorld
    • RabbitMQ之工作模式
  • Zookeeper

    • Zookeeper一文入门
  • Docker

    • Docker入门初体验
  • Maven

    • 把自己的包到Maven中央仓库
    • Maven之自定义插件
  • Nginx

    • nginx的安装
    • nginx的配置文件
    • nignx 的变量
  • Tomcat

    • Servlet3通过SPI进行注册组件
  • Vagrant

    • vagrant 初始化
    • vagrant 常用配置
    • vagrant 自己制作 box
  • Linux

    • 启动方式 Systemd
    • 后台服务
    • 防火墙与 Iptables
  • 设计模式

    • 设计模式-代理
    • 设计模式-单例模式
    • 设计模式-迭代器
  • 分布式

    • CAP 理论
  • 数据结构

    • 数据结构之堆Heap
    • 数据结构之哈希表
    • 数据结构之队列
  • 计算机网络

    • HTTP与HTTPS详解
    • 浅谈DNS协议
    • ISP中的网络层
  • 算法

    • 常用查找算法及Java实现
    • 常用排序算法及Java实现
    • 迪杰斯特拉算法
  • 操作系统

    • 操作系统之进程调度算法
    • 操作系统之进程通讯IPC
    • 操作系统之内存管理
  • 抓包

    • 生成安卓系统证书
  • 加解密

    • 常见加密算法
    • 公开秘钥基础知识
    • RSA 解析
  • Windows

    • scoop 包管理
    • windows-terminal 配置
    • 增强 PowerShell
归档
Github (opens new window)
首页
  • Java

    • 面向对象的思想OOP
    • 浅谈Java反射原理
    • endorsed覆盖JDK中的类
  • 认证与授权

    • LDAP概念和原理介绍
    • OAuth2介绍
  • Impala

    • Impala 介绍
  • MySQL

    • 关于MySQL的一些面试题
    • 解决MySQL不到中文数据
    • 数据库之事务与实现原理
  • Oracle

    • oracle的表空间,用户管理,表操作,函数
    • oracle的查询、视图、索引
    • plsql简单入门
  • Redis

    • 数据类型详解
    • 跳越表
    • 数据持久化的两种方式
  • 共识算法

    • gossip
  • RPC

    • GRPC初识与快速入门
    • ProtocolBuffer基本语法
  • RabbitMQ

    • RabbitMQ入门程序之HelloWorld
    • RabbitMQ之工作模式
  • Zookeeper

    • Zookeeper一文入门
  • Docker

    • Docker入门初体验
  • Maven

    • 把自己的包到Maven中央仓库
    • Maven之自定义插件
  • Nginx

    • nginx的安装
    • nginx的配置文件
    • nignx 的变量
  • Tomcat

    • Servlet3通过SPI进行注册组件
  • Vagrant

    • vagrant 初始化
    • vagrant 常用配置
    • vagrant 自己制作 box
  • Linux

    • 启动方式 Systemd
    • 后台服务
    • 防火墙与 Iptables
  • 设计模式

    • 设计模式-代理
    • 设计模式-单例模式
    • 设计模式-迭代器
  • 分布式

    • CAP 理论
  • 数据结构

    • 数据结构之堆Heap
    • 数据结构之哈希表
    • 数据结构之队列
  • 计算机网络

    • HTTP与HTTPS详解
    • 浅谈DNS协议
    • ISP中的网络层
  • 算法

    • 常用查找算法及Java实现
    • 常用排序算法及Java实现
    • 迪杰斯特拉算法
  • 操作系统

    • 操作系统之进程调度算法
    • 操作系统之进程通讯IPC
    • 操作系统之内存管理
  • 抓包

    • 生成安卓系统证书
  • 加解密

    • 常见加密算法
    • 公开秘钥基础知识
    • RSA 解析
  • Windows

    • scoop 包管理
    • windows-terminal 配置
    • 增强 PowerShell
归档
Github (opens new window)
  • 步道乐跑位置模拟刷步数
  • 利用PhantomJs抓取动态网页
    • 简介
    • 基本使用
    • 抓取网页脚本
    • 自定义请求头
    • 忽略SSL错误
    • 代理
    • 优化
    • Java示例
      • Js脚本
      • Java工具
    • 参考
  • 最佳评论系统Valine-Valine-Admin简洁且带邮件通知
  • ElasticSearch-Head安装配置
  • 未归档
unclezs
2020-12-26
0
目录

利用PhantomJs抓取动态网页

# 简介

PhantomJS是可使用JavaScript编写脚本的无头WebKit,我们可以用来做一些爬虫工作,网页截图等,不过目前项目已经被挂起。

# 基本使用

下载执行文件对应自己的操作系统,目前最新的是v2.11 下载地址 (opens new window)

语法

phantomjs [options] script.js [arg1 [arg2 [...]]]
1

编写脚本 hello.js

console.log("hello phantomJS!")
phantom.exit(0)
1
2

执行脚本

phantom hello.js
1

输出

hello phantomJS!
1

# 抓取网页脚本

var page = require('webpage').create();
page.open('http://blog.unclezs.com', function (status) {
    if (status !== 'success') {
        console.log('failed');
    } else {
        console.log(page.content);
    }
    phantom.exit();
});
1
2
3
4
5
6
7
8
9

执行即可看到抓取到的html

# 自定义请求头

可以通过 http://httpbin.org/get (opens new window) 这个网站测试自己的请求内容

page.customHeaders={
  'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}
1
2
3

# 忽略SSL错误

通过参数 --proxy=address:port 设置

比如 phantom --proxy=127.0.0.1:80 script.js

# 代理

通过参数 --ignore-ssl-errors=[true|false|yes|no] 默认为false

比如 phantom --proxy=127.0.0.1:80 script.js

# 优化

取消图片加载 --load-images=[true|false|yes|no] 默认true

# Java示例

# Js脚本

/**
 * phantomjs 解析动态网页
 * 支持传入referer、cookie、useragent
 *
 * @author blog.unclezs.com
 * @date   2020-12-24
 * @see    https://phantomjs.org/api/
 */
var page = require('webpage').create();
var system = require('system');

// 只传入脚本名称 不传入参数不执行
if (system.args.length === 1) {
    phantom.exit();
}
// 为了提升加载速度,不加载图片
page.settings.loadImages = false;
// 超过10秒放弃加载
page.settings.resourceTimeout = 10000;
// 忽略SSL错误

// 参数 需要按照顺序
var url = system.args[1];
var referer = system.args[2];
var cookie = system.args[3];
var userAgent = system.args[4];
var customHeaders = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
    'Referer': url
};
if (referer) {
    customHeaders['Referer'] = referer;
}
if (cookie) {
    customHeaders['Cookie'] = cookie;
}
if (userAgent) {
    customHeaders['User-Agent'] = userAgent;
}
page.customHeaders = customHeaders;
page.open(url, function (status) {
    if (status === 'success') {
        console.log(page.content);
    }
    phantom.exit();
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

# Java工具

/**
 * https://phantomjs.org/api/
 * <p>
 * 首先 添加system properties PHANTOMJS_PATH、PHANTOMJS_SCRIPT
 * <p>
 * 不然会使用默认位置去读取
 *
 * @author blog.unclezs.com
 * @since 2020/12/24 17:30
 */
@Slf4j
public class PhantomJsClient implements HttpProvider {
    /**
     * PhantomJs执行文件的位置
     */
    public static final String PHANTOMJS_PATH = "PHANTOMJS_PATH";
    /**
     * 脚本位置
     */
    public static final String PHANTOMJS_SCRIPT = "PHANTOMJS_SCRIPT_PATH";
    public static final String DEFAULT_PHANTOMJS_SCRIPT = FileUtil.USER_DIR + "/script/spider.js";
    public static final String DEFAULT_PHANTOMJS_PATH =
        FileUtil.USER_DIR + "/script/phantomjs" + SystemUtil.getExecuteSuffix();

    /**
     * 获取网页内容
     *
     * @param data 请求数据
     * @return /
     * @throws IOException /
     */
    @Override
    public String content(RequestData data) throws IOException {
        return executePhantomJs(PhantomJsRequestData.from(data));
    }

    @Override
    public InputStream stream(RequestData requestData) throws IOException {
        throw new UnsupportedEncodingException("PhantomJs动态网页HTTP客户端不支持获取流");
    }

    @Override
    public boolean isDynamic() {
        return true;
    }

    public String content(String url) throws IOException {
        return content(RequestData.defaultRequestData(url));
    }

    /**
     * 执行PhantomJs脚本抓取动态网页
     * phantomjs [options] script.js [arg1 [arg2 [...]]]
     * @param data 请求数据
     * @return /
     */
    public String executePhantomJs(PhantomJsRequestData data) throws IOException {
        if (StringUtil.isEmpty(data.getUrl())) {
            log.warn("phantomJS request url 不能为空");
            return StringUtil.EMPTY;
        }
        StringBuilder command = new StringBuilder();
        // phantomJs
        command.append(System.getProperty(PHANTOMJS_PATH, DEFAULT_PHANTOMJS_PATH));
        // 忽略SSL错误
        command.append(StringUtil.BLANK).append("--ignore-ssl-errors=").append(data.isIgnoreSslError());
        // 不加载图片
        command.append(StringUtil.BLANK).append("--load-images=").append(data.isLoadImg());
        // HTTP代理
        if (StringUtil.isNotEmpty(data.getProxy())) {
            command.append(StringUtil.BLANK).append("--proxy=").append(data.getProxy());
        }
        // script
        command.append(StringUtil.BLANK).append(System.getProperty(PHANTOMJS_SCRIPT, DEFAULT_PHANTOMJS_SCRIPT));
        // args
        command.append(StringUtil.BLANK).append(data.getUrl());
        command.append(StringUtil.BLANK).append(data.getReferer());
        command.append(StringUtil.BLANK).append(data.getCookie());
        command.append(StringUtil.BLANK).append(data.getUserAgent());
        return CommandUtil.execute(command.toString());
    }
}


/**
 * 执行CMD命令工具
 *
 * @author blog.unclezs.com
 * @since 2020/12/25 11:09
 */
@Slf4j
@UtilityClass
public class CommandUtil {
    /**
     * 执行CMD命令
     *
     * @param command 命令
     * @return 控制台数据
     */
    public static String execute(String command) throws IOException {
        StringBuilder buffer = new StringBuilder();
        log.trace("执行Command - 命令:{}", command);
        Process process = Runtime.getRuntime().exec(command);
        InputStream is = process.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String tmp;
        while ((tmp = br.readLine()) != null) {
            buffer.append(tmp).append(StringUtil.NEW_LINE);
        }
        return buffer.toString();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

# 参考

官方文档 (opens new window)

在 GitHub 编辑此页 (opens new window)
上次更新: 2024/02/25, 12:11:11
步道乐跑位置模拟刷步数
最佳评论系统Valine-Valine-Admin简洁且带邮件通知

← 步道乐跑位置模拟刷步数 最佳评论系统Valine-Valine-Admin简洁且带邮件通知→

Theme by Vdoing | Copyright © 2018-2024 unclezs
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式