Java爬虫:用jsoup解析网页

  • Jsoup的官网:https://jsoup.org/
  • 主要功能:
1. 从一个URL,文件或字符串中解析HTML;

2. 使用DOM或CSS选择器来查找、取出数据;

3. 可操作HTML元素、属性、文本;

两种方法解析:

1、来自用户输入,一个文件或一个网站的HTML字符串,你可能需要对它进行解析并取其内容,或校验其格式是否完整:

静态Jsoup.parse(String html) 方法或 Jsoup.parse(String html, String baseUri)

String html = "<html><head><title>First parse</title></head>"
  + "<body><p>Parsed HTML into a doc.</p></body></html>";
Document doc = Jsoup.parse(html);

解析一个body片段可用:Jsoup.parseBodyFragment(String html)方法

String html = "<div><p>Lorem ipsum.</p>";
Document doc = Jsoup.parseBodyFragment(html);
Element body = doc.body();//能取得文档body元素的所有子元素,与 doc.getElementsByTag("body")相同

 2、 从一个URL加载一个Document

  • parse(String html, String baseUri) 方法能够将输入的HTML解析为一个新的文档 (Document),参数 baseUri 是用来将相对 URL 转成绝对URL,并指定从哪个网站获取文档
  • 只要解析的不是空字符串,就能返回一个结构合理的文档,其中包含(至少) 一个head和一个body元素。
  •  一旦拥有了一个Document,你就可以使用Document中适当的方法或它父类 Element和Node中的方法来取得相关数据。
Document doc = Jsoup.connect("http://example.com/").get();
String title = doc.title();

 这个方法只支持Web URLs (httphttps 协议); 假如你需要从一个文件加载,可以使用 parse(File in, String charsetName) 代替。

数据抽取

使用DOM方法来遍历一个文档

从HTML文档中提取数据

File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");

Element content = doc.getElementById("content");
Elements links = content.getElementsByTag("a");
for (Element link : links) {
  String linkHref = link.attr("href");
  String linkText = link.text();
}

Elements这个对象提供了一系列类似于DOM的方法来查找元素,抽取并处理其中的数据:

//查看元素:
    getElementById(String id)
    getElementsByTag(String tag)
    getElementsByClass(String className)
    getElementsByAttribute(String key) (and related methods)
    Element siblings: siblingElements(), firstElementSibling(), lastElementSibling(); nextElementSibling(), previousElementSibling()
    Graph: parent(), children(), child(int index)

//元素数据:
        attr(String key)获取属性attr(String key, String value)设置属性
    attributes()获取所有属性
    id(), className() and classNames()
    text()获取文本内容text(String value) 设置文本内容
    html()获取元素内HTMLhtml(String value)设置元素内的HTML内容
    outerHtml()获取元素外HTML内容
    data()获取数据内容(例如:script和style标签)
    tag() and tagName()

//操作HTML和文本

    append(String html), prepend(String html)
    appendText(String text), prependText(String text)
    appendElement(String tagName), prependElement(String tagName)
    html(String value)

完整实例:

从网页的投票页面中依据票数从高到低爬取参与者信息

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

class Blogger{
	private  String no;
	private String name;
	private String articleNo;
	private int tickerNo;
	
	public String getNo() {
		return no;
	}

	public void setNo(String no) {
		this.no = no;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getArticleNo() {
		return articleNo;
	}

	public void setArticleNo(String articleNo) {
		this.articleNo = articleNo;
	}

	public int getTickerNo() {
		return tickerNo;
	}

	public void setTickerNo(int tickerNo) {
		this.tickerNo = tickerNo;
	}
}

public class Main {
	
	public static Blogger getBlogger(String line){
		Blogger blogger = new Blogger();
        String no = line.substring(0, line.indexOf(" "));
        String name = line.substring(line.indexOf(" ") + 1, line.indexOf(" 原创"));
        String articleNo = line.substring(line.indexOf(":") + 1, line.indexOf("当前") - 1);
        int ticketNo = Integer.valueOf(line.substring(line.indexOf("当前票数:") + 5, line.length()));
        blogger.setNo(no);
        blogger.setName(name);
        blogger.setArticleNo(articleNo);
        blogger.setTickerNo(ticketNo);
        return blogger;
	}

	public static void main(String[] args) throws IOException {		
		Document doc = Jsoup.connect("https://bss.csdn.net/m/topic/blog_star2018").get();
        Elements elements = doc.getElementsByClass("user-info");
        List<Blogger> list = new ArrayList<Blogger>();
        for (Element element : elements) {
            if (!element.text().trim().equals("")) {
                Blogger blogger = new Blogger();
                blogger = getBlogger(element.text());
                list.add(blogger);
            }
        }

        //System.out.println(list.size());
        Collections.sort(list, new Comparator<Blogger>(){
            /*
             * int compare(Person p1, Person p2) 返回一个基本类型的整型,
             * 返回负数表示:p1大于p2,
             * 返回0 表示:p1和p2相等,
             * 返回正数表示:p1小于p2
             */
            public int compare(Blogger p1, Blogger p2) {
                //按照Person的年龄进行升序排列
                if(p1.getTickerNo() < p2.getTickerNo()){
                    return 1;
                }
                if(p1.getTickerNo() == p2.getTickerNo()){
                    return 0;
                }
                return -1;
            }
        });
        
        int i = 1;
        for (Blogger blogger : list) {
            System.out.println(i + " " + blogger.getName() + " " + blogger.getTickerNo());
            i++;
        }
    }
}

 


文档:http://www.open-open.com/jsoup/load-document-from-url.htm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值