前言
学校好多人都在学java的时候,有一个和我同届的大佬就开始用Python写爬虫了.人家算法比较np,所以那哥们用起Py就跟玩似的.哥们我就想,人家既然可以用Py写np的爬虫,那咱也可以用java写一个简单的啊.Py有可以解析网页的模块,java肯定会有解析网页的jar包啊,并且springboot整合的那么完美,连服务器都可以搞成jar包,网页解析功能就是个小弟.
开搞
1.先找一个想要并且可以爬取的网址,我比较喜欢看小说,就找到了这么个玩意儿
http://www.mianhuatang.cc/
2.进入网页,按F12,找到Network(网络)
点他
出来这玩意
3.idea创建一个springboot项目(自己起名字),选择web那个包
4.添加需要的依赖(jar包的maven地址)
<!--这个就是用来解析网页的-->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.12.2</version>
</dependency>
<!--这个是单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
想下载最新版的,点他 jsoup的jar包地址
5.开始伪装浏览器
/*通过地址获取连接*/
String url = "http://www.mianhuatang.cc/";
Connection connect = Jsoup.connect(url);
/*把请求头里的东西全部写在连接头里*/
connect.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
connect.header("Accept-Encoding", "gzip, deflate");
connect.header("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
connect.header("Cache-Control", "max-age=0");
connect.header("Connection", "keep-alive");
connect.header("Cookie", "UM_distinctid=171e556f9dd8-05bce87e0e10988-4c302e7f-144000-171e556f9de108; CNZZDATA1265551891=1691618955-1588687682-%7C1588687682; Hm_lvt_3da24feae7f655f938aafb15f22da69a=1588690615; Hm_lpvt_3da24feae7f655f938aafb15f22da69a=1588690615");
connect.header("Host", "www.mianhuatang.cc");
connect.header("Upgrade-Insecure-Requests", "1");
connect.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0");
//忽略错误
connect.ignoreHttpErrors(true);
/*发送get请求并获取响应*/
Connection.Response execute = connect.method(Connection.Method.GET).execute();
/*通过获取的响应解析拿到整个网页*/
Document parse = execute.parse();
/*用整个网页拿到<body></body>里面的东西*/
Element body = parse.body();
6.拿到这个<body></body>里的内容了,该解析了,
6.1 首先每一个分类里面的书最多,就是这些东西
6.2 他们都是一个个可以点击跳转的标签,该怎么拿里面的路径呢?点这玩意儿,然后移到想要拿到的标签上
6.3 左击,出现个这东西
6.4 鼠标右击a标签->复制->css选择器->在有放大镜的那一行ctrl+v(粘贴css选择器)
.nav > ul:nth-child(1) > li:nth-child(1) > a:nth-child(1)
//这样拿到的是一个,整理一下拿到所有的
.nav > ul:nth-child(1) > li
6.5 拿到之后用select选择器选择解析(这就拿到了每一个li标签)
6.6 for循环一下可以用select.get(i).select("a").attr("href")获取a标签中的地址,url+""+select.get(i).select("a").attr("href")获取完整地址,之后用一个集合把每一个分类的地址存进去
6.6 for循环遍历每一个地址,再次用Jsoup.connect(url);来获取连接,之后重复上面的方法就可以拿到书名,简介,作者等信息.
结果:
由于数量过多,我没学多线程爬虫,所以没爬取文章内容,也没往数据库存
源码:
package org.test.pabook.test;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.junit.Test;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class BookTest {
private static Element getConn(String url) throws IOException {
/*通过地址获取连接*/
Connection connect = Jsoup.connect(url);
/*把请求头里的东西全部写在连接头里*/
connect.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
connect.header("Accept-Encoding", "gzip, deflate");
connect.header("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
connect.header("Cache-Control", "max-age=0");
connect.header("Connection", "keep-alive");
connect.header("Cookie", "UM_distinctid=171e556f9dd8-05bce87e0e10988-4c302e7f-144000-171e556f9de108; CNZZDATA1265551891=1691618955-1588687682-%7C1588687682; Hm_lvt_3da24feae7f655f938aafb15f22da69a=1588690615; Hm_lpvt_3da24feae7f655f938aafb15f22da69a=1588690615");
connect.header("Host", "www.mianhuatang.cc");
connect.header("Upgrade-Insecure-Requests", "1");
connect.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0");
//忽略错误
connect.ignoreHttpErrors(true);
/*发送get请求并获取响应*/
Connection.Response execute = connect.method(Connection.Method.GET).execute();
/*通过获取的响应解析拿到整个网页*/
Document parse = execute.parse();
/*用整个网页拿到<body></body>里面的东西*/
return parse.body();
}
/*拼接地址*/
private static String jiequ(String k) {
String split = k.substring(0, k.lastIndexOf("/"));
String split0 = k.substring(0, k.lastIndexOf("."));
String[] split1 = split0.split(split);
String[] split2 = split1[1].split("-");
String[] split3 = split2[0].split("/");
String url = split + "/" + split3[1] + "-";
System.out.println(url);
return url;
}
@Test
public void pa() throws IOException {
String url = "http://www.mianhuatang.cc/";
Element body = getConn(url);
Elements select = body.select(".nav > ul:nth-child(1) > li");
String uri = null;
Map<String, String> bookMap = new HashMap<>();
for (int i = 0, len = select.size(); i < len; i++) {
if (i == 0) {
uri = select.get(i).select("a").attr("href");
continue;
}
bookMap.put(uri + "" + select.get(i).select("a").attr("href"), select.get(i).text());
uri = select.get(0).select("a").attr("href");
}
//从集合里面拿到每一个分类的路径
for (String value : bookMap.keySet()) {
System.out.println(value + " ->" + bookMap.get(value));
String jiequ = jiequ(value);
Element conn = getConn(value);
Elements select2 = conn.select(".main > .articlepage .pages > .lastpage");
String text = select2.text().replace("...", "");
int i = Integer.parseInt(text);
test(jiequ, i);
System.out.println(i + "\n\n\n");
}
}
// 爬取每个分类里面的内容
private static void test(String url, int num) throws IOException {
String url1;
for (int i = 1; i <= num; i++) {
url1 = url + i + ".html";
Element body = getConn(url1);
Elements select = body.select("div.alistbox > .info .title > h2:nth-child(1) > a");
for (Element element : select) {
System.out.println(element);
}
url1 = url;
}
}
}
我是把每个分类的所有书名和URL拿到了,就行当于俄罗斯套娃那样将网页地址一层层剥开了.
网友评论