Java 实现模拟浏览器查询关键字结果截图
前言:
先说实现了一个什么,这样才能看下去。
通过接口传两个参数:1、模拟在百度搜索框内的关键字。2、接收截图的邮箱。
模拟打开浏览器输入关键字,搜索,然后做长截图。之后发送到你的邮箱附件中。
这个长截图是整个浏览器页面的截图不是Alt+a;
分享 - Chrome浏览器的长截图操作(windows):
1:打开浏览器,按 F12;
2:Ctrl+Shift+P;
3:输入 full 这个单词 然后回车。
需求来源(为什么要做)
我们公司做SEO的业务,一次吃饭完一起打王者听到的一声唠叨。他们工作中有一个KPI要完成,就是:每天都要对负责的关键字在百度上的排名做截图留存。这个正好也勾起我的兴趣,这个用程序能实现吗?应该怎么做呢。要打开浏览器?那他要没Chrome咋办。还要长截图?
我也开始了翻找资料,发现了 phantomjs 这个好东西。
phantomjs文章分享:
https://www.cnblogs.com/front-Thinking/p/4321720.html
下载下来这个phantom.exe
这是一个测试的main方法
/**
* @Description:根据网页地址转换成图片
*/
public class PhantomTools {
private static String tempPath = "D:/home/";// 图片保存目录
private static String BLANK = " ";
// 下面内容可以在配置文件中配置
private static String binPath = "D:\\ideawork\\help_seo\\target\\classes\\sysplugins\\phantomjs.exe";// 插件引入地址
private static String jsPath = "D:\\ideawork\\help_seo\\target\\classes\\sysplugins\\rasterize.js";// js引入地址
// 执行cmd命令
public static String cmd(String imgagePath, String url) {
return binPath + BLANK + jsPath + BLANK + url + BLANK + imgagePath;
}
//关闭命令
public static void close(Process process, BufferedReader bufferedReader) throws IOException {
if (bufferedReader != null) {
bufferedReader.close();
}
if (process != null) {
process.destroy();
process = null;
}
}
/**
* @param url
* @throws IOException
*/
public static void printUrlScreen2jpg(String url) throws IOException, InterruptedException {
String imgagePath = tempPath+"/"+System.currentTimeMillis()+".png";//图片路径
//Java中使用Runtime和Process类运行外部程序
Process process = Runtime.getRuntime().exec(cmd(imgagePath,url));
InputStream inputStream = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null && line.length() > 0) {
}
close(process,reader);
System.out.println("success");
}
public static void main(String[] args) throws IOException, InterruptedException {
/**
* 个站
*/
String url = "https://www.dahuangzi.work";
PhantomTools.printUrlScreen2jpg(url);
}
举例
百度
String url=“https://www.baidu.com/s?wd=”+URLEncoder.encode(“你的关键字”);
这样的是第一页。
获取 第二页:拼接 “&pn=”
String url=“https://www.baidu.com/s?wd=”+URLEncoder.encode(“你的关键字”)+"&pn="+10;
pn=10 是第二页,20第三页 往后推。。
rasterize.js文件
关于这个rasterize.js这个写法,我也是菜鸡,找的现成的。
"use strict";
var page = require('webpage').create(),
system = require('system'),
address, output, size;
try{
if (system.args.length < 3 || system.args.length > 5) {
console.log('error');
phantom.exit(1);
} else {
address = system.args[1];
output = system.args[2];
page.viewportSize = { width: 600, height: 600 };
if (system.args.length > 3 && system.args[2].substr(-4) === ".pdf") {
size = system.args[3].split('*');
page.paperSize = size.length === 2 ? { width: size[0], height: size[1], margin: '0px' }
: { format: system.args[3], orientation: 'portrait', margin: '1cm' };
} else if (system.args.length > 3 && system.args[3].substr(-2) === "px") {
size = system.args[3].split('*');
var pageWidth,pageHeight;
if (size.length === 2) {
pageWidth = parseInt(size[0], 10);
pageHeight = parseInt(size[1], 10);
page.viewportSize = { width: pageWidth, height: pageHeight };
page.clipRect = { top: 150, left: 0, width: pageWidth, height: pageHeight };
} else {
console.log("size:", system.args[3]);
pageWidth = parseInt(system.args[3], 10);
pageHeight = parseInt(pageWidth * 3/4, 10); // it's as good an assumption as any
console.log ("pageHeight:",pageHeight);
page.viewportSize = { width: pageWidth, height: pageHeight };
}
}
if (system.args.length > 4) {
page.zoomFactor = system.args[4];
}
var start = Date.now();
page.open(address, function (status) {
console.log("open cost " + (Date.now() - start) + " ms")
start = Date.now();
if (status !== 'success') {
console.log('Unable to load the address!');
phantom.exit(1);
} else {
var repetition = 0;
var handler = setInterval(function () {
repetition++;
var loaded = page.evaluate(function () {
return window.loadedPdf;
});
console.log("loaded:" + loaded + " " + address);
if (repetition > 300 || ( loaded != null && loaded && loaded=='success') ) {
console.log(repetition + "page render cost " + (Date.now() - start) + " ms");
start = Date.now();
clearInterval(handler);
page.render(output);
console.log("capture image cost " + (Date.now() - start) + " ms");
phantom.exit(0);
}
}, 200);
}
});
}
}catch(e){
console.log(e+'error');
phantom.exit();
}
关于Springboot发送邮件 用的163的邮箱
1、pom文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
2、.yml配置
我这用的是 163 也可以 qq;
网上大多数都是qq邮箱的例子。先去开通 这个smtp,网上的qq教程很多。
163的 进去之后点 设置 你就能看见 POP3/SMTP 点开启 。
spring:
mail:
host: smtp.163.com
password: 你开通SMTP之后给你的那个password,
username: 13520350513@163.com //
3、代码
没附件的
@Autowired
private JavaMailSender mailSender;
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("13520350513@163.com");
//收件人
message.setTo("13520350513@163.com");
message.setSubject("内容");
message.setText("哈哈这是主题..............................");
mailSender.send(message);
有附件的
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = null;
try {
helper = new MimeMessageHelper(message, true);
helper.setFrom("13520350513@163.com");
helper.setTo("13520350513@163.com");
helper.setSubject("simple mail");
helper.setText("<h3>附件</h3>", true);
FileSystemResource file = new FileSystemResource(new File("D:\\ideawork\\20210225113237266164483465100.png"));
String fileName = file.getFilename();
helper.addAttachment(fileName, file);
mailSender.send(message);
log.info("邮件已经发送");
} catch (MessagingException e) {
log.error("{}",e);
}
没了,我试试发送多个附件,应该就是这个 helper.addAttachment(fileName, file); add多个吧。
想要做成 关键字、邮箱、页数;三个参数。一个邮件多个附件。这样就比较可爱了。
弄完源码我放到git,链接我分享到评论。
当能解决一个日常重复动作,你是不是最有尝试开发的欲望。