Java调用Python爬虫获取信息
- 前言
最近想做一个基于爬虫获取数据的小网站,Pyhton爬虫是做的差不多了,但是最终还是要回到Java做后端的,这就有个问题了,那就是怎么样用java执行python脚本,向脚本传递参数,并获取脚本返回的信息。本文将介绍如何进行操作,和操作过程中的一些小坑。
我已经把这个封装为了一个较为完善的累了,可以直接把我的代码拿过去改一下就可以直接使用了
1,使用的方法
在寻找许多方法后,比如Jython
,但是发现那玩意比较麻烦,而且好像这玩意是用Java运行Python的,使用的不是本机的Python环境,所以很难使用第三方的库。最后还是用Java自带的库解决了问题。
使用的是java.io.BufferedReader 下面的 Runtime.getRuntime().exec() 方法,怎么使用直接上代码吧:
@Component
public class CrawlRuner {
// windows和linux中python输出的编码格式好像不一样.
// 考虑到后面方便部署,这里引用了application.properties中的配置,也可以直接赋值
@Value("${crawler.command}")
String command;
@Value("${crawler.path}")
String path;
@Value("${crawler.sys}")
String sys;
// 调用函数就可以获取脚本运行的接过来
/*
* name: 脚本文件名 不用添加后缀(.py)
* values : 调用脚本传递的参数,这里长度可变
*/
public String Run(String name,String... values){
// 生成args
int argsLength = values.length + 2;
String[] args = new String[argsLength];
args[0] = command;
args[1] = path + name + ".py";
for(int i=2;i<argsLength;i++){
args[i] = values[i-2];
}
// 运行
Process proc;
try{
proc = Runtime.getRuntime().exec(args);
BufferedReader in;
// windows 这里要使用gb2312编码,否则会乱码(我的python版本是3.7),只用windows或linux可以直接赋值
if(sys.equals("Windows")){
in = new BufferedReader(new InputStreamReader(proc.getInputStream(),"gb2312")); //"gb2312"
}else{
in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
}
// 获取输出信息
String line = null,result = "";
while ((line = in.readLine()) != null) {
result += line;
}
in.close();
proc.waitFor();
return result;
}catch (Exception e) {
e.printStackTrace();
return "error";
}
}
}
springboot中的application.properties中的配置如下:
// 你使用python时的命令,一般直接用pyhton就可以了,我的系统因为装了几个python要用python3.7
crawler.command=python
// 这里是你的脚本所在的文件夹,记得最后的‘/’不能少
crawler.path=D:/Crawl/
// 系统,只有是Windows是Java才是判断用gb2312编码
crawler.sys = Windows
2,Python中的注意事项
因为这种Java调用Python的方法就相当于是直接CMD命令调用,所以脚本要可以从命令中获取参数。可以通过脚本的主函数,使用如下方式获取命令行中的参数,并调用函数,sys.argv[n] 就对应命令行中输入的第n个参数。
此外,java通过命令的输出值获取脚本执行内容,所以python要使用print函数返回结果,而不能用return,那样的话获取不到结果
import sys
if __name__ == '__main__':
result = login(sys.argv[1], sys.argv[2])
print(result)
3,使用样例
这是在springboot中调用login脚本的代码:
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
CrawlRuner crawlRuner;
@PostMapping("/login")
public Result Login(@RequestBody User user, HttpServletResponse response) {
// 调用登录爬虫
String result = crawlRuner.Run("login",user.getId(),user.getPwd());
...
这里就是相当于java帮我们在cmd输入
python D:/Crawl/login.py (user.getId()的值) (user.getPwd()的值)
并获取运行结果到result变量