1. 介绍
Jsoup是Java中的一个包,可以用于爬取页面中的数据
Jsoup爬取数据分为以下几个步骤:
1. 获取所爬取网页的Document对象
2. 找到所爬取数据所在的父级标签,将其从Document对象中解析出来,解析出来的内容放置在Element对象中
3. 再在Element中通过每一个数据所在的子标签去解析,解析出来的内容放置在Elements对象中
4. 最后再通过每一个Element对象中的属性获得想要爬取的数据
接下来以爬取京东商品页面中的商品数据为例
2. 新建SpringBoot项目,并导入依赖
<!-- 解析网页 -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.10.2</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
3. 确认进行爬取的链接
进入京东官网,随便搜索一个商品,看上方的链接
例如:https://search.jd.com/Search?keyword=笔记本&enc=utf-8&wq=笔记本&pvid=371fd4a6b1ef4b138e493cd39d4a34dc
去掉后面多余的参数,得到最后的目标链接:
https://search.jd.com/Search?keyword=笔记本
这个就是最后我们爬取数据时需要的链接
// 获取请求 https://search.jd.com/Search?keyword=java
String url = "https://search.jd.com/Search?keyword=" + keywords;
/* 解析网页 超过 30s 没有返回就报错 Jsoup返回的Document就是浏览器的Document对象 */
Document document = Jsoup.parse(new URL(url), 30000);
4. 找到所有数据的父级标签
找到所有商品所在的父级div,通过其id获取该div的Element对象
/* J_goodsList 是京东数据展示的那个 div 的名字 获取上述 url 中 div 名字为 J_goodsList 的 html */
Element element = document.getElementById("J_goodsList");
5. 找到每个数据放置的标签
发现页面中每个商品的数据都是放在li里,然后通过getElementsByTag()方法获取上述父级盒子的Element对象里所有li标签的Element对象集合
// 获取 J_goodsList 中的所有 li,然后进行循环
Elements elements = element.getElementsByTag("li");
for (Element el : elements) {
...
}
6. 准备对象
本次只爬取页面中商品的标题,图片链接和价格
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Content {
private String title;
private String img;
private String price;
}
6.1 找到数据所处的位置
位置都是通过标签里的属性来进行定位的
普及:
大部分图片特别多的网站,所有的图片都是延迟加载的,即在页面进行渲染时,图片的链接不是放在标签的src属性中
所谓延迟加载,意思是页面在出现的时候,所有图片不会立马显现出来,而是都会先默认显示一张图片,等到真正的图片传输过来时才将默认图片替换成真正的图片
所以在这里寻找图片链接时,不能去寻找图片的src属性
6.1.1 寻找图片
在京东,图片的真正地址在img标签里的data-lazy-img属性中。所以我们要获取上述li标签里的img标签的属性
/* getElementsByTag 通过标签进行获取 eq(0) 获取第一个元素 attr() 获取属性里的值 */
String img = el.getElementsByTag("img").eq(0).attr("data-lazy-img");
6.1.2 寻找价格数据所处位置
/* getElementsByClass 通过 class 的名字进行获取 eq(0) 获取第一个元素 text() 所有的文本 */
String price = el.getElementsByClass("p-price").eq(0).text();
6.1.3 寻找标题数据所处位置
/* getElementsByClass 通过 class 的名字进行获取 eq(0) 获取第一个元素 text() 所有的文本 */
String title = el.getElementsByClass("p-name").eq(0).text();
7. 将找到的数据封装进对象
完整代码如下:
import com.gec.pojo.Content;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class HtmlParseUtil {
public static void main(String[] args) throws IOException {
new HtmlParseUtil().parseJD("搞笑")
.forEach(System.out::println);
}
public List<Content> parseJD(String keywords) throws IOException {
String url = "https://search.jd.com/Search?keyword=" + keywords;
Document document = Jsoup.parse(new URL(url), 30000);
Element element = document.getElementById("J_goodsList");
// 获取 J_goodsList 中的所有 li
Elements elements = element.getElementsByTag("li");
List<Content> goodsList = new ArrayList<>();
// 获取元素中的内容,这里是 el ,就是每一个li标签
for (Element el : elements) {
String img = el.getElementsByTag("img").eq(0).attr("data-lazy-img");
String price = el.getElementsByClass("p-price").eq(0).text();
String title = el.getElementsByClass("p-name").eq(0).text();
Content content = new Content();
content.setImg(img);
content.setPrice(price);
content.setTitle(title);
goodsList.add(content);
}
return goodsList;
}
}
8. 结果
Content(title=汇鑫泉运通 假山流水喷泉屏风高山水景观流水墙水幕墙风水轮家居公司前台风水轮招财落地摆件装饰品 7079 (长91*宽51*高170CM), img=//img12.360buyimg.com/n7/jfs/t1/154317/8/10257/352628/5fdac831Efef04fcb/13a5e3a464c0c024.jpg, price=¥3188.00)
Content(title=抖音同款网红遥控大便屎玩具便便车发声仿真粑粑恶搞整蛊搞笑礼物 遥控便便 普通电池款 抖音同款网红遥控大便屎玩具便便车发声仿真粑粑恶搞整蛊搞笑礼物 遥控便便 普通电池款, img=//img11.360buyimg.com/n7/jfs/t1/135096/39/22238/136938/61e57f8fE8f1f97a3/7a462e78f4d3b762.jpg, price=¥25.80)
...
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/38498.html