java爬虫

爬虫的三大模块
1.获取数据
2.解析数据
3.保存数据

爬虫说白了就是一个程序,用来获取网络上的数据

爬虫的价值在于数据的价值

爬虫分类:
通用型爬虫:用来获取互联网上所有的数据,代表就是百度,谷歌
垂直型爬虫:爬取特定的行业或网站的特定信息的爬虫程序

爬虫的爬取过程
1.指定爬取的url
2.获取数据
3.解析数据(解析url)
4.保存数据

爬虫程序在爬取数据的时候要把自己伪装成一个浏览器,这样就不容易被干掉,主要可以在请求头上做一些文章
user-agent 指定浏览器的内核版本
referer 指定来源 部分网站用于防盗链
cookie 用来判断用户的登录状态(JSESSIONID) 通过session的id找到session看看里面是不是有用户,有就是登录的状态

爬取完的数据是放在响应体中的,另外服务器也会向浏览器设置cookie,这个需要获取并模拟,假装一个真正的浏览器

用原生jdk获取网页信息的过程
1.定义url字符串
2.创建URL对象
3.通过URL对象获取连接对象
4.设置请求方式
5.获取输入流
6.从输入流中获取数据

切记写完代码以后,程序没运行就是还没有干活呢,里面还没有数据

httpClient是Apache开源的工具,是专为http请求而生的
使用步骤
首先导包
1.定义url字符串
2.创建HttpClient对象 HttpClients.createDefaults();
3.创建请求方式对象 HttpGet HttpPost() 可以将url传入构造方法 get的参数直接写在url字符串中 post的请求体需要自己创建
4.HttpClient执行请求方式对象 获取响应结果对象 response
5.从结果对象中获取我么想要的数据 response 获取响应状态行 获取响应头 获取响应体(HttpEntity)
6.EntityUtils.toString(entity,“UTF-8”); 获得html页面

Jsoup是Apache开源的解析html的java工具,一般不用他的connect(URL url).get()方式来获取document对象,因为比起httpClient它的效率相对较低 Jsoup的主要功能是解析这块

网站的数据爬取
简单的比如启点中文网,直接进去找到相关的链接再继续新的链接,重复的部分,循环获取就可以
需要获得一些登录后的信息的,就需要模拟浏览器,发送一样的请求方式,一样的请求体,一些referer 再次访问别的页面,需要携带服务器设置的cookie 小网站是这些,大些的还需要再研究

客户端最后记得要关掉

浏览器请求服务器后服务器响应体中返回页面信息,如果其中包含ajax代码时,浏览器会再次发送异步请求获取此处的数据,返回的数据一般是Json格式的

跨域请求,当协议,域名,端口号有一项不相同时就可以称为跨域 跨域请求中有一个同源策略,那就是只能访问自己网站里的内容,如果想访问别的网站的内容怎么办呢,jsonp就可以解决此问题,这是Json的一种使用模式

线程安全问题,容器安全,你的数据也就安全

线程除了继承Thread类,和实现Runnable接口,还有有返回值的线程,Callable FutureTask new Thread(new FutureTask(new Callable(){})

创建一个线程从时间和内存上来说都是昂贵的,因为创建它需要占用内存的资源,操作系统的调用等等 而它的内存是不受java程序的控制,在java程序之外分配系统的内存 默认一个线程的线程栈大小是1M

Executors.newFixedThreadPool(num) 创建固定大小的线程池
newCaechedThreadPool()创建可大可小的线程池

newScheduledThreadPool创建定时执行的线程池
pool.scheduledAtFixedRate(new Runnable(),0,1000,时间单位) 0代表无延迟 时间单位代表1000的时间单位 定时执行不管上一个任务是否执行完毕
pool.scheduledWithFixedDelay(new Runnable(),0,1000,时间单位) 0代表无延迟 时间单位代表1000的时间单位 等上一个任务执行完毕后 过指定的时间执行(会等上一个任务)

newSingleThreadExecutor(); 创建一个单线程执行的线程池
newSingleThreadScheduledExecutor(); 创建一个单线程定时执行的线程池

线程任务是可以放在线程池之外的,这样就可以创建一个FutureTask 然后回调完成的结果 输出结果

队列一般都是先进先出的FIFO

队列的api有两组,一组是抛出异常的,一组是返回特殊值的
异常组: add()添加 remove()删除 element()查看元素
特殊值组:offer()添加 poll()移除 peek()查看元素

queue被称为原生队列,只允许在尾部插入队列,在头部弹出队列
异常组: addFirst() addLast()添加 removeFirst() removeLast()删除 getFirst() getLast()查看元素 get方法只会查看不会移除
特殊值组:offerFirst() offerLast()添加 pollFirst() pollLast()移除 peekfirst() peeklast()查看元素

BlockingQueue BlockingDeque 阻塞双端和单端队列 使用阻塞方法是线程安全的 put()存数据 take()取数据 如果无法存或者取会无限等待
offer(time) poll(time) 有时间限制的这两种方法在阻塞队列中也是线程安全的

多线程获取pid并消费pid的注意事项,单个线程的流程相对较为简单,但是多线程的时候相对有一些细节需要注意
首先Callable FutureTask 的使用,它的返回值方法会阻塞其他方法的执行,这块要注意,不要阻塞的不能执行
线程池的使用,线程池调用execute方法,里面就是多线程了,不会阻塞其他方法 ,但它每次只能执行一个线程,如果执行30个要循环,另外线程内部死循环执行
主线程监控其他线程执行,单独自己的逻辑
线程池用完了记得关了,不然程序还是处于运行状态
线程池关了,运行中的线程还是在运行不会关闭,直到程序运行完毕.死循环的线程可以设置线程的终止条件是线程池关闭,这样也可以在线程池关闭后结束所有线程

程序部署到linux上运行
1.保证linux上安装了jdk不低于我们代码的版本
2.安装了mysql,并且开启了远程访问的权限
3.mysql中建立相关的库和表
4.相关连接数据库的参数进行修改,改为连接linux,连接url后面加一个参数characterEncoding=UTF-8 防止出现乱码的情况
5.导入打包插件 assembly 并指定程序的主入口
6.使用插件的打包功能打包 打包前记得重新编译一下,因为idea只在执行程序前会编译,其他时间不会自动编译 (maven自带的打包功能只会打我们的代码,不会打包依赖的jar包)

在部署到linux上后,会出现一个问题,那就是说密码错误但是经排查发现没有问题,解决办法就是将user表中没用的用户全部删除掉,只留一个本地和一个远程即可,可能是别的在干扰我们

展开阅读全文

没有更多推荐了,返回首页