jsoup (网页获取与解析)

1.获取

<dependency>
	<groupId>org.jsoup</groupId>		<artifactId>jsoup</artifactId>
	<version>1.6.3</version>
</dependency>

2.常用类

org.jsoup.nodes.Document

一个Html文档。类的定义为:public class Document extends Element{}


Connection org.jsoup.Jsoup. connect(String url)
指定URL,为下一步拿到HTML网页做准备。

Document org.jsoup.Connection.get() throws IOException
发送get请求,得到Document。

两个示例
Document doc = Jsoup.connect("http://example.com").userAgent("Mozilla").data("name", "jsoup").get(); 
Document doc = Jsoup.connect("http://example.com").cookie("auth", "token").post(); 

String org.jsoup.nodes.Element.text()
获取此元素 与 它所有子元素的文本内容的组合。如给定的html为<p>Hello <b>there</b> now!</p>, p.text() ,那么返回的是"Hello there now!"

Document org.jsoup.Jsoup. parse(String html)
将Html内容解析为一个文档。

Document org.jsoup.Jsoup.parse(File in, String charsetName, String baseUri) 

从本地html文件中解析网页,得到document。

Elements org.jsoup.nodes.Element.select(String cssQuery)
寻找与指定css选择器匹配的元素。

Element org.jsoup.select.Elements.get(int index)

从elements中拿element,下标从0起。

Element org.jsoup.nodes.Element.child(int index)

返回该节点的第i个孩子,下标从0起。

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

public class A {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Document doc = null;
		try {
			doc = Jsoup
					.connect(
							"http://blog.csdn.net/chuchus/article/details/23205283").userAgent("Mozilla")
					.get();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(doc.title());
		String text=doc.text();
		String [] texts=text.split("。|\\.");//以中文句号或英文句号作为分割
		for (String string : texts) {
			System.out.println(string);
		}
	}

	public static boolean isChineseChar(String str) {
		boolean temp = false;
		Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
		Matcher m = p.matcher(str);
		if (m.find()) {
			temp = true;
		}
		return temp;
	}
}
/*
  一般情况下,一个网页的url以xx.html结尾。对于不以xx.xx结尾的网页jsoup也是能够获取的。如www.baidu.com。
在抓取csdn博客时,以地址 http://blog.csdn.net/chuchus/article/details/23205283为例,会出现403禁止访问异常,这是csdn故意的。
解决办法:doc = Jsoup.connect("http://blog.csdn.net/chuchus/article/details/23205283").userAgent("Mozilla").get(); //只需要添加浏览器代理就好了。
 */

/*图论总述 - chuchus - 博客频道 - CSDN.NET
图论总述 - chuchus
        - 博客频道 - CSDN
NET chuchus 目录视图 摘要视图 订阅 博客Markdown编辑器上线啦 ???? 那些年我们追过的Wrox精品红皮计算机图书 ???? PMBOK第五版精讲视频教程 ???? 火星人敏捷开发1001问 图论总述 分类: 图论 2014-04-08 20:31 351人阅读 评论(0) 收藏 举报 图论总述 图的存储 图通常用G=(V,E)表示
V为顶点(vertex)集合,E为边(Edge)的集合
 图的物理存储,有两种方法
 1
邻接矩阵,就是二维数组,较直观,但不能存储重边
 2
邻接表,它是一种顺序与链式兼有的存储
 n个顶点的连通图至少有多少条边? 答:至少要有(n-1)条边
对于简单图而言至多有n*(n-1)/2条边,此时即是完全图
 ?二部图 二部图:存在一种划分方法,将图G的顶点划分为两个集合A和B,使得图中任意一条边的两个邻接顶点分属不同的顶点集
 匹配:二部图中没有公共顶点的边集
边数最多的匹配叫最大匹配
若图中每个顶点都被匹配边邻接,叫完美匹配
 未盖点:不与任何匹配边邻接的顶点
 增广路:从未盖点出发,经非匹配边、匹配边、非匹配边
交替进行,最终以未盖点结尾,此路径叫增广路
在增广路中,把原匹配边与非匹配边对换,则得到的新匹配比原来的多一条边
 匈牙利算法:不断寻找增广路,最终得到最大匹配
 二部图最小覆盖:选择尽量少的点,使得图中每条边至少有一个端点被选中
可以证明,最小覆盖数=最大匹配数
 ?二部图的独立集:该集合中任意两点不相邻接
独立集中顶点个数=总顶点数-最大匹配中边的数目
 一个图G,若其顶点集V可划分为不相交的3个集合V1,V2,V3,使得不同集合的任意两点都邻接,但同一集合内的任意两点都不相邻,则称G为完全三部图
 网络流-概念 容量网络(capacity?network):设G(V,?A)是一个有向网络,在V?中指定了一个顶点,称为源点(记为Vs),以及另一个顶点,称为汇点(记为Vt);对于每一条弧
   
   
    
    ∈A,对应有一个权值c(u,?v)>0,称为弧的容量(capacity)
通常把这样的有向网络G?称为容量网络
从源点到汇点的最大可行流叫最大流
 可行流(Valid?Flow):可行流f(u,v)表示顶点u到顶点v的流量
 前向弧:原图中的弧
 反向弧:对前向弧取反
 增广路(augmenting?path): 设f?是一个容量网络G?中的一个可行流,P?是从Vs?到Vt?的一条路径,若P?满足下列条件: 1)?在P?的所有前向弧
    
    
     
     上,0?≤?f(u,?v)?
     
     上,0?
     
     上的流量按下述规则变化:(始终满足可行流的2?个条件) a)?在前向弧
     
     
      
      上,f(u,?v)?=?f(u,?v)?+x; b)?在后向弧
      
      
       
       上,f(u,?v)?=?f(u,?v)?-x
 x应该等于每条前向弧上的c(u,?v)–f(u,?v)与每条后向弧上的f(u,?v)的最小值
即: x=min{?min{c(u,v)-f(u,v)},?min{f(u,v)}}
 ? 最小割最大流 割——对于图G=(V,E),对顶点集合V进行划分,分为S和T
其中源点s∈S,汇点t∈T,且T=V-S
则称(S,T)为一个割
割的容量定义为capacity(S,T)=∑capacity(u,v),其中u∈S,v∈T
 对于任意s-t流f,和任意s-t割(S,T),都有|f|<=capacity(S,T),因为流f必定跨过割中的若干条边
 当最后一条增广路被找到,下一次BFS找不到新的增广路时,把已标号的点看作集合S(对于其中的任意一点v都有a[v]>0),V-S看作T,此时的割就是最小割
 ? 最小费用最大流 ? 最小生成树 一个图的连通分量是该图的极大连通子图;而一个连通图的生成树是极小连通子图
若给边赋上权值,最小生成树就是权值和最小的生成树,算法有Prime与Kruskal
原图为G=(V,E);生成树G1=(V1,E1)
 Prime: 1
初始化,V1、E1都为空,任选一点v加入V1
 2
求出具有最小权值的边(u,v),u属于V1,v属于V-V1
将v加入V1并将此边加入E1
 3
不断重复步骤2 ,直至V1=V
 复杂度为O(n*n)
 Kruskal: 1
将边按照从小到大的次序排序
置V1=V
 2
顺序遍历每个边edge[i],若加入此边G1有环,则舍弃,否则加入E1
 复杂度为O(边数)
 最短路径 原图为G=(V,E),求s到任意顶点的最短路径
辅助数组dist[i]表示当前从源点s到顶点i的最短路径,辅助数组visited[ ]表示集合A
 1
初始化,置dist[i]=graph[s][i],A中只有s点
 2
找到具有最小值的dist[x],x属于V-A
x加入A,更新所有的dist[ y ],y属于V-A
更新步骤为 if(dist[x]+graph[x][y]
       
       
      
      
     
     
    
    
   
   

3.Jsoup与浏览器

需要注意的是,我们平时上网用的浏览器,除了根据用户输入的url完成通信,还要解析执行javascript代码。
浏览器在发送http请求时,会在头部里面加入很多信息,比如Cookie、userAgent等。所以网站可以根据这些信息来确定这个请求是正常的用户请求还是爬虫机器请求,对于后者,为了减轻网站压力服务器通常不予回应,所以该系统在使用jsoup工具时会附上猎豹浏览器的真实userAgent,降低失败率。
浏览器在拿到网页以后,会执行java script代码,有一些代码会再次让浏览器发送请求,拿到一些内容来展现在网页上。因为jsoup不能执行java script代码,所以会出现它拿到的内容少于真实内容的情形。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值