Java實現(xiàn)爬蟲
為什么我們要爬取數(shù)據(jù)
在大數(shù)據(jù)時代,我們要獲取更多數(shù)據(jù),就要進(jìn)行數(shù)據(jù)的挖掘、分析、篩選,比如當(dāng)我們做一個項目的時候,需要大量真實的數(shù)據(jù)的時候,就需要去某些網(wǎng)站進(jìn)行爬取,有些網(wǎng)站的數(shù)據(jù)爬取后保存到數(shù)據(jù)庫還不能夠直接使用,需要進(jìn)行清洗、過濾后才能使用,我們知道有些數(shù)據(jù)是非常真貴的。
分析豆瓣電影網(wǎng)站
我們使用Chrome瀏覽器去訪問豆瓣的網(wǎng)站如
https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0
在Chrome瀏覽器的network中會得到如下的數(shù)據(jù)

可以看到地址欄上的參數(shù)type=movie&tag=熱門&sort=recommend&page_limit=20&page_start=0
其中type是電影tag是標(biāo)簽,sort是按照熱門進(jìn)行排序的,page_limit是每頁20條數(shù)據(jù),page_start是從第幾頁開始查詢。
但是這不是我們想要的,我們需要去找豆瓣電影數(shù)據(jù)的總?cè)肟诘刂肥窍旅孢@個
https://movie.douban.com/tag/#/
我們再次的去訪問請求終于拿到了豆瓣的電影數(shù)據(jù)如下圖所示

在看下請求頭信息


最后我們確認(rèn)了爬取的入口為:
https://movie.douban.com/j/new_search_subjects?sort=U&range=0,10&tags=&start=0
創(chuàng)建Maven項目開始爬取
我們創(chuàng)建一個maven工程,如下圖所示

maven工程的依賴,這里只是爬取數(shù)據(jù),所以沒有必要使用Spring,這里使用的數(shù)據(jù)持久層框架是mybatis 數(shù)據(jù)庫用的是mysql,下面是maven的依賴
<dependencies>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>創(chuàng)建好之后,結(jié)構(gòu)如下所示

首先我們在model包中建立實體對象,字段和豆瓣電影的字段一樣,就是請求豆瓣電影的json對象里面的字段

Movie實體類
public class Movie {
private String id; //電影的id
private String directors;//導(dǎo)演
private String title;//標(biāo)題
private String cover;//封面
private String rate;//評分
private String casts;//演員
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDirectors() {
return directors;
}
public void setDirectors(String directors) {
this.directors = directors;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getCover() {
return cover;
}
public void setCover(String cover) {
this.cover = cover;
}
public String getRate() {
return rate;
}
public void setRate(String rate) {
this.rate = rate;
}
public String getCasts() {
return casts;
}
public void setCasts(String casts) {
this.casts = casts;
}
}這里注意的是導(dǎo)演和演員是多個人我沒有直接處理。這里應(yīng)該是一個數(shù)組對象。
創(chuàng)建mapper接口
public interface MovieMapper {
void insert(Movie movie);
List<Movie> findAll();
}在resources下創(chuàng)建數(shù)據(jù)連接配置文件jdbc.properties
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/huadi username=root password=root
創(chuàng)建mybatis配置文件 mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="jdbc.properties"></properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="MovieMapper.xml"/>
</mappers>
</configuration>創(chuàng)建mapper.xml映射文件
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cn.scitc.mapper.MovieMapper">
<resultMap id="MovieMapperMap" type="com.cn.scitc.model.Movie">
<id column="id" property="id" jdbcType="VARCHAR"/>
<id column="title" property="title" jdbcType="VARCHAR"/>
<id column="cover" property="cover" jdbcType="VARCHAR"/>
<id column="rate" property="rate" jdbcType="VARCHAR"/>
<id column="casts" property="casts" jdbcType="VARCHAR"/>
<id column="directors" property="directors" jdbcType="VARCHAR"/>
</resultMap>
<insert id="insert" keyProperty="id" parameterType="com.cn.scitc.model.Movie">
INSERT INTO movie(id,title,cover,rate,casts,directors)
VALUES
(#{id},#{title},#{cover},#{rate},#{casts},#{directors})
</insert>
<select id="findAll" resultMap="MovieMapperMap">
SELECT * FROM movie
</select>
</mapper>由于這里沒有用任何的第三方爬蟲框架,用的是原生Java的Http協(xié)議進(jìn)行爬取的,所以我寫了一個工具類
public class GetJson {
public JSONObject getHttpJson(String url, int comefrom) throws Exception {
try {
URL realUrl = new URL(url);
HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立實際的連接
connection.connect();
//請求成功
if (connection.getResponseCode() == 200) {
InputStream is = connection.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//10MB的緩存
byte[] buffer = new byte[10485760];
int len = 0;
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
String jsonString = baos.toString();
baos.close();
is.close();
//轉(zhuǎn)換成json數(shù)據(jù)處理
// getHttpJson函數(shù)的后面的參數(shù)1,表示返回的是json數(shù)據(jù),2表示http接口的數(shù)據(jù)在一個()中的數(shù)據(jù)
JSONObject jsonArray = getJsonString(jsonString, comefrom);
return jsonArray;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
public JSONObject getJsonString(String str, int comefrom) throws Exception{
JSONObject jo = null;
if(comefrom==1){
return new JSONObject(str);
}else if(comefrom==2){
int indexStart = 0;
//字符處理
for(int i=0;i<str.length();i++){
if(str.charAt(i)=='('){
indexStart = i;
break;
}
}
String strNew = "";
//分割字符串
for(int i=indexStart+1;i<str.length()-1;i++){
strNew += str.charAt(i);
}
return new JSONObject(strNew);
}
return jo;
}
}爬取豆瓣電影的啟動類
public class Main {
public static void main(String [] args) {
String resource = "mybatis-config.xml"; 定義配置文件路徑
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);//讀取配置文件
} catch (IOException e) {
e.printStackTrace();
}
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//注冊mybatis 工廠
SqlSession sqlSession = sqlSessionFactory.openSession();//得到連接對象
MovieMapper movieMapper = sqlSession.getMapper(MovieMapper.class);//從mybatis中得到dao對象
int start;//每頁多少條
int total = 0;//記錄數(shù)
int end = 9979;//總共9979條數(shù)據(jù)
for (start = 0; start <= end; start += 20) {
try {
String address = "https://Movie.douban.com/j/new_search_subjects?sort=U&range=0,10&tags=&start=" + start;
JSONObject dayLine = new GetJson().getHttpJson(address, 1);
System.out.println("start:" + start);
JSONArray json = dayLine.getJSONArray("data");
List<Movie> list = JSON.parseArray(json.toString(), Movie.class);
if (start <= end){
System.out.println("已經(jīng)爬取到底了");
sqlSession.close();
}
for (Movie movie : list) {
movieMapper.insert(movie);
sqlSession.commit();
}
total += list.size();
System.out.println("正在爬取中---共抓取:" + total + "條數(shù)據(jù)");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}最后我們運行將所有的數(shù)據(jù)插入到數(shù)據(jù)庫中。

項目地址
總結(jié)
爬取豆瓣網(wǎng)站非常的輕松,每頁任何的難度,需要注意的是就是start是每頁多少條我們發(fā)現(xiàn)規(guī)則當(dāng)start=0的時候是20條數(shù)據(jù)是從0到19條,就這樣每次加20條直到爬取完。
到此這篇關(guān)于Java實現(xiàn)爬蟲的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- java編程實現(xiàn)簡單的網(wǎng)絡(luò)爬蟲示例過程
- Java 使用maven實現(xiàn)Jsoup簡單爬蟲案例詳解
- Java 實現(xiàn)網(wǎng)絡(luò)爬蟲框架詳細(xì)代碼
- 半小時實現(xiàn)Java手?jǐn)]網(wǎng)絡(luò)爬蟲框架(附完整源碼)
- 使用java實現(xiàn)網(wǎng)絡(luò)爬蟲
- Java實現(xiàn)的爬蟲抓取圖片并保存操作示例
- java實現(xiàn)一個簡單的網(wǎng)絡(luò)爬蟲代碼示例
- java實現(xiàn)網(wǎng)頁爬蟲的示例講解
- java實現(xiàn)簡單的爬蟲之今日頭條
- Java爬蟲 信息抓取的實現(xiàn)
相關(guān)文章
Apache commons fileupload文件上傳實例講解
這篇文章主要為大家詳細(xì)介紹了Apache commons fileupload文件上傳實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-10-10
SpringCloud Eureka自我保護(hù)機(jī)制原理解析
這篇文章主要介紹了SpringCloud Eureka自我保護(hù)機(jī)制原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-02-02
springboot?filter配置多個時,執(zhí)行順序問題
這篇文章主要介紹了springboot?filter配置多個時,執(zhí)行順序問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12
如何基于mybatis框架查詢數(shù)據(jù)庫表數(shù)據(jù)并打印
這篇文章主要介紹了如何基于mybatis框架查詢數(shù)據(jù)庫表數(shù)據(jù)并打印,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-11-11

