Java爬虫——转CSDN博主:代码忘烦恼 (以豆瓣为例,大致描述如何看数据,如何看请求头,未用爬虫框架,爬到相关电影地址)


https://blog.csdn.net/qwe86314/article/details/91450098

为什么我们要爬取数据

在大数据时代,我们要获取更多数据,就要进行数据的挖掘、分析、筛选,比如当我们做一个项目的时候,需要大量真实的数据的时候,就需要去某些网站进行爬取,有些网站的数据爬取后保存到数据库还不能够直接使用,需要进行清洗、过滤后才能使用,我们知道有些数据是非常真贵的。

分析豆瓣电影网站

我们使用Chrome浏览器去访问豆瓣的网站如 :https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0

在Chrome浏览器的network中会得到如下的数据

可以看到地址栏上的参数type=movie&tag=热门&sort=recommend&page_limit=20&page_start=0

其中type是电影tag是标签,sort是按照热门进行排序的,page_limit是每页20条数据,page_start是从第几页开始查询。

但是这不是我们想要的,我们需要去找豆瓣电影数据的总入口地址是下面这个:

https://movie.douban.com/tag/#/

我们再次的去访问请求终于拿到了豆瓣的电影数据如下图所示

在看下请求头信息

Movie 实体类

public class Movie {

private String id; //电影的id

private String directors;//导演

private String title;//标题

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;

}

}

工具类:

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();

//转换成json数据处理

// getHttpJson函数的后面的参数1,表示返回的是json数据,2表示http接口的数据在一个()中的数据

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;//记录数

int end = 9979;//总共9979条数据

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("已经爬取到底了");

sqlSession.close();

}

for (Movie movie : list) {

movieMapper.insert(movie);

sqlSession.commit();

}

total += list.size();

System.out.println("正在爬取中---共抓取:" + total + "条数据");

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

总结

爬取豆瓣网站非常的轻松,每页任何的难度,需要注意的是就是start是每页多少条我们发现规则当start=0的时候是20条数据是从0到19条,就这样每次加20条直到爬取完。

版权

声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/qwe86314/article/details/91450098为什么我们要爬取数据在大数据时代,我们要获取更多数据,就要进行数据的挖掘、分析、筛选,比如当我们做一个项目的时候,需要大量真实的数据的时候,就需要去某些网站进行爬取,有些网站的数据爬取后保存到数据库还不能够直接使用,需要进行清洗、过滤后才能使用,我们知道有些数据是非常真贵的。
分析豆瓣电影网站我们使用Chrome浏览器去访问豆瓣的网站如
https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=01在Chrome浏览器的network中会得到如下的数据
可以看到地址栏上的参数type=movie&tag=热门&sort=recommend&page_limit=20&page_start=0其中type是电影tag是标签,sort是按照热门进行排序的,page_limit是每页20条数据,page_start是从第几页开始查询。但是这不是我们想要的,我们需要去找豆瓣电影数据的总入口地址是下面这个
https://movie.douban.com/tag/#/1我们再次的去访问请求终于拿到了豆瓣的电影数据如下图所示
在看下请求头信息

最后我们确认了爬取的入口为:
https://movie.douban.com/j/new_search_subjects?sort=U&range=0,10&tags=&start=01创建Maven项目开始爬取我们创建一个maven工程,如下图所示

maven工程的依赖,这里只是爬取数据,所以没有必要使用Spring,这里使用的数据持久层框架是mybatis 数据库用的是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>12345678910111213141516171819202122232425262728293031创建好之后,结构如下所示

首先我们在model包中建立实体对象,字段和豆瓣电影的字段一样,就是请求豆瓣电影的json对象里面的字段

Movie实体类
public class Movie {
private String id; //电影的id private String directors;//导演 private String title;//标题 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; }}
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859这里注意的是导演和演员是多个人我没有直接处理。这里应该是一个数组对象。
创建mapper接口
public interface MovieMapper {
void insert(Movie movie); List<Movie> findAll();}123456在resources下创建数据连接配置文件jdbc.properties
driver=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/huadiusername=rootpassword=root1234创建mybatis配置文件 mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//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>123456789101112131415161718192021创建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>1234567891011121314151617181920212223由于这里没有用任何的第三方爬虫框架,用的是原生Java的Http协议进行爬取的,所以我写了一个工具类
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(); //转换成json数据处理 // getHttpJson函数的后面的参数1,表示返回的是json数据,2表示http接口的数据在一个()中的数据 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; }
}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960爬取豆瓣电影的启动类
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;//记录数 int end = 9979;//总共9979条数据 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("已经爬取到底了"); sqlSession.close(); } for (Movie movie : list) { movieMapper.insert(movie); sqlSession.commit(); } total += list.size(); System.out.println("正在爬取中---共抓取:" + total + "条数据");
} catch (Exception e) { e.printStackTrace(); }
} }
}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950最后我们运行将所有的数据插入到数据库中。

项目地址github
总结爬取豆瓣网站非常的轻松,每页任何的难度,需要注意的是就是start是每页多少条我们发现规则当start=0的时候是20条数据是从0到19条,就这样每次加20条直到爬取完。
下一篇爬取前程无忧爬取前程无忧所有数据————————————————版权声明:本文为CSDN博主「代码忘烦恼」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qwe86314/article/details/91450098

优质内容筛选与推荐>>
1、Digg:无所依的产业链
2、3297: [USACO2011 Open]forgot
3、node.js1
4、lambda表达式
5、tesseract-ocr如何训练Tesseract 4.0


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号