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才是更适合写爬虫的语言。原因有如下三个方面:
一、任务:爬取用户在Github上的repo信息
通过实例的方式学习爬虫是最好的方法,先定一个小目标:爬取github repo信息。入口URL如下,我们只需要一直点击next按钮就能够遍历到用户的所有repo。
https://github.com/{{username}}?tab=repositories
获取repo之后,可以做什么?
二、爬虫双股剑: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。
整个项目用到的库包括:
试用地址:
https://weiyinfu.cn/githubstatistic/search.html?
案例地址:https://github.com/weiyinfu/GithubStatistic
原文链接:https://zhuanlan.zhihu.com/p/53763115
*请认真填写需求信息,我们会在24小时内与您取得联系。