java用多线程实现爬虫_JAVA 多线程爬虫实例详解
JAVA 多线程爬虫实例详解
发布于 2020-5-29|
复制链接
摘记: JAVA 多线程爬虫实例详解前言以前喜欢Python的爬虫是出于他的简洁,但到了后期需要更快,更大规模的爬虫的时候,我才渐渐意识到Java的强大。Java有一个很好的机制,就是多线程。而且Java的代码效率执行起来要比python快很多。这份博客主要用于记录 ..
JAVA 多线程爬虫实例详解前言以前喜欢Python的爬虫是出于他的简洁,但到了后期需要更快,更大规模的爬虫的时候,我才渐渐意识到Java的强大。Java有一个很好的机制,就是多线程。而且Java的代码效率执行起来要比python快很多。这份博客主要用于记录我对多线程爬虫的实践理解。线程线程是指一个任务从头至尾的执行流。线程提供了运行一个任务的机制。对于Java而言,可以在一个程序中并发地启动多个线程。这些线程可以在多处理器系统上同时运行。runnable接口任务类必须实现runnable接口,它只包含一个run方法。需要实现这个方法来告诉系统线程将如何运行。Thread类包含为任务而创建的线程的构造方法,以及控制线程的方法。synchronized关键字为避免竞争状态,防止多个线程同时进入程序的某个特定部分,即临界区,以便一次只有一个线程可以访问临界区。利用加锁同步Java可以显式加锁,一个锁是一个Lock接口的实例,它定义了加锁和释放锁的方法。线程池线程池是管理开发执行任务个数的理想方法。Java提供Executor接口来执行线程池中的任务,提供ExecutorService接口管理和控制任务。使用线程池的方法获取url列表
```java
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/*
* 获取京东评论url列表
*/
public class MyThreading {
private static String p_id = null;
private static Url urls = null;
public MyThreading(String p_id){
this.p_id = p_id ; // 京东商品的id
urls = new Url(p_id);
}
public List getUriList(){
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0 ; i urlList = new ArrayList();
private String p_id;
public Url(String p_id ){
this.p_id = p_id ;
}
public List getList(){
return urlList;
}
public void addList(int page){
lock.lock();
try{
String url = "http://club.jd.com/productpage/p-" + p_id + "-s-0-t-0-p-" + String.valueOf(page) + ".html";
// Thread.sleep(5);
urlList.add(url); //添加url到url列表
}catch(Exception ex ){
}
finally {
lock.unlock(); // 解锁
}
}
}
public static void main(String[] args) {
String p_id = "2441288";
MyThreading myThreading = new MyThreading(p_id);
List urlList = myThreading.getUriList();
for(String url : urlList){
System.out.println(url);
}
System.out.println(urlList.size());
}
}
```
代码分析
代码的作用:获取京东评论的url列表
类的说明:MyThreading是主类, AddUrl和Url是它的内部类,AddUrl实现了runnable的接口,主要启动多线程服务运行Url的addList方法。而Url是最内核的部分 ,他提供addList任务和多线程的共享区域urlList,所以在实现添加url的步骤中,需要对urlList加锁。
线程池主要有两种类型,一个是固定线程池,即newFixedThreadPool;另一个是newCachedThreadPool,这个主要利用了缓冲机制,能动态地添加线程。在上述代码中,我主要使用了newCachedthreadPool.
使用线程池的方法根据url列表爬取网页元素
```java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ThreadingCrawel {
private static Content content = null;
private static List urlList = null;
public ThreadingCrawel(List urlList){
this.urlList = urlList;
content = new Content();
}
public List getContent(){
ExecutorService executor = Executors.newCachedThreadPool();
for (String url : urlList){
executor.execute(new AddContent(url));
}
executor.shutdown();
while(!executor.isTerminated()){}
return content.getContent();
}
public static class AddContent implements Runnable{
String url;
public AddContent(String url){
this.url = url;
}
public void run(){
content.addContent(url);
}
}
public static class Content {
private static Lock lock = new ReentrantLock();
private static List contentList = new ArrayList();
public void addContent(String url){
String content = "";
BufferedReader in = null;
try{
URL realUrl = new URL(url);
URLConnection connection = realUrl.openConnection();
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "gbk"));
String line;
while( (line = in.readLine()) != null){
content += line +"\n";
}
}catch(Exception e){
e.printStackTrace();
}
finally{
try{
if (in != null){
in.close();
}
}catch(Exception e2){
e2.printStackTrace();
}
}
Pattern p = Pattern.compile("content\":\".*?\"");
Matcher match = p.matcher(content);
String tmp;
lock.lock();
while(match.find()){
tmp = match.group();
tmp = tmp.replaceAll("\"", "");
tmp = tmp.replace("content:", "");
tmp = tmp.replaceAll("", "");
contentList.add(tmp);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
lock.unlock();
}
public List getContent(){
return contentList;
}
}
public static void main(String[] args){
long start = System.currentTimeMillis();
String p_id = "2441288";
MyThreading myThreading = new MyThreading(p_id);
List urlList = myThreading.getUriList();
ThreadingCrawel threadingCrawel = new ThreadingCrawel(urlList);
List contentList = threadingCrawel.getContent();
for(String content : contentList){
System.out.println(content);
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
}
```
java用多线程实现爬虫_JAVA 多线程爬虫实例详解相关推荐
- java 获取用户的MAC地址多种方法实例详解
java 获取用户的MAC地址多种方法实例详解 这篇文章主要介绍了JAVA实现获取用户的MAC地址的多种方法实例,需要的朋友可以参考下 java实现获取用户的MAC地址方法: 方法一:将本机地址与局域 ...
- java异常例子_java 异常的实例详解
java 异常的实例详解 1.异常的定义:程序在运行时出现不正常情况. 异常的划分: Error:严重的问题,对于error一般不编写针对性的代码对其进行处理. Exception:非严重的问题,对于 ...
- java中的装饰模式讲解,java 中设计模式(装饰设计模式)的实例详解
搜索热词 java 中设计模式(装饰设计模式)的实例详解 应用场景: 在不对原有对象类进行修改的基础上,给一个或多个已有的类对象提供增强额外的功能. 我觉得可以从字面理解,装饰,装饰房子.房子可以看成 ...
- java 自定义正则表达式_java中正则表达式实例详解
Java中正则表达式运用实例(参看java中正则表达式运用详解): 测试代码 package test; /** * 在String的matches()方法,split()方法中使用正则表达式. * ...
- java编程数据溢出问题_Java数据溢出代码详解
Java数据溢出代码详解 发布时间:2020-10-05 15:08:31 来源:脚本之家 阅读:103 作者:Pony小马 java是一门相对安全的语言,那么数据溢出时它是如何处理的呢? 看一段代码 ...
- java和c++的区别_JAVA和C++区别详解
JAVA和C++区别详解 来源:-- 作者:-- 浏览:811 时间:2016-08-10 14:18 标签: 摘要: 1)java是解释性语言,java程序在运行时类加载器从类路经中加载相关的类,然 ...
- java代码逻辑讲解_java逻辑控制语句实例详解
一.Java选择结构 1.if(条件)-else结构 当条件==true时执行if下的语句,否则执行else下的语句 2.if(条件1)-else if(条件2)-else结构(相关视频教程推荐:ja ...
- java input函数怎么用_Java函数习惯用法详解
在Java编程中,有些知识 并不能仅通过语言规范或者标准API文档就能学到的.在本文中,我会尽量收集一些最常用的习惯用法,特别是很难猜到的用法. 我把本文的所有代码都放在公共场所里.你可以根据自己的喜 ...
- java中的工厂模式_java中工厂模式详解和使用方法
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻 ...
- java二分排序法原理_Java常见排序算法详解—— 二分插入排序
转载请注明出处: 二分插入排序Binary Insert Sort 概念: 二分(折半)插入排序是一种在直接插入排序算法上进行小改动的排序算法.其与直接排序算法最大的区别在于查找插入位置时使用的是二分 ...
最新文章
- 让几个div靠外面容器底部对齐
- Python面试题(三)(爬虫方面)
- Linux下开启/关闭MySql Server命令
- 我做了一个 Istio Workshop,这是第一讲介绍
- TIOBE 2014年7月编程语言排行榜:仅发布1月,Swift进Top 20!
- HTTP Authentication(HTTP认证)(转)
- java四个基本步骤_javac编译的四个主要的流程
- 《BI那点儿事》数据流转换——聚合
- vbs基础教程(1)
- 指纹识别算法MZFinger5.0
- 企业微信给微信好友定时发送图文并茂的消息
- 信息检索与利用(第三版)第四章 信息检索原理与技术
- 谷歌地图打不开怎么办?
- Unity TimeLine实用功能讲解
- 理解CTP/XTP柜台对接
- 【网络基础】Https加解密详解
- es的DSL语句查询
- DHCPV4 VS DHCPV6
- 元宇宙|世界人工智能大会之元宇宙论坛:设计篇
- 各种类型相机rtsp取流格式大汇总
热门文章
- PACKAGE-INFO.JAVA 作用及用法详解
- IGP-LAB-EIGRP-1
- 2、使用Keras构建回归模型
- mysql_query扩展_前端学PHP之mysql扩展函数
- xcode打包ipa_codesign签名ipa
- Java模拟文件管理器
- linux使用中的问题 --- (Another app is currently holding the yum lock; waiting for it to exit...)
- 单片机自动浇花器答辩记录_一个塑料瓶一颗螺丝,教你做自动浇花器,再不担心花草没人浇水了...
- Oracle存在修改,不存在插入记录 SQL
- 每周个人进度总结06