需求:采集网站中每一页的联系人信息

一、创建maven工程,添加jsoup和poi的依赖包

        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.16-beta2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.10.2</version>
</dependency>

二、发送http get请求的客户端类

  这里简单使用Jsoup.connect()访问url,也可以用HttpClient创建一个connection,设置长连接Connection:keep-alive,全部页面访问完成后再关闭connection,效率更高

package com.guods.contact;

import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; /**
* 这里简单使用Jsoup.connect()访问url
* 扩展:也可以创建一个connection,设置长连接Connection:keep-alive,全部页面访问完成后再关闭connection,效率更高
* @author guods
*
*/
public class MyHttpClient { public Document get(String url){
try {
return Jsoup.connect(url)
.get();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

三、excel存取类,解析页面时提取联系人信息,存入excel文档。

package com.guods.contact;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException; import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; /**
* excel
*
* @author guods
* 扩展:excel读写数据可以模仿集合实现增删改查等方法,方便调用
* 如,把本类实现Iterable接口,再写个实现Iterator的内部类,就可以和集合一样迭代excel每一行的数据,这里用不到暂且不写
*/
public class Excel { private String filePath;
private XSSFWorkbook workbook;
private XSSFSheet sheet;
private XSSFCellStyle titleStyle, commonStyle;
private int rowCount; //总记录数 /**
*
* @param file 文件名
* @param sheetName sheet名
* @param columnNames 第一行内容(标题)
*/
public Excel(String file, String sheetName, String[] columnNames) {
super();
this.filePath = file;
newSheet(sheetName, columnNames);
}
/**
* 初始化excel表格,生成标题(第一行数据)
* @param sheetName sheet标签名
* @param columnNames 列名
*/
private void newSheet(String sheetName, String[] columnNames){
workbook = new XSSFWorkbook();
//设置标题字体
XSSFFont titleFont = workbook.createFont();
titleFont.setBold(true);
titleFont.setFontName("黑体");
titleStyle = workbook.createCellStyle();
titleStyle.setFont(titleFont);
//设置正文字体
XSSFFont commonFont = workbook.createFont();
commonFont.setBold(false);
commonFont.setFontName("宋体");
commonStyle = workbook.createCellStyle();
commonStyle.setFont(commonFont);
//创建sheet
sheet = workbook.createSheet(sheetName);
//设置初始记录行数
rowCount = 0;
//创建标题行
insertRow(columnNames, titleStyle);
}
public void insertRow(String[] rowData){
insertRow(rowData, commonStyle);
}
/**
* 插入一行数据
* @param rowData 数据内容
* @param style 字体风格
*/
public void insertRow(String[] rowData, XSSFCellStyle style){
XSSFRow row = sheet.createRow(rowCount);
for (int i = 0; i < rowData.length; i++) {
XSSFCell cell = row.createCell(i);
sheet.setColumnWidth(i, 5000);
cell.setCellStyle(style);
cell.setCellValue(rowData[i]);
}
rowCount++;
}
/**
* excel文件存储到磁盘
*/
public void saveFile(){
try {
File file = new File(filePath);
if (file.exists()) {
file.delete();
}
file.createNewFile();
FileOutputStream fileOutputStream = new FileOutputStream(file);
workbook.write(fileOutputStream);
} catch (FileNotFoundException e) {
System.out.println(filePath + "保存文件错误:" + e.getMessage());
} catch (IOException e) {
System.out.println(filePath + "保存文件错误:" + e.getMessage());
}
}
/**
* 返回excel总行数
* @return
*/
public int size() {
return rowCount;
} }

四、页面解析类。解析MyHttpClient获取的页面,把有效数据存到excel。

  分析html页面的标签结构,根据标签结构写页面的解析方法,取联系人信息对应的元素。

  当然,如果采集的量比较多的话也可以把数据存到本地数据库作为自己的联系人库。方便起见先存到excel。

package com.guods.contact;

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; public class PageParser { /**
* 解析列表页面,根据页面的标签结构提取联系人信息
* VIP会员在列表中没有展示联系人信息,需要获取VIP会员的公司链接,抓取公司页面,在公司页面获取联系人信息
* @param document 获取的http页面
* @param excel 提取客户信息存到excel
*/
public void parseListPage(Document document, Excel excel){
if (document == null) {
return;
}
Elements tbodys = document.getElementsByTag("tbody");
if (tbodys == null || tbodys.size() == 0) {
return;
}
Element tbody = tbodys.get(0);
Elements trs = tbody.getElementsByTag("tr");
for (int i = 0; i < trs.size(); i++) {
//解析列表页面,获取列表信息
Elements tdivs = trs.get(i).getElementsByClass("tdiv");
if (tdivs.size() == 0) {
continue;
}
//取描述字段
Element tdiv = trs.get(i).getElementsByClass("tdiv").get(0);
String desc = tdiv.text();
//取标题字段
Element a = tdiv.getElementsByTag("a").get(0);
String title = a.text();
//取客户名字段
Element seller = tdiv.getElementsByClass("seller").get(0);
String sellerName = seller.text();
//取联系电话字段
Element yuyueVertop = trs.get(i).getElementsByClass("yuyue_vertop").get(0);
String contact = yuyueVertop.attr("data-j4fe");
//excel插入记录,联系电话没有的数据不记录
if (contact != null && contact.trim() != "") {
String[] rowData = {title, desc, sellerName, contact};
excel.insertRow(rowData);
}
}
} }

五、采集数据

  浏览器上复制页面的url,以url的页码数为界前后分开,把preUrl + 页码数 + postUrl拼接成完整的url,循环访问每个页面。

package com.guods.contact;

import org.jsoup.nodes.Document;

public class Main
{
public static void main( String[] args )
{
//采集1-10页的数据
startWork(1, 10);
} public static void startWork(int fromPage, int endPage){
StringBuffer urlBuffer = new StringBuffer();
String preUrl = "http://hz.58.com/shigongjl/pn";
String postUrl = "/?PGTID=0d306d36-0004-f163-ca53-0cdfddb146d0&ClickID=2";
MyHttpClient myHttpClient = new MyHttpClient();
Document document;
//创建excel文档
String[] columnNames = {"标题", "描述", "名字", "联系方式"};
Excel excel = new Excel("d:\\contact.xlsx", "contact", columnNames);
//创建一个解析器
PageParser parser = new PageParser();
//修改页码拼接请求,一次循环处理一个页面
for (int i = fromPage; i <= endPage; i++) {
//清空urlBuffer,重新组装url
if (urlBuffer.capacity() > 0) {
urlBuffer.delete(0, urlBuffer.capacity());
}
urlBuffer.append(preUrl).append(i).append(postUrl);
//访问url,获取document
document = myHttpClient.get(urlBuffer.toString());
//解析document
parser.parseListPage(document, excel);
System.out.println("第" + i + "页列表采集完成。。。");
}
//数据存档
excel.saveFile();
System.out.println("采集完成,列表总共:" + excel.size() + "条");
}
}

六、运行结果:

第1页列表采集完成。。。
第2页列表采集完成。。。
第3页列表采集完成。。。
第4页列表采集完成。。。
第5页列表采集完成。。。
第6页列表采集完成。。。
第7页列表采集完成。。。
第8页列表采集完成。。。
第9页列表采集完成。。。
第10页列表采集完成。。。
采集完成,列表总共:317条

第一次发博,亲测可用。

源码下载:https://github.com/dongsheng824/guods.git

Jsoup抓取、解析网页和poi存取excel综合案例——采集网站的联系人信息的更多相关文章

  1. 使用java开源工具httpClient及jsoup抓取解析网页数据

    今天做项目的时候遇到这样一个需求,需要在网页上展示今日黄历信息,数据格式如下 公历时间:2016年04月11日 星期一 农历时间:猴年三月初五 天干地支:丙申年 壬辰月 癸亥日 宜:求子 祈福 开光 ...

  2. jsoup抓取网页+具体解说

    jsoup抓取网页+具体解说 Java 程序在解析 HTML 文档时,相信大家都接触过 htmlparser 这个开源项目.我以前在 IBM DW 上发表过两篇关于 htmlparser 的文章.各自 ...

  3. Jsoup抓取网页数据完成一个简易的Android新闻APP

    前言:作为一个篮球迷,每天必刷NBA新闻.用了那么多新闻APP,就想自己能不能也做个简易的新闻APP.于是便使用Jsoup抓取了虎扑NBA新闻的数据,完成了一个简易的新闻APP.虽然没什么技术含量,但 ...

  4. HttpClients+Jsoup抓取笔趣阁小说,并保存到本地TXT文件

    前言 首先先介绍一下Jsoup:(摘自官网) jsoup is a Java library for working with real-world HTML. It provides a very ...

  5. 抓取https网页时,报错sun.security.validator.ValidatorException: PKIX path building failed 解决办法

    抓取https网页时,报错sun.security.validator.ValidatorException: PKIX path building failed 解决办法 原因是https证书问题, ...

  6. python网络爬虫抓取动态网页并将数据存入数据库MySQL

    简述以下的代码是使用python实现的网络爬虫,抓取动态网页 http://hb.qq.com/baoliao/ .此网页中的最新.精华下面的内容是由JavaScript动态生成的.审查网页元素与网页 ...

  7. 【转】详解抓取网站,模拟登陆,抓取动态网页的原理和实现(Python,C#等)

    转自:http://www.crifan.com/files/doc/docbook/web_scrape_emulate_login/release/html/web_scrape_emulate_ ...

  8. jsoup抓取网页内容

    java项目有时候我们需要别人网页上的数据,怎么办?我们可以借助第三方架包jsou来实现,jsoup的中文文档,那怎么具体的实现呢?那就跟我一步一步来吧 最先肯定是要准备好这个第三方架包啦,下载地址, ...

  9. selenium抓取动态网页数据

    1.selenium抓取动态网页数据基础介绍 1.1 什么是AJAX AJAX(Asynchronouse JavaScript And XML:异步JavaScript和XML)通过在后台与服务器进 ...

随机推荐

  1. swift -- 单例

    方式一: (类似OC) class SingletonDispatch{ class var shareInstance : SingletonDispatch { //结构体 struct Stat ...

  2. 字符编码的种类:ASCII、GB2312、GBK、GB18030、Unicode、UTF-8、UTF-16、Base64

    ASCII码ASCII:https://zh.wikipedia.org/wiki/ASCIIASCII(American Standard Code for Information Intercha ...

  3. kali linux 忘记root密码重置办法

    有段时间没用kali linux 的,加上最近装的系统有比较多,系统root的密码忘掉了,真是麻烦啊.之前在网上看到的一些方法尝试后没进的去,可能是因为不同的linux 不一样吧. 如果因为忘记密码而 ...

  4. SQL Server中的Merge关键字 更新表数据

    简介 Merge关键字是一个神奇的DML关键字.它在SQL Server 2008被引入,它能将Insert,Update,Delete简单的并为一句.MSDN对于Merge的解释非常的短小精悍:”根 ...

  5. windows phone 8.1开发:(消息弹出框)强大的ContentDialog

    原文出自:http://www.bcmeng.com/contentdialog/ 在应用开发中我们必不可少的会使用到消息框,windows phone8中的messagebox在windows ph ...

  6. SQLSERVER 切换数据库为单用户和多用户模式

    有时候数据库在占用时,想做一些操作,无法操作.可以尝试将数据库切换为单用户模式来操作.操作完之后再切换回多用户模式. 命令如下: alter database 数据库名 set Single_user ...

  7. BootStrap入门教程 (四)

    本文转自 http://www.cnblogs.com/ventlam/archive/2012/06/17/2536728.html 上讲回顾:Bootstrap组件丰富同时具有良好可扩展性,能够很 ...

  8. javaWEB与Session

    HttpSession(*****)1. HttpSession概述  * HttpSession是由JavaWeb提供的,用来会话跟踪的类.session是服务器端对象,保存在服务器端!!!  * ...

  9. iOS面试必看经典试题分析

    > **不用临时变量怎么实现两个数据的交换?** 方式一:加减法的运算方式求解new_b = a - b + b = a;new_a = a + b - a = b;一个简单的运算方式,最重要的 ...

  10. SQLServer数据库中开启CDC导致“事务日志空间被占满,原因为REPLICATION”的原因分析和解决办法

    本文出处:http://www.cnblogs.com/wy123/p/6646143.html SQLServer中开启CDC之后,在某些情况下会导致事务日志空间被占满的现象为:在执行增删改语句(产 ...