Jsoup抓取、解析网页和poi存取excel综合案例——采集网站的联系人信息
需求:采集网站中每一页的联系人信息
一、创建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综合案例——采集网站的联系人信息的更多相关文章
- 使用java开源工具httpClient及jsoup抓取解析网页数据
今天做项目的时候遇到这样一个需求,需要在网页上展示今日黄历信息,数据格式如下 公历时间:2016年04月11日 星期一 农历时间:猴年三月初五 天干地支:丙申年 壬辰月 癸亥日 宜:求子 祈福 开光 ...
- jsoup抓取网页+具体解说
jsoup抓取网页+具体解说 Java 程序在解析 HTML 文档时,相信大家都接触过 htmlparser 这个开源项目.我以前在 IBM DW 上发表过两篇关于 htmlparser 的文章.各自 ...
- Jsoup抓取网页数据完成一个简易的Android新闻APP
前言:作为一个篮球迷,每天必刷NBA新闻.用了那么多新闻APP,就想自己能不能也做个简易的新闻APP.于是便使用Jsoup抓取了虎扑NBA新闻的数据,完成了一个简易的新闻APP.虽然没什么技术含量,但 ...
- HttpClients+Jsoup抓取笔趣阁小说,并保存到本地TXT文件
前言 首先先介绍一下Jsoup:(摘自官网) jsoup is a Java library for working with real-world HTML. It provides a very ...
- 抓取https网页时,报错sun.security.validator.ValidatorException: PKIX path building failed 解决办法
抓取https网页时,报错sun.security.validator.ValidatorException: PKIX path building failed 解决办法 原因是https证书问题, ...
- python网络爬虫抓取动态网页并将数据存入数据库MySQL
简述以下的代码是使用python实现的网络爬虫,抓取动态网页 http://hb.qq.com/baoliao/ .此网页中的最新.精华下面的内容是由JavaScript动态生成的.审查网页元素与网页 ...
- 【转】详解抓取网站,模拟登陆,抓取动态网页的原理和实现(Python,C#等)
转自:http://www.crifan.com/files/doc/docbook/web_scrape_emulate_login/release/html/web_scrape_emulate_ ...
- jsoup抓取网页内容
java项目有时候我们需要别人网页上的数据,怎么办?我们可以借助第三方架包jsou来实现,jsoup的中文文档,那怎么具体的实现呢?那就跟我一步一步来吧 最先肯定是要准备好这个第三方架包啦,下载地址, ...
- selenium抓取动态网页数据
1.selenium抓取动态网页数据基础介绍 1.1 什么是AJAX AJAX(Asynchronouse JavaScript And XML:异步JavaScript和XML)通过在后台与服务器进 ...
随机推荐
- 自定义cell设置现价,原价(加横线)
原价,现价分别是连个label.这两个label不能直接限制死他们的宽度,因为他们的宽度不确定,而由于lable的特殊性,不设置它的宽度约束时,宽度取决于文字的内容,所以两个lable的约束设置好一些 ...
- java初级开发一系列的工具安装配置
最近压力很大,刚刚帮朋友安装了一整套环境,按照印象写下此篇记录(没有图解),一是用来释放压力,二来希望可以帮到各位. 一.首先,Eclipse的安装,下载eclipse压缩包,一般为200~300M, ...
- 无线同步模块SYN1000在电力监测相位测量领域的应用方案
在电力监测领域,出于安全考虑,有些系统不得不采用无线通信的方式,在这样一个无线通信的应用系统,该如何来控制多个设备进行同步采样,以期提高相位角的测量精度,是一个不小的难题. 很多技术人员习惯性的采用无 ...
- Java的Date和Time入门教程
本文是一篇翻译文章,已取得原作者授权,原文地址是http://tutorials.jenkov.com/java-date-time/index.html Java语言的JDK中关于日期和时间的API ...
- @PostConstruct 注解
@PostConstruct 注解 /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. ...
- 给angularJs grid列上添加自定义按钮
由于项目需要在angular 显示的表格中添加按钮,多次查询资料终于找到解决方法.就是给columnDefs 上的列增加 cellTemplate,同时绑定对应的触发事件,代码如下 columnDef ...
- iOS开发之UIView的常见属性
1.所有控件都继承自UIView,UIView的常见属性如下: @property(nonatomic,readonly) UIView *superview;获得自己的父控件对象 @property ...
- 安装Postgresql
p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; line-height: 150%; fon ...
- Java基础之面试题
本文我们将要讨论Java面试中的各种不同类型的面试题,它们可以让雇主测试应聘者的Java和通用的面向对象编程的能力.下面的章节分为上下两篇,第一篇将要讨论面向对象编程和它的特点,关于Java和它的功能 ...
- Redis基础学习(二)—数据类型
一.Redis支持的数据类型 Redis中存储数据是通过key-value存储的,对于value的类型有以下几种: (1)字符串. (2)Map (3)List (4)Set public cla ...