欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

网络爬虫原理详解及案例实现(二)

程序员文章站 2022-03-04 08:41:20
...

网络爬虫之Java实现


今日份:因为热爱,所以甘愿付出

回顾及前言

上一篇博客中,谈及到一些爬虫时需要的HTTP相关知识,在了解清楚HTTP客户端怎么发送请求,请求的具体内容格式以及WEB服务器端接收到请求后的响应,响应的内容格式后,就可以轻松地利用编程语言去抓取网页了。但是我们的目的并不是到此为止,或者说我们只是走好了爬虫的第一步。下面让我们先看一下常用的提取网页信息的代码:

ublic class Demo1 {
	public static void main(String[] args) throws Exception{
	//创建httpclient对象,即创建了一个浏览器
	HttpClient hClient=new DefaultHttpClient();
	
	//设置响应时间,传输源码时间,以及设置代理服务器
	/*hClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10000)
		   .setParameter(CoreConnectionPNames.SO_TIMEOUT, 10000)
		   .setParameter(ConnRouteParams.DEFAULT_PROXY,new HttpHost("140.143.246.163",8080));*/
	//创建一个get类型的http请求对象
	HttpGet hget=new HttpGet("https://www.jb51.net/");
	//添加请求头信息
	hget.addHeader("User-Agent", "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Mobile Safari/537.36");
	hget.addHeader("Connection","keep-alive");
	
	//向网站发送请求获取网页源码
	String content="";
	try{
	//浏览器发送请求,获得服务器的响应
	HttpResponse responce=hClient.execute(hget);
	//获得响应主体的字符串形式
	content=EntityUtils.toString(responce.getEntity(),"gb2312");
	}catch(Exception e){
		e.printStackTrace();
	}

	hget.releaseConnection();

	//1.使用正则表达式
	ArrayList<String> results = new ArrayList<String>();
	//Pattern p=Pattern.compile("href.+?title(.+?)>");//正则表达式捕获组()
	Pattern p=Pattern.compile("li><a href=\".+?\">(.+?)<");//正则表达式捕获组()
	Matcher m=p.matcher(content);
	boolean isFind=m.find();
	while(isFind){
		 results.add(m.group(1));
		
		isFind=m.find();
	}
	System.out.println(results);
	}

	//2.使用JSoup解析网页源码
Document doc=Jsoup.parse(content);
	String urlString="";
	Elements elements=doc.select("div.m-nav a");
	//System.out.println(element.text());
	for(Element e:elements){
		urlString=e.text()+":"+e.attr("href");
		System.out.println(urlString);
	}	
	
}

刚看到这样一段代码的时候,首先让人感到困难的就是这样的一行字符串,毫无头绪。

"li><a href=\".+?\">(.+?)<"

那么它究竟是什么呢?为什么要这样去写?那么现在就来学习一下有关它的知识,让我们去征服它吧。

1. 正则表达式

  • 正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。

  • Regular Expression的“Regular”一般被译为“正则”、“正规”、“常规”。此处的“Regular”即是“规则”、“规律”的意思,Regular Expression即“描述某种规则的表达式”之意。

一、利用正则表达式匹配字符串
在项目里我们导入了关于正则表达式的包
import java.util.regex.Matcher;
import java.util.regex.Pattern;

···用正则表达式来判断(在Java里正则对应的类是pattern,而不是Regex,相关方法都在pattern类里面。)

         * 1.compile(String regex)    将给定的正则表达式编译到模式中。
         * 2.matcher(CharSequence input)    创建匹配给定输入与此模式的匹配器。
         * 3.matches()    尝试将整个输入序列与模式相匹配。
         *4. matches(String regex, CharSequence input) 编译给定的正则表达式,并尝试匹配给定的输入。 

			·Pattern.matches(regex, input);//适用于模式被多次使用
			·Pattern.compile(regex).matcher(input).matches();
···用字符串来判断
		str.matches("Regex");

二、利用正则表达式切割字符串
		public String[] split(String regex)
		将此字符串拆分为给定的regular expression的匹配。 
		该方法的工作原理是通过使用给定表达式和限制参数为零调用双参数split方法。 因此,尾随的空字符串不会包含在结果数组中。

三、利用正则表达式替换字符串
public String replaceAll(String regex,String replacement)
		用给定的替换替换与给定的regular expression匹配的此字符串的每个子字符串。 
		这种形式产生与表达式Pattern.compile(regex).matcher(str).replaceAll(repl) 完全相同的结果 

关于正则表达式的匹配规则详见我的另一篇博客正则表达式的相关应用.

2.JSoup

JSoup的官方解释:
jsoup: Java HTML Parser
jsoup is a Java library for working with real-world HTML.
It provides a very convenient API for extracting and manipulating data, using the best of DOM, CSS, and jquery-like methods.

jsoup implements the WHATWG HTML5 specification, and parses HTML to the same DOM as modern browsers do.

HTML DOM 定义了访问和操作 HTML 文档的标准。
1. “W3C 文档对象模型 (DOM) 是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。”

2. W3C DOM 标准被分为 3 个不同的部分:

  • 核心 DOM - 针对任何结构化文档的标准模型
  • XML DOM - 针对 XML 文档的标准模型
  • HTML DOM - 针对 HTML 文档的标准模型

JSoup主要用于以下几个方面:

  • 从URL,文件或字符串中获取和解析 HTML
  • 使用DOM遍历或CSS选择器查找和提取数据
  • 操纵 HTML元素,属性和文本
  • 清除用户提交的内容以防止安全白名单,以防止XSS攻击
  • 输出整洁的HTML

从JSoup的解释中可以知道JSoup主要用于解析HTML文档,利用DOM相关方法及CSS选择器等提取有用信息

  • 1、通过其他相关方法获取网页HTML源代码,再经JSoup解析文档,可以看到其确实简单易用
Document doc=Jsoup.parse(content);
	String urlString="";
	Elements elements=doc.select("div.m-nav a");
	//System.out.println(element.text());
	for(Element e:elements){
		urlString=e.text()+":"+e.attr("href");
		System.out.println(urlString);
	}	

2、直接通过JSoup来获取网页源代码并解析

Document doc=Jsoup.connect(url).userAgent("Mozilla").data("name", "jsoup").get();
	String urlString="";
	Elements elements=doc.select("div.m-nav a");
	//System.out.println(element.text());
	for(Element e:elements){
		urlString=e.text()+":"+e.attr("href");
		System.out.println(urlString);
	}	

不清楚JSoup相关的类的方法的用法,详见JSoup官方API.

相关标签: 爬虫 Java