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

一、创建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. 1821: [JSOI2010]Group 部落划分 Group

    1821: [JSOI2010]Group 部落划分 Group Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1308  Solved: 627[Su ...

  2. java入门知识

    Java特性 简单.面向对象.支持网络.解释性.健壮性.安全性.高性能.可移植(跨平台) Java特点 开源.免费.跨平台.面向对象 应用平台 JavaSE(standard edition)(c/s ...

  3. 浅谈python 手机crash和app crash循环执行问题

    ----------------引子---------------- app自动化测试人员经常遇见的问题,第一:手机抛的异常导致脚本循环停止!!!!!!!!第二:app抛的异常导致脚本循环停止!!!! ...

  4. lnmp pathinfo问题

    location / {              if (!-e $request_filename) {              rewrite  ^/(.*)$  /index.php/$1  ...

  5. git中常见的几个命令

    git中常见的几个命令 本地仓库 三个区域 工作目录 暂存区 本地仓库 文件的四个状态 未跟踪 untracked 已暂存 staged 已提交commited 已修改 modified 基本命令 g ...

  6. JQ万能轮播图

    lunbotu.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8">  ...

  7. Codeforces Gym 100269E Energy Tycoon 贪心

    题目链接:http://codeforces.com/gym/100269/attachments 题意: 有长度为n个格子,你有两种操作,1是放一个长度为1的东西上去,2是放一个长度为2的东西上去 ...

  8. 使用gem安装jekyll错误记录

    准备在windows7上安装Jekyll, 安装好了Ruby和RubyDevKit之后,准备使用: $ gem install jekyll 安装jekyll,但是返回错误: ERROR: While ...

  9. 开始学习yii2第一天

    今天在朋友圈看到一条转发,内容是根据招聘网站的要求,列举了需要一个php工程师具体需要哪些技能 框架要求是yii2 出现的最多 已经出来工作了快半个月了,感觉工资还是少的可怜,而且我也好想去张江, 所 ...

  10. 我所理解的javascript中函数的作用域和作用域链

    本文为原创,转载请注明出处: cnzt       文章:cnzt-p 写在前面 一周木有更新了,今天终于攻克了自行车难关,非常开心,特意来一更~ (那些捂嘴偷笑的人我看到你们了快把嘴闭上我会假装没看 ...