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 多线程爬虫实例详解相关推荐

  1. java 获取用户的MAC地址多种方法实例详解

    java 获取用户的MAC地址多种方法实例详解 这篇文章主要介绍了JAVA实现获取用户的MAC地址的多种方法实例,需要的朋友可以参考下 java实现获取用户的MAC地址方法: 方法一:将本机地址与局域 ...

  2. java异常例子_java 异常的实例详解

    java 异常的实例详解 1.异常的定义:程序在运行时出现不正常情况. 异常的划分: Error:严重的问题,对于error一般不编写针对性的代码对其进行处理. Exception:非严重的问题,对于 ...

  3. java中的装饰模式讲解,java 中设计模式(装饰设计模式)的实例详解

    搜索热词 java 中设计模式(装饰设计模式)的实例详解 应用场景: 在不对原有对象类进行修改的基础上,给一个或多个已有的类对象提供增强额外的功能. 我觉得可以从字面理解,装饰,装饰房子.房子可以看成 ...

  4. java 自定义正则表达式_java中正则表达式实例详解

    Java中正则表达式运用实例(参看java中正则表达式运用详解): 测试代码 package test; /** * 在String的matches()方法,split()方法中使用正则表达式. * ...

  5. java编程数据溢出问题_Java数据溢出代码详解

    Java数据溢出代码详解 发布时间:2020-10-05 15:08:31 来源:脚本之家 阅读:103 作者:Pony小马 java是一门相对安全的语言,那么数据溢出时它是如何处理的呢? 看一段代码 ...

  6. java和c++的区别_JAVA和C++区别详解

    JAVA和C++区别详解 来源:-- 作者:-- 浏览:811 时间:2016-08-10 14:18 标签: 摘要: 1)java是解释性语言,java程序在运行时类加载器从类路经中加载相关的类,然 ...

  7. java代码逻辑讲解_java逻辑控制语句实例详解

    一.Java选择结构 1.if(条件)-else结构 当条件==true时执行if下的语句,否则执行else下的语句 2.if(条件1)-else if(条件2)-else结构(相关视频教程推荐:ja ...

  8. java input函数怎么用_Java函数习惯用法详解

    在Java编程中,有些知识 并不能仅通过语言规范或者标准API文档就能学到的.在本文中,我会尽量收集一些最常用的习惯用法,特别是很难猜到的用法. 我把本文的所有代码都放在公共场所里.你可以根据自己的喜 ...

  9. java中的工厂模式_java中工厂模式详解和使用方法

    工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻 ...

  10. java二分排序法原理_Java常见排序算法详解—— 二分插入排序

    转载请注明出处: 二分插入排序Binary Insert Sort 概念: 二分(折半)插入排序是一种在直接插入排序算法上进行小改动的排序算法.其与直接排序算法最大的区别在于查找插入位置时使用的是二分 ...

最新文章

  1. 让几个div靠外面容器底部对齐
  2. Python面试题(三)(爬虫方面)
  3. Linux下开启/关闭MySql Server命令
  4. 我做了一个 Istio Workshop,这是第一讲介绍
  5. TIOBE 2014年7月编程语言排行榜:仅发布1月,Swift进Top 20!
  6. HTTP Authentication(HTTP认证)(转)
  7. java四个基本步骤_javac编译的四个主要的流程
  8. 《BI那点儿事》数据流转换——聚合
  9. vbs基础教程(1)
  10. 指纹识别算法MZFinger5.0
  11. 企业微信给微信好友定时发送图文并茂的消息
  12. 信息检索与利用(第三版)第四章 信息检索原理与技术
  13. 谷歌地图打不开怎么办?
  14. Unity TimeLine实用功能讲解
  15. 理解CTP/XTP柜台对接
  16. 【网络基础】Https加解密详解
  17. es的DSL语句查询
  18. DHCPV4 VS DHCPV6
  19. 元宇宙|世界人工智能大会之元宇宙论坛:设计篇
  20. 各种类型相机rtsp取流格式大汇总

热门文章

  1. PACKAGE-INFO.JAVA 作用及用法详解
  2. IGP-LAB-EIGRP-1
  3. 2、使用Keras构建回归模型
  4. mysql_query扩展_前端学PHP之mysql扩展函数
  5. xcode打包ipa_codesign签名ipa
  6. Java模拟文件管理器
  7. linux使用中的问题 --- (Another app is currently holding the yum lock; waiting for it to exit...)
  8. 单片机自动浇花器答辩记录_一个塑料瓶一颗螺丝,教你做自动浇花器,再不担心花草没人浇水了...
  9. Oracle存在修改,不存在插入记录 SQL
  10. 每周个人进度总结06