java调用Linux执行Python爬虫,并将数据存储到elasticsearch--(环境脚本搭建)
java调用Linux执行Python爬虫,并将数据存储到elasticsearch中
一、以下博客代码使用的开发工具及环境如下:
1、idea:
2、jdk:1.8
3、elasticsearch:5.2.0
4、Linux
5、Python
6、maven
二、maven坐标:
<!--java连接ulinix脚本架包-->
<dependency>
<groupId>ch.ethz.ganymed</groupId>
<artifactId>ganymed-ssh2</artifactId>
<version>build209</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!--es相关坐标-->
<dependency>
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>transport-netty4-client</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.nlpcn</groupId>
<artifactId>elasticsearch-sql</artifactId>
<version>6.3.0.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.9</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.2.0</version>
</dependency>
二、Linux脚本
cd /usr/local/python3/lib/python3.6/site-packages
python linux_sina.py &
三、Python爬虫脚本
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Created on Mon Aug 13 10:12:56 2018 @author: Administrator
""" import public_python as p
import urllib.request
from bs4 import BeautifulSoup
#存储到ES
from elasticsearch import Elasticsearch import flask
from flask import request
server = flask.Flask(__name__) from selenium import webdriver @server.route('/news',methods=['get','post'])
def get_html2():
#异常处理机制:
#声明全局变量
#global title,time,strcon,cos
try:
url=request.values.get("url")
#存储的新闻类型----用于数据库表中的字段
theme_id=request.values.get("theme_id")#----guonei--新闻类型 #无界面启动
firefox_options = webdriver.FirefoxOptions()
firefox_options.add_argument('--headless')
browser = webdriver.Firefox(firefox_options=firefox_options)
#超时设置
#timeout=request.values.get("timeout")
'''设置加载时间'''
browser.set_page_load_timeout(30000)
browser.set_script_timeout(30000)#这两种设置都进行才有效
browser.get(url)
'''
判断url是否包含多个链接,如果包含--即URL值不会是以.shtml结尾的字符串
那么就去获取链接里面所有的以.shtml结尾的链接url值。
'''
#存放页面中具体的url链接
data_urls=[]
if ".shtml" not in url: list_father=browser.find_element_by_tag_name('body')#先定位大的标签
#存放所有<a>链接
ahref=list_father.find_elements_by_tag_name("a")#在打标签下寻找确定的小标签的集合-需要:elements。 '''
对标签<a>进行遍历,获取其中的属性为:href的值,
然后过滤判断,如果包含.shtml,那么将href的值保存到数组,并且对数组进行set去重。
如果没包含.shtml,那么跳过本次循环。
最后调用获取数据的方法进行爬取数据
'''
for ah in ahref:#具体小标签中包含内容较多,所以还需要遍历 hr=ah.get_attribute("href")#获取连接的值
if ".shtml" in hr: #对链接进行遍历过滤
data_urls.append(hr)
links=set(data_urls)#去重
else:
pass
continue
#getcontent(links)#调用获取内容的方法:
'''
判断url是否包含多个链接,如果url包含。shtml,那么代表此url是单页的。
那么直接将url存入数组,然后调用获取数据的方法
'''
if ".shtml" in url:
data_urls.append(url)
links=set(data_urls)#去重
#getcontent(links)
'''
#最后均去调用获取内容的方法:
'''
getcontent(links)
return "ok" #测试
#data_urls中包含网页中所有.shtml的链接。
'''
for i in range(len(data_urls)):
print(data_urls[i])
''' browser.quit()#完成后退出关闭浏览器
except urllib.error.URLError as e :
if hasattr(e,"code"):
print(e.code)
return e.code
if hasattr(e,"reason"):
print(e.reason)
return e.reason
except Exception as e:
print("exception:"+str(e))
return e def getcontent(data_urls):
#异常处理机制:
try:
global title,time,strcon,cos
from selenium import webdriver
#存储的新闻类型----用于数据库表中的字段
theme_id=request.values.get("theme_id")#----guonei--新闻类型
#图片的前缀链接域名
#domain_name=request.values.get("domain_name") #无界面启动
firefox_options = webdriver.FirefoxOptions()
firefox_options.add_argument('--headless')
browser = webdriver.Firefox(firefox_options=firefox_options) '''
连接ES集群,获取es
'''
es=Elasticsearch(hosts=['192.168.200.211:9201'], maxsize=25) '''
对传递过来的url数组进行遍历,获取每一个具体链接url(以.shtml结尾的url)
'''
for url in data_urls:
print(url) #具体每个标题链接,后缀是.shtml browser.get(url) conlist=[] #存储文章内容,先以数组进行保存 #判断源代码中id的值:artibodyTitle是否存在,存在的话将值内容赋值给标题变量
if "artibodyTitle" in browser.page_source:
title=browser.find_element_by_id("artibodyTitle").text
#判断class的值:main-title是否存在,存在的话将值内容赋值给标题变量
elif "main-title" in browser.page_source:
title=browser.find_element_by_class_name("main-title").text
'''
以上是对新浪网新闻中标题存在的不同形式的判断。
'''
else:
#跳过异常错误 继续执行
#pass
#continue
title="无法爬取标题"
print(title) '''
以下是获取时间的方式。
''' if "pub_date" in browser.page_source:
time=browser.find_element_by_id("pub_date").text
elif "date" in browser.page_source:
time=browser.find_element_by_class_name("date").text
else:
#pass
#continue
time="无法爬取时间"
#print(time) '''
以下是去获取正文内容。
先:打开url,并读取内容
''' file=urllib.request.urlopen(url=url,timeout=30000)
data=file.read().decode('utf-8','ignore')
soup=BeautifulSoup(data,'lxml') '''#存实际的所有正文的内容--不以数组形式存储'''
strcon="" '''
#内容有2中情况,一种在class=article的div下(class以“.”表示),
一种在id=artibody的div下(id以“#”表示)
'''
if soup.select('.article ') :
cos=soup.select('.article ')
elif soup.select('#artibody '):
cos=soup.select('#artibody ')
'''
判断包含内容的标签是否存在,以下代码均是在内容存在的情况下进行
'''
if cos:
for i in cos:
'''
遍历内容标签,查找包含图片和段落的标签(img和p),
结果是bs4.element.ResultSet集合。
集合中每一个元素是一个tag标签
'''
alls=i.find_all(["img","p"])#传入一个字符串的列表,将匹配列表中标签的Tag全部返回
#print(type(alls)) #<class 'bs4.element.ResultSet'>
#(type(alls[0])) #<class 'bs4.element.Tag'> '''
对过滤后的标签结合进行遍历。
'''
for j in alls:
#print(j) #---div-article标签下所以内容。包含标签在内
'''
#接下来需要将图片进行替换成本地图片:
#第一步:将本页的图片按原名下载下来
#第二步,替换标签<img>中src的来源路径即可
'''
if j in soup.findAll("img"): #获取图片的连接url
imgAllName=str(j.attrs["src"])
#图片名称
imgName=imgAllName.split("/")[-1].split(".")[0]#aaa.jpg格式--aaa
#图片后缀
imgName_suffix=imgAllName.split("/")[-1].split(".")[-1]#类似jpg
#将图片存入本地文件-由于网址中src缺少"http:",所以需要添加形成完整url路径
urllib.request.urlretrieve("http:"+imgAllName,"//opt//zc//img//"+imgName+"."+imgName_suffix)
'''
#设置新的图片(目的:将本地图片地址去替换原来的链接地址)-本地图片的位置和图片名称链接
'''
imglink="http:/"+"/opt/zc/img/"+imgName+"."+imgName_suffix '''
#修改:图片位置存放链接,将本地图片地址去替换原来的链接地址
#j.attrs["src"]通过标签的attrs属性获取里面的属性值
'''
j.attrs["src"]=imglink #此添加的就是仅仅修改图片链接地址后全部的内容。
conlist.append((j))
'''
遍历保存内容的数组,将其保存为一个整体
'''
for i in range(len(conlist)):
strcon+=str(conlist[i]) #str:将标签内容转换成string类型
#print(strcon)#内容
'''
#以下是ES存储的时候的表字段
'''
#存储的新闻类型----用于数据库表中的字段
#theme_id=request.values.get("theme_id")#----guonei--新闻类型
#autoid 主键
#company_id="" # 公司ID
#title:标题-title
#content:内容-strcon '''
对es中的索引进行判断,查看是否存在
如果不存在,那么就创建,将id的值赋值为1,然后添加数据
'''
if es.indices.exists(index=theme_id) is not True: autoid=1 #设置es中id的值
#将结果写入ES
data={"id":autoid,"title":title,
"content":strcon
}#str(conlist)转换成str类型 否则序列化失败
#创建新索引---注意位置在此!
es.indices.create(index=theme_id)
p.insert_result(theme_id,"sina",data) '''
如果索引存在的话,先查询出索引中所有内容,然后将数据进行转换成dataframe
然后去获取其中关于标题:title和主键:id的值。 '''
else: '''
#去重,先去查询ES,如果title不相同的,那么继续执行,否则跳出此循环,pass,continue
继续执行的前提下,查询ES中的id的最大值,然后每次存储,id+1 ''' res0=p.search(theme_id,"sina")#查询方法 res1=p.clean_data(res0)#对数据进行转换成:dataFrame res_title=res1[["title"]]#获取需要的部分数据dataframe--
res_id=res1[["id"]]#获取需要的部分数据dataframe #print(res_title.values)#---[[],[]]:二维数组 titles=[]#存储es中已经存在的title的集合
for i in res_title.values:
#print(i)#[] [] []
for j in i:
titles.append(j)
'''
以上,标题titles保存的就是一维数组
''' ids=[]#存储es中已经存在的id的集合
for i in res_id.values:
#print(i)#[] [] []
for j in i:
ids.append(j)
'''
以上,主键ids:保存的就是一维数组
''' '''
由于每次插入数据id自动增加,所以先要去查看es中(ids)的最大值,然后每加一条记录+1。
#对ids数组进行遍历,获取最大值,#max(ids)是:<class 'numpy.int64'>,要转换成int类型
#print(type(ids))#list类型
'''
autoid_max=int(max(ids))
#设置es中id的值,自动增加1 #print(type(autoid_max))#int 类型
autoid=int(autoid_max+1) '''
去重处理。
#print(titles)#titles:['','','']
#对title的值进行判断是否存在。--去重!!!!!,如果存在那么跳出本次循环
'''
if title in titles:
#pass
#continue
print("已经存在此标题") else: data={"id":autoid,"title":title,"content":strcon
}
#调用方法,往es中插入数据 p.insert_result(theme_id,"sina",data) #seach获取---本地打印
res00=p.search(theme_id,"sina")#查询方法
print(res00)
return "ok" except urllib.error.URLError as e :
if hasattr(e,"code"):
print("==="+e.code)
return e.code
if hasattr(e,"reason"):
print("----"+e.reason)
return e.reason
except Exception as e:
print("exception:"+str(e))
return e
server.run(host='0.0.0.0',port=8000,debug=True)
以上Linux脚本及Python爬虫脚本,作者在此感谢我的同事张超提供。下一篇博客作者将为大家提供后台java代码(https://www.cnblogs.com/chenyuanbo/p/9973769.html)。此篇博客主要为Python爬虫都是自己书写的小伙伴参考
java调用Linux执行Python爬虫,并将数据存储到elasticsearch--(环境脚本搭建)的更多相关文章
- java调用Linux执行Python爬虫,并将数据存储到elasticsearch中--(java后台代码)
该篇博客主要是java代码,如需相应脚本及java连接elasticsearch工具类代码,请移步到上一篇博客(https://www.cnblogs.com/chenyuanbo/p/9973685 ...
- Java调用Linux命令执行
调用方式 Java调用linux命令执行的方式有两种,一种是直接调用linux命令,一种是将linux命令写到.sh脚本中,然后调用脚本执行. 详细说明 直接调用:使用java中lang包下面的Run ...
- Java调用Javascript、Python算法总结
最近项目中经常需要将Javascript或者Python中的算法发布为服务,而发布Tomcat服务则需要在Java中调用这些算法,因此就不免要进行跨语言调用,即在Java程序中调用这些算法. 不管是调 ...
- Java调用Linux命令(cd的处理)
一.Java调用Linux系统的命令非常简单 这是一个非常常用的调用方法示例: public String executeLinuxCmd(String cmd) { System.out.print ...
- java调用cmd执行maven命令
一.原理介绍 Java的Runtime.getRuntime().exec(commandStr)可以调用执行cmd指令. cmd /c dir 是执行完dir命令后封闭命令窗口. cmd /k di ...
- java调用linux下的so库
1.编写java类 public class Abc { static { System.loadLibrary("abc"); } public native static St ...
- Linux 安装python爬虫框架 scrapy
Linux 安装python爬虫框架 scrapy http://scrapy.org/ Scrapy是python最好用的一个爬虫框架.要求: python2.7.x. 1. Ubuntu14.04 ...
- Java 调用并执行cmd命令
cmd java 调用 执行 概要: Java 调用并执行cmd命令 Java | 复制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 2 ...
- Java调用oracle存储过程通过游标返回临时表数据
注:本文来源于 < Java调用oracle存储过程通过游标返回临时表数据 > Java调用oracle存储过程通过游标返回临时表数据 项目开发过程中,不可避免的会用到存储过程返回结 ...
随机推荐
- 在VS2010中使用Git管理源代码
前文我们讲了使用TortoiseGit管理源代码,但是对于使用VS2010的朋友来说,源代码管理起来还是不怎么方便.要是直接在VS2010中能使用Git就好了,下面我们就来看看怎么在VS2010中使用 ...
- Java基础——泛型
一.定义 泛型(generic)是指参数化类型的能力.可以定义带泛型类型的类或方法,随后编译器会用具体的类型来替换它(泛型实例化).使用泛型的主要优点是能够在编译时,而不是在运行时检测出错误.它是jd ...
- static ,final 、abstract的作用,以及它们的联系和区别
static可以修饰变量,修饰的变量直接属于某各类,不局限于某个方法,无法在成员方法中修饰变量,也不可以在静态方法中修饰变量.被static修饰的方法属于静态方法(类方法),与对象无关,与类有关.fi ...
- 了解java虚拟机—串行回收器(6)
串行回收器 串行回收器只有一个工作线程,串行回收器可以在新生代和老年代使用,根据作用于不同的堆和空间,分为新生代串行回收器和老年代串行回收器. 1.新生代串行回收器 串行收集器是所有垃圾回收器中最古老 ...
- 积分之迷-2015决赛C语言B组第一题
标题:积分之迷 小明开了个网上商店,卖风铃.共有3个品牌:A,B,C. 为了促销,每件商品都会返固定的积分. 小明开业第一天收到了三笔订单: 第一笔:3个A + 7个B + 1个C,共返积分:315 ...
- SpringCloud微服务架构第三篇
原文链接:https://www.javazhiyin.com/5130.html 微服务开发专栏:https://www.javazhiyin.com/category/springcloud Ri ...
- python生成器简单了解
1.什么是生成器 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素, ...
- 全局 DOM 变量
全局 DOM 变量 你可能已经知道,声明一个全局变量(使用 var 或者不使用)的结果并不仅仅是创建一个全局变量,而且还会在 global 对象(在浏览器中为 window )中创建一个同名属性. 还 ...
- Nginx的性能优化
1.优化worker进程个数: 在高并发.高访问量的WEB服务场景,需要事先启动更多的nginx进程,以保证快速响应并处理大量并发用户的请求,优化nginx进程个数的配置项就是,在nginx.conf ...
- java实现文件复制粘贴功能
java编程思想中讲到了IO流的思想,以前对于java基础总是不够深入,浅尝辄止,如今碰到语句插桩的时候就感到书到用时方恨少啊! 文件的复制涉及到源文件和新文件(无需手动创建),给出源文件的路径和文件 ...