Jsoup用法

Jsoup可以解析请求返回的HTML页面,因为有些页面中的数据不是通过接口的形式返回的,它是在服务器中就已经把数据和页面渲染好了,然后直接返回,用WebDriver的方法可以通过无头浏览器获取网站的页面结构,从而通过Jsoup来解析页面获取数据。

就像这样,接口中并没有返回相应的数据
在这里插入图片描述

但是我们可以通过Jsoup的方式获取到HTML页面中的信息,所以使用Jsoup的前提就是需要掌握一些HTML的知识

/**
	 * 小红书 通过url获取文章
	 * @param url
	 * @return
	 */
	private CompositionResult xiaohongshuCopositionResult(String url) {
		CompositionResult compositionResult =null;
		// 这里从分享的小红书连接中提取出URL
		Matcher m = Pattern.compile("(?i)(http|https)://[^\u4e00-\u9fa5]+").matcher(url);
		String realUrl = "";

		// 解析url
		while(m.find()){
			realUrl = m.group();
			logger.info(realUrl);
			if(realUrl.endsWith(",")) {
				realUrl = realUrl.substring(0, realUrl.length() - 1);
				logger.info(realUrl);
			}
		}

		Document doc = null;
		Map<String,Object> driverMap = null;
		try {
			// 获取浏览器
			driverMap = chromeDriverService.getDriver();
			// 发起请求
			String chromeDriver = chromeDriverPage(realUrl, TargetPlatformEnums.XIAOHONGSHU,driverMap);
			// 用Jsoup进行解析无头浏览器返回的页面信息
			doc = Jsoup.parse(chromeDriver);
			logger.info(doc.toString());
			//这个方法就是获取元素中属性名和值相应的元素,取第一个
			Element script = doc.getElementsByAttributeValue("type", "application/ld+json").first();
			// 有一些网络语法,JSONObject解析不了,就要先从中替换了解析不了的地方
			String dataStr = script.data().trim().replace("@", "");
			JSONObject dataObj = JSONObject.parseObject(dataStr);
			// 自己封装的方法,用来判断返回值是否为空
			Assert.isNotNull(dataObj, ErrorCodeUtil.PARAMETER_NULL);

			JSONObject authorObj = dataObj.getJSONObject("author");
			Assert.isNotNull(authorObj, ErrorCodeUtil.PARAMETER_NULL);
			String authorUrl = authorObj.getString("url");

			String[] split = authorUrl.split("/");
			String id = split[split.length - 1];
			
			// 通过class名获取元素,通常获取到的是一个数组
			Elements nameElement=doc.getElementsByClass("name-detail");
			String name = nameElement.get(0).text();
			logger.info("名字:"+nameElement.get(0).text());
			Elements likeElement=doc.getElementsByClass("like");
			String like = likeElement.get(0).text();
			logger.info("点赞:"+likeElement.get(0).text());
			Elements commentElement=doc.getElementsByClass("comment");
			String comment = commentElement.get(0).text();
			logger.info("评论:"+commentElement.get(0).text());
			Elements starElement=doc.getElementsByClass("star");
			String collect = starElement.get(0).text();
			logger.info("收藏:"+starElement.get(0).text());
		}catch (Exception e) {
			logger.error(e.getMessage(),e);
			int failNum = (Integer)driverMap.get("failNum");
			driverMap.put("failNum", ++failNum);
			throw new IllegalParameterException(ErrorCodeUtil.FAILURE_TO_OBTAIN_INFORMATION);
		}finally {
			// 归还浏览器
			chromeDriverService.returnDriver(driverMap);
		}
		return compositionResult;
	}

在这里插入图片描述

注意:如果页面是相同的,可以直接通过这种方法爬取大量数据,但如果页面结构不同,则需要根据相应的元素位置做出相应的改变

在爬取B站信息的时候,就遇到了兼容性的问题,有些视频是一个UP主进行制作的,而有些是团队协作的,原本up主的位置是只显示一个人的,而现在会显示一堆人
在这里插入图片描述
在这里插入图片描述
这样就需要做一个兼容,当然还会有其他各种各样的不同的页面,之后遇到也会在添加的

			// 发起请求
			String chromeDriver = chromeDriverPage(url, TargetPlatformEnums.BILIBILI,driverMap);

			Document doc = Jsoup.parse(chromeDriver);
			Element userInfoElement = doc.getElementsByAttributeValueContaining("id", "v_upinfo").first();
			// 个人up主
			if(userInfoElement != null) {
				Elements nameElement=doc.getElementsByClass("name");
				name = nameElement.get(0).getElementsByAttributeValueContaining("report-id", "name").text();
				logger.info("昵称:"+nameElement.get(0).getElementsByAttributeValueContaining("report-id", "name").text());
				// 获取up主的主页链接
				homePageUrl = nameElement.get(0).getElementsByAttributeValueContaining("report-id", "name").attr("href");
			}else{
				// 团队up主
				Element memberInfoElement = doc.getElementsByAttributeValueContaining("id", "member-container").first();
				if(memberInfoElement != null) {
					Element userFirstElement = doc.getElementsByClass("name-text").first();
					name = userFirstElement.text();
					logger.info("团队第一up昵称:" + name);
					// 这里是获取up主的主页链接
					homePageUrl = userFirstElement.attr("href");
				}else {
					throw new IllegalParameterException(ErrorCodeUtil.FAILURE_TO_OBTAIN_INFORMATION);
				}		
			}

关于Jsoup的api网上有很多,这里就不再详细介绍了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值