整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

java爬虫-网页解析Jsoup

java爬虫-网页解析Jsoup

soup是一款Java的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

在爬虫采集网页领域主要作用是用HttpClient获取到网页后,使用Jsoup提取网页中需要的信息,Jsoup支持类似Jquery、CSS选择器,来获取需要的数据,使用非常方便。

下面结合代码简单展示如何使用Jsoup获取需要的页面数据。

public class JsoupHello {

public static void main(String[] args) throws Exception{

CloseableHttpClient httpclient=HttpClients.createDefault(); // 创建httpclient实例

HttpGet httpget=new HttpGet("http://www.cnblogs.com/"); // 创建httpget实例

CloseableHttpResponse response=httpclient.execute(httpget); // 执行get请求

HttpEntity entity=response.getEntity(); // 获取返回实体

String content=EntityUtils.toString(entity, "utf-8");

response.close(); // 关闭流和释放系统资源

Document doc=Jsoup.parse(content); // 解析网页 得到文档对象

Elements elements=doc.getElementsByTag("title"); // 获取tag是title的所有DOM元素

Element element=elements.get(0); // 获取第1个元素

String title=element.text(); // 返回元素的文本

System.out.println("网页标题是:"+title);

Element element2=doc.getElementById("site_nav_top"); // 获取id=site_nav_top的DOM元素

String navTop=element2.text(); // 返回元素的文本

System.out.println("口号:"+navTop);

}

}

1、使用httpClient 获取网页2、使用jsoup parse解析网页,并根据丰富的getElement方法按照不同的属性获取元素值

二、常用查找dom元素方法

1、根据标签名(tagName)查找dom

Elements elements=doc.getElementsByTag("title"); //获取tag是title的所有dom元素

Element element=elements.get(0); //获取第一个

System.out.println(element.text());//输出元素txt值

2、根据元素Id查找

3、根据class 名查找

4、根据attribute属性名查找

5、根据attribute和attributeValue共同查找

三、使用Jsoup选择器查找dom元素1、class类选择器使用

//class 使用. 中间空格

Elements eleLinks=doc.select(".post_item .post_item_body h3 a");

for(Element el:eleLinks)

{

System.out.println(el.text());

}

测试 JavaScript 框架库 - jQuery

引用 jQuery

如需测试 JavaScript 库,您需要在网页中引用它。

为了引用某个库,请使用 <script> 标签,其 src 属性设置为库的 URL:

引用 jQuery

<!DOCTYPE html>

<html>

<head>

<script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js">

</script>

</head>

<body>

</body>

</html>

jQuery 描述

主要的 jQuery 函数是 $() 函数(jQuery 函数)。如果您向该函数传递 DOM 对象,它会返回 jQuery 对象,带有向其添加的 jQuery 功能。

jQuery 允许您通过 CSS 选择器来选取元素。

在 JavaScript 中,您可以分配一个函数以处理窗口加载事件:

JavaScript 方式:

function myFunction()

{

var obj=document.getElementById("h01");

obj.innerHTML="Hello jQuery";

}

onload=myFunction;

等价的 jQuery 是不同的:

jQuery 方式:

function myFunction()

{

$("#h01").html("Hello jQuery");

}

$(document).ready(myFunction);

上面代码的最后一行,HTML DOM 文档对象被传递到 jQuery :$(document)。

当您向 jQuery 传递 DOM 对象时,jQuery 会返回以 HTML DOM 对象包装的 jQuery 对象。

jQuery 函数会返回新的 jQuery 对象,其中的 ready() 是一个方法。

由于在 JavaScript 中函数就是变量,因此可以把 myFunction 作为变量传递给 jQuery 的 ready 方法。

jQuery 返回 jQuery 对象,与已传递的 DOM 对象不同。jQuery 对象拥有的属性和方法,与 DOM 对象的不同。您不能在 jQuery 对象上使用 HTML DOM 的属性和方法。

测试 jQuery

请试一下下面这个例子:

实例

<!DOCTYPE html>

<html>

<head>

<script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js">

</script>

<script>

function myFunction()

{

$("#h01").html("Hello jQuery")

}

$(document).ready(myFunction);

</script>

</head>

<body>

<h1 id="h01"></h1>

</body>

</html>

请再试一下这个例子:

实例

<!DOCTYPE html>

<html>

<head>

<script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js">

</script>

<script>

function myFunction()

{

$("#h01").attr("style","color:red").html("Hello jQuery")

}

$(document).ready(myFunction);

</script>

</head>

<body>

<h1 id="h01"></h1>

</body>

</html>

正如您在上面的例子中看到的,jQuery 允许链接(链式语法)。

链接(Chaining)是一种在同一对象上执行多个任务的便捷方法。

如您还有不明白的可以在下面与我留言或是与我探讨QQ群308855039,我们一起飞!

比Python,JavaScript才是更适合写爬虫的语言。原因有如下三个方面:

  • JavaScript异步IO机制适用于爬虫这种IO密集型任务。JavaScript中的回调非常自然,使用异步网络请求能够充分利用CPU。
  • JavaScript中的jQuery毫无疑问是最强悍的HTML解析工具,使用JavaScript写爬虫能够减少学习负担和记忆负担。虽然Python中有PyQuery,但终究还是比不上jQuery自然。
  • 爬取结果多为JSON,JavaScript是最适合处理JSON的语言。

一、任务:爬取用户在Github上的repo信息

通过实例的方式学习爬虫是最好的方法,先定一个小目标:爬取github repo信息。入口URL如下,我们只需要一直点击next按钮就能够遍历到用户的所有repo。

https://github.com/{{username}}?tab=repositories

获取repo之后,可以做什么?

  • 统计用户最常使用的语言,统计用户语言使用分布情况统计用户所获取的star数,fork数

二、爬虫双股剑:axios和jQuery

axios是JavaScript中很常用的异步网络请求库,相比jQuery,它更轻量、更专业。既能够用于浏览器端,也可以用于Node。它的语法风格是promise形式的。在本任务中,只需要了解如下用法就足够了:

axios.get(url).then((resp)=> {
 请求成功,处理resp.data中的html数据
}).catch((err)=> {
 请求失败,错误处理
})

请求之后需要处理回复结果,处理回复结果的库当然是用jQuery。实际上,我们有更好的选择:cheerio。

在node下,使用jQuery,需要使用jsdom库模拟一个window对象,这种方法效率较低,四个字形容就是:笨重稳妥。

如下代码使用jQuery解析haha.html文件

fs=require("fs")
jquery=require('jquery')
jsdom=require('jsdom') //fs.readFileSync()返回结果是一个buffer,相当于byte[] 
html=fs.readFileSync('haha.html').toString('utf8') 
dom=new jsdom.JSDOM(html) 
$=jquery(dom.window) console.log($('h1'))

cheerio只实现了jQuery中的DOM部分,相当于jQuery的一个子集。cheerio的语法和jQuery完全一致,在使用cheerio时,几乎感觉不到它和jQuery的差异。在解析HTML方面,毫无疑问,cheerio是更好的选择。如下代码使用cheerio解析haha.html文件。

cheerio=require('cheerio')
html=require('fs').readFileSync("haha.html").toString('utf8')
$=cheerio.load(html)
console.log($('h1'))

只需20余行,便可实现简单的github爬虫,此爬虫只爬取了一页repo列表。

var axios=require("axios")
var cheerio=require("cheerio")
axios.get("https://github.com/weiyinfu?tab=repositories").then(resp=> {
 var $=cheerio.load(resp.data)
 var lis=$("#user-repositories-list li")
 var repos=[]
 for (var i=0; i < lis.length; i++) {
 var li=lis.eq(i)
 var repo={
 repoName: li.find("h3").text().trim(),
 repoUrl: li.find("h3 a").attr("href").trim(),
 repoDesc: li.find("p").text().trim(),
 language: li.find("[itemprop=programmingLanguage]").text().trim(),
 star: li.find(".muted-link.mr-3").eq(0).text().trim(),
 fork: li.find(".muted-link.mr-3").eq(1).text().trim(),
 forkedFrom: li.find(".f6.text-gray.mb-1 a").text().trim()
 }
 repos.push(repo)
 }
 console.log(repos)
})

三、更丰富的功能

爬虫不是目的,而是达成目的的一种手段。获取数据也不是目的,从数据中提取统计信息并呈现给人才是最终目的。

在github爬虫的基础上,我们可以扩展出更加丰富的功能:使用echarts等图表展示结果。

要想让更多人使用此爬虫工具获取自己的github统计信息,就需要将做成一个网站的形式,通过搜索页面输入用户名,启动爬虫立即爬取github信息,然后使用echarts进行统计展示。网站肯定也要用js作为后端,这样才能和js爬虫无缝衔接,不然还要考虑跨语言调用。js后端有两大web框架express和koa,二者API非常相似,并无优劣之分,但express更加流行。

如上设计有一处用户体验不佳的地方:当启动爬虫爬取github信息时,用户可能需要等待好几秒,这个过程不能让用户干等着。一种解决思路是:让用户看到爬虫爬取的进度或者爬取过程。可以通过websocket向用户推送爬取过程信息并在前端进行展示。展示时,使用类似控制台的界面进行展示。

如何存储爬取到的数据呢?使用MongoDB或者文件都可以,最好实现两种存储方式,让系统的存储方式变得可配置。使用MongoDB时,用到js中的连接池框架generic-pool。

整个项目用到的库包括:

  • express:后端框架
  • cheerio+axios:爬虫
  • ws:websocket展示爬取过程
  • webpack:打包工具
  • less:样式语言
  • echarts:图表展示
  • vue:模板渲染
  • jquery:DOM操作
  • mongodb:存储数据
  • generic-pool:数据库连接池

试用地址:

https://weiyinfu.cn/githubstatistic/search.html?

案例地址:https://github.com/weiyinfu/GithubStatistic

原文链接:https://zhuanlan.zhihu.com/p/53763115