开发爬虫时所用到的页面元素分析利器Jsoup

jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
使用jsoup 抽取html 页面的数据。如果你已经知道一个html文档并了解文档的结构。将html 文档解析成一个Document 对象,再利用操作DOM的方法来进行操作。Java 中爬虫比较知名的就WebCollector当我们抓取到大量数据后,怎么从繁杂的页面代码中获取自己想要的数据时候,这个时候就必须熟悉Jsoup 页面元素的分析利器。直接上代码

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();
}

从上面的代码我们不难看出,爬取的结果为一个Element 对象。当然Element 对象也为我们封装了一系列类似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)
使用选择器语法来查找元素:
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");
Elements links = doc.select("a[href]"); //带有href属性的a元素
Elements pngs = doc.select("img[src$=.png]");//扩展名为.png的图片
Element masthead = doc.select("div.masthead").first();//class等于masthead的div标签
Elements resultLinks = doc.select("h3.r > a"); //在h3元素之后的a元素
从上面的代码我们不难看出,select方法返回的是一个Element集合,提供一组方法来处理和抽取其中的结果。
Selector选择器的介绍:
tagname: 通过标签查找元素,比如:a
ns|tag: 通过标签在命名空间查找元素,比如:可以用 
  fb|name 语法来查找 <fb:name> 元素
#id: 通过ID查找元素,比如:#logo
.class: 通过class名称查找元素,比如:.masthead
[attribute]: 利用属性查找元素,比如:[href]
[^attr]: 利用属性名前缀来查找元素,比如:可以用[^data-] 来查找带有HTML5 Dataset属性的元素 
[attr=value]: 利用属性值来查找元素,比如:[width=500]
[attr^=value], [attr$=value], 
  [attr*=value]: 利用匹配属性值开头、结尾或包含属性值来查找元素,比如:[href*=/path/]
[attr~=regex]: 利用属性值匹配正则表达式来查找元素,比如: img[src~=(?i)\.(png|jpe?g)]
*: 这个符号将匹配所有元素
Selector选择器组合使用:
el#id: 元素+ID,比如: div#logo 
el.class: 元素+class,比如: 
  div.masthead
el[attr]:  元素+class,比如: 
  a[href]  
任意组合,比如:a[href].highlight
ancestor child: 查找某个元素下子元素,比如:可以用.body p 查找在"body"元素下的所有 p元素
parent > child: 查找某个父元素下的直接子元素,比如:可以用div.content > p 查找 p 元素,也可以用body > * 查找body标签下所有直接子元素
siblingA + siblingB: 查找在A元素之前第一个同级元素B,比如:div.head + div  
siblingA ~ siblingX: 查找A元素之前的同级X元素,比如:h1 ~ p
el, el, el:多个选择器组合,查找匹配任一选择器的唯一元素,例如:div.masthead, 
div.logo

更多Jsoup 的方法。可以参见jsoup官网。

另外在说明下,使用WebCollector 爬取数据后持久化本地的时候,WebCollector爬虫并不像scrapy那样,提供一个pipeline这样的数据持久化接口。
用户通过自定义WebCollector中BreadthCrawler中的visit方法,来定义对每个页面的操作。同样,数据的持久化,也是在这里让用户自定义的。持久化的操作:新建一个jdbc的持久化工具类

import java.util.HashMap;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.jdbc.core.JdbcTemplate;



/*
 * Author liyaqiang
 * 持久化数据的帮助类 
 */
public class JDBCHelperUtil {


     public static HashMap templateMap = new HashMap();

     public static JdbcTemplate createOracleemplate(String templateName, 
                String url, String username, String password, 
                int initialSize, int maxActive) {

            BasicDataSource dataSource = new BasicDataSource();
            dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
            dataSource.setUrl(url);
            dataSource.setUsername(username);
            dataSource.setPassword(password);
            dataSource.setInitialSize(initialSize);
            dataSource.setMaxActive(maxActive);
            JdbcTemplate template = new JdbcTemplate(dataSource);
            templateMap.put(templateName, template);
            return template;
        }

     public static JdbcTemplate getJdbcTemplate(String templateName){
            return templateMap.get(templateName);
        }



}

然后在Visit 方法中操作jdbc

@Override
    public void visit(Page page, CrawlDatums arg1) {
                JdbcTemplate jdbcTemplate = null;
                try {
                    jdbcTemplate = JDBCHelperUtil.createOracleemplate("oracle",
                            "jdbc:oracle:thin:@x.x.x.x:1521:ORCL11G",
                            "xx", "xx", 10, 30);
                    /*创建数据表
                    jdbcTemplate.execute("CREATE TABLE  credit_zz_message ("
                            + "id varchar2(32),"
                            + "title varchar2(2550),url varchar2(255),sub_time varchar2(16),"
                            + "message_type varchar2(1),"
                            + "PRIMARY KEY (id)"
                            + ")");
                    System.out.println("成功创建数据表 credit_zz_message");*/
                } catch (Exception e) {
                    jdbcTemplate = null;
                    System.out.println("Oracle未开启或JDBCHelperUtil.createOracleemplate中参数配置不正确!");
                }
                Iterator listring =new ArrayList().iterator();
                String message_type="";
                if("xydt".equals(page.getUrl().substring(27, 31))){
                       message_type="1";
                       listring =page.select("ul[class=ul_min]>li").iterator();
                }else if ("fgzc".equals(page.getUrl().substring(27, 31))) {
                       message_type="2";
                       listring =page.select("ul[class=ul_min]>li").iterator();
                }else {
                    message_type="3";
                    listring =page.select("div[class=dom-box selected-dom clear]>ul>li").iterator();
                }
                while (listring.hasNext()) {
                    Element s=listring.next();
                    String id=UUIDGernerator.getUUID();
                    String title =s.getElementsByTag("a").attr("title");
                    String url =s.getElementsByTag("a").attr("href");
                    String sub_time=s.getElementsByClass("dom-time").text();
                    int updates =jdbcTemplate.update("INSERT INTO CREDIT_ZZ_MESSAGE VALUES('"  
                               +id + "', '"  
                               + title + "', '"  
                               + url + "', '"  
                               + sub_time + "',"
                               + message_type+")");  
                        if(updates==1){
                            System.out.println("CREDIT_ZZ_MESSAGE表插入成功");
                        }
                    } 
                }

这样就可以将爬取的数据持久化到相应的数据库中

你可能感兴趣的:(JAVA)