在上次学习了爬取一章的文本之后, 我想到可不可以把所有章节的文本都爬取到, 换句话说, 爬取到分页的数据。
那么开始今天的实验 :
第一步:
寻找目标,我比较喜欢看动漫,但是每一页的动漫只有几十个动漫名字, 很多都看过了, 所以为了一次性的查看所有的动漫名, 这次实验的目标就确定了。
https://www.yinghuadongman123.com/y/2.html
樱花动漫网
第二步:
httpClient + 正则表达式 ,虽然也挺好的, 但是我们还是采用, jsoup 这个比较方便。
我们还是先引入依赖``
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.12.1</version>
</dependency>
第三步:
先尝试爬取第一页的动漫名字
成功的代码:
package com.example.demo;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class Test4 {
public static void main(String[] args) {
try {
Document document =Jsoup.connect("https://www.yinghuadongman123.com/y/2.html").get();
Elements elements=document.select("body > div:nth-child(1) > div > div > div.stui-pannel__bd.clearfix > ul > li> div > div > h4 > a");
for(Element i : elements)
{
String str=i.attr("title");
System.out.println(str);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
结果:
第四步:
来到了今天最重要的一步:
怎么获取分页的数据,经过分析发现第一页的css表达式和第二页的css表达式差不多, 那么关键之处就不再这个css表达式上, 通过控制变量法, 我发现网页的地址不一样 ,
除了第一页之外其他的地址的格式都是
https://www.yinghuadongman123.com/y/2-i.html
i是第几页 就是几
接下来我们把第一页到第3页的动漫名字爬出来。
成功代码如下:
package com.example.demo;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.util.ArrayList;
//body > div:nth-child(1) > div > div > div.stui-pannel__bd.clearfix > ul > li:nth-child(1) > div > div > h4 > a
public class Test4 {
public static void main(String[] args) {
try {
ArrayList<String> ans=new ArrayList<>();
ans.add("https://www.yinghuadongman123.com/y/2.html");
String str="https://www.yinghuadongman123.com/y/2";
String str2=".html";
for(int i=2;i<=3;i++)
{
String str3=str+"-"+i+str2;
ans.add(str3);
}
int index=1;
for(String j: ans ) {
System.out.println("动漫第" +(index++)+"页");
Document document = Jsoup.connect(j).get();
int w=0;
Elements elements = document.select("body > div:nth-child(1) > div > div > div.stui-pannel__bd.clearfix > ul > li> div > div > h4 > a");
for (Element i : elements) {
w++;
String str1 = i.attr("title");
System.out.print(str1+"\t");
if(w==4)
{
System.out.println();
w=0;
}
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
结果截图:
第三页对比
第五步:
虽然成功了但是如果网页的网址区别的复杂度太高呢?
那么这种方法就成功不了
于是我打算在做一次实验, 换一个目标
起点中文网猩红降临第二和第三章的内容,
在这里插入代码片
将前面的总结我们得到了一条思路
如果要爬取有相同HTML结构的网页,
那么我们可以先爬取所有网页地址,
再根据网页的结构去爬取我们想要的数据
第六步:
爬取第二章和第三章的网址
呃,遇到了前端反调试debugger (一种反爬措施)
没办法, 去另一个网站做实验。
笔趣阁
成功的代码:
package com.example.demo;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import javax.print.Doc;
import java.net.URL;
import java.util.ArrayList;
//body > div:nth-child(1) > div > div > div.stui-pannel__bd.clearfix > ul > li:nth-child(1) > div > div > h4 > a
public class Test4 {
public static void main(String[] args) {
try {
//https://book.qidian.com/info/1034000598/?WxUg5ztDmi=1658285555106
/// Document document=Jsoup.parse(new URL("https://book.qidian.com/info/1034000598/?WxUg5ztDmi=1658285555106"),60000);
Document document=Jsoup.connect("https://www.mayiwxw.com/67_67743/index.html").get();
System.out.println(document);
//https://www.qidian.com/
Elements elements=document.select("#list > dl > dd > a");
System.out.println("成功了");
int index=0;
String mainurl="https://www.mayiwxw.com";
for(Element i: elements)
{
String w=i.attr("href");
String o=i.ownText();
System.out.println(o);
Document document1=Jsoup.connect(mainurl+w).get();
Elements elements1=document1.select("#content");
for(Element j : elements1)
{
String p=j.ownText();
System.out.println(p);
}
index++;
if(index>2) break;
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
结果如图:
今天就差不多了。