数据学习
登录
注册
原创博客
期刊会议
学术世界
期刊出版社
领域期刊
SCI/SCIE/SSCI/EI简介
期刊列表
会议列表
所有期刊分区
学术期刊信息检索
JCR期刊分区查询
CiteScore期刊分区查询
中科院期刊分区查询
领域期刊分区
管理 - UTD24期刊列表
管理 - AJG(ABS)期刊星级查询
管理 - FMS推荐期刊列表
计算机 - CCF推荐期刊会议列表
高校期刊分区
南大核心(CSSCI)
合工大小核心
合工大大核心
AI资源仓库
AI领域与任务
AI研究机构
AI学术期刊
AI论文快讯
AI数据集
AI开源工具
AI模型
AI模型概览
预训练模型
数据推荐
网址导航
我的网址导航
程序员必备网站
Java多线程网络爬虫(时光网为例)
标签:
#Java#
#网络爬虫#
时间:2016-09-26 08:27:06
作者:十七岁的雨季
原文地址:http://blog.csdn.net/qy20115549/article/details/52648631 **目录** [TOC] #多线程简介 Java多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。 本文所采用的方法是继承Thread类的方法,Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。 #多线程网络爬虫 为了加快爬虫速度,可以采用多线程网络爬虫的方法。以下我以时光网为例,写一个简单的网络爬虫。 #分析要爬的数据 如下面数据,为我爬的一些电影预告片的初始信息,存在数据库movie的这张表中。  下表是我所要爬的预告片相关的数据,包括预告片的id(prmovieId),预告片的链接(url),预告片对应的电影id(movieId),预告片的标题(title)。后面会在model框架中,你会发现,我会把这些待爬取的数据封装在MtimeModel中。  #网络抓包 通过网络抓包的方式,查看数据的获取方式、方法。即真实请求的地址及返回数据的格式(html or json). 如果你不会网络抓包,请参考我前面所写的与爬虫相关的一系列博客,或者这个地址:http://blog.csdn.net/qy20115549/article/details/52249232 #爬虫框架 如果想了解,为什么这样写,请看我前面的介绍网络爬虫框架的文章。  #model model里面主要写了三个,我们需要的,一个是MtimeUrl封装的是数据库movie这张表中某些数据对应的信息。 MtimeModel封装的是需要爬取数据的信息。 ```java package org.autodata.model; /* * author:合肥工业大学 管院学院 钱洋 *1563178220@qq.com */ public class MtimeUrl { //待爬取电影的id和对应的连接 private String id; private String url; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } } ``` 爬取的数据为: ```java package org.autodata.model; /* * author:合肥工业大学 管院学院 钱洋 *1563178220@qq.com */ public class MtimeModel { private String prmovieId; private String url; private String movieId; private String title; public String getPrmovieId() { return prmovieId; } public void setPrmovieId(String prmovieId) { this.prmovieId = prmovieId; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getMovieId() { return movieId; } public void setMovieId(String movieId) { this.movieId = movieId; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } } ``` Json数据的解析model ```java package org.autodata.model; /* * author:合肥工业大学 管院学院 钱洋 *1563178220@qq.com */ public class JsonModel { private String VideoID; private String MovieID; private String ShortTitle; private String prmovieId; private String url; public String getVideoID() { return VideoID; } public String getShortTitle() { return ShortTitle; } public void setShortTitle(String shortTitle) { ShortTitle = shortTitle; } public String getPrmovieId() { return prmovieId; } public void setPrmovieId(String prmovieId) { this.prmovieId = prmovieId; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public void setVideoID(String videoID) { VideoID = videoID; } public String getMovieID() { return MovieID; } public void setMovieID(String movieID) { MovieID = movieID; } } ``` #MtimeThread主方法 主方法里为了方便,我直接使用的是Jsoup去请求数据,建议大家还是使用httpclient,因为有时候Jsoup是失灵的。 ```java package org.autodata.navi.main; /* * author:合肥工业大学 管院学院 钱洋 *1563178220@qq.com */ import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.sql.DataSource; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.ResultSetHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.autodata.db.MyDataSource; import org.autodata.model.MtimeModel; import org.autodata.model.MtimeUrl; import org.autodata.parse.MtimeParse; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; public class MtimeThread extends Thread{ public static DataSource ds = MyDataSource.getDataSource("jdbc:mysql://127.0.0.1:3306/moviedata"); public static QueryRunner qr = new QueryRunner(ds); String Starturl = ""; String Id=""; //构造函数,初始化使用 public MtimeThread (String Starturl,String Id){ this.Starturl = Starturl; this.Id = Id; } public void run(){ List
moviedatas=new ArrayList
(); //这里采用jsoup直接模拟访问网页 try { Document doc = Jsoup.connect(Starturl).userAgent("bbb").timeout(120000).get(); moviedatas =MtimeParse.getData(doc); } catch (IOException e) { e.printStackTrace(); } for (MtimeModel mt:moviedatas) { System.out.println("prmovieId:"+mt.getPrmovieId()+" movieId:"+mt.getMovieId()+" Title:"+mt.getTitle() +" url:"+mt.getUrl()); } try { MYSQLControl.executeUpdate(moviedatas,Id); } catch (SQLException e) { e.printStackTrace(); } } public static void main(String[] args) throws SQLException{ ResultSetHandler
> h = new BeanListHandler
(MtimeUrl.class); List
Starturls = qr.query("SELECT id,url FROM moviedata.movie WHERE website='时光网' and is_crawler=0", h); //创建固定大小的线程池 ExecutorService exec = Executors.newFixedThreadPool(5); for (MtimeUrl Start:Starturls) { //执行线程 exec.execute(new MtimeThread(Start.getUrl(),Start.getId())); } //线程关闭 exec.shutdown(); } } ``` #MtimeParse解析数据 ```java package org.autodata.parse; /* * author:合肥工业大学 管院学院 钱洋 *1563178220@qq.com */ import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.autodata.model.JsonModel; import org.autodata.model.MtimeModel; import org.jsoup.nodes.Document; import com.alibaba.fastjson.JSON; public class MtimeParse { public static List
getData (Document doc) { List
mtimeData=new ArrayList
(); //获取待解析的html文件 String html=doc.html(); //fastJson测试 //just contain the preview List
mtimeJsonData=new ArrayList
(); Pattern data1 = Pattern.compile("预告片\":(.*?)\\,(\"拍摄花絮|\"精彩片段)"); Matcher dataMatcher1 = data1.matcher(html); String da1=""; while (dataMatcher1.find()) { //待解析的json字符串 da1=dataMatcher1.group(1); } if (da1.length()!=0) { List
jsonmodel1 = JSON.parseArray(da1,JsonModel.class); for (JsonModel jso:jsonmodel1 ) { JsonModel mtimeModel=new JsonModel(); String VideoID="mtime"+jso.getVideoID(); String MovieID="mtime"+jso.getMovieID(); String ShortTitle=jso.getShortTitle(); String url="http://video.mtime.com/"+jso.getVideoID()+"/?mid"+jso.getMovieID(); mtimeModel.setPrmovieId(VideoID); mtimeModel.setUrl(url); mtimeModel.setMovieID(MovieID); mtimeModel.setShortTitle(ShortTitle); mtimeJsonData.add(mtimeModel); } } return mtimeData; } } ``` #数据库操作 MyDataSource ```java package org.autodata.db; import javax.sql.DataSource; import org.apache.commons.dbcp2.BasicDataSource; /* * author:合肥工业大学 管院学院 钱洋 *1563178220@qq.com */ public class MyDataSource { public static DataSource getDataSource(String connectURI){ BasicDataSource ds = new BasicDataSource(); //MySQL的jdbc驱动 ds.setDriverClassName("com.mysql.jdbc.Driver"); ds.setUsername("root"); //所要连接的数据库名 ds.setPassword("112233"); //MySQL的登陆密码 ds.setUrl(connectURI); return ds; } } ``` ```java package org.autodata.db; import java.sql.SQLException; import java.util.List; import javax.sql.DataSource; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.autodata.model.MtimeCommentModel; import org.autodata.model.MtimeModel; /* * author:合肥工业大学 管院学院 钱洋 *1563178220@qq.com */ public class MYSQLControl { static final Log logger = LogFactory.getLog(MYSQLControl.class); static DataSource ds = MyDataSource.getDataSource("jdbc:mysql://127.0.0.1:3306/moviedata"); static QueryRunner qr = new QueryRunner(ds); //第一类方法 public static void executeUpdate(String sql){ try { qr.update(sql); } catch (SQLException e) { logger.error(e); } } //第二类数据库操作方法 public static void executeUpdate(List
moviedata,String id) throws SQLException { //定义一个Object数组,行列 Object[][] params = new Object[moviedata.size()][4]; for ( int i=0; i
moviedata,String id) throws SQLException { Object[][] params = new Object[moviedata.size()][3]; for ( int i=0; i
相关博客
最热博客