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

一、创建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. 当前最上层的视图控制器vc 和 当前最上层的导航控制器nav

    在处理 URL Router 跳转的时候,我们经常需要得到 当前最上层的视图控制器 和 当前最上层的导航控制器 来进行视图跳转或者方法调用.- (UIViewController *)currentV ...

  2. UI 事件处理

    一 > 事件的基本概念 事件概述 : UIEvent  ( [ɪ’vent]事件  )  事件,是由硬件捕捉的一个表示用户操作设备的对象 分三类 : 触摸事件 ,晃动事件 ,远程控制事件 触摸事 ...

  3. POJ 2182 解题报告

    Lost Cows Time Limit: 1000 MS Memory Limit: 65536 KB Description N (2 <= N <= 8,000) cows have ...

  4. JavaScript原型模式-理解对象

    一:简述 当初学编程一看到什么什么模式就比较头晕,不过本文我们通过简单的示例代码来说一下js 对象这个话题 ,来看下如何理解这个原型模式. 二:理解对象 1.简单对象 js对象中没有java.C#等类 ...

  5. Linux-ubuntu安装过程讲解

    前言也不准备介绍Linux是什么,为什么要安装ubuntu?相信你能够看到这篇文章也知道自己想要做什么. 一,准备工具 1.VMwareWorkstation虚拟机 下载地址:https://my.v ...

  6. waypoints

    http://imakewebthings.com/waypoints waypoints 滑冰122分钟 Cygwin http:/nxutils.sourceforge.net http://ba ...

  7. python混账的编码问题解决之道

    下面的代码作用是修改文件的编码格式.代码很简单,但是也很牛逼(在我看来),这是在segment上找到的解决办法,废话不多说,直接上代码. import codecsdef ReadFile(fileP ...

  8. Ubuntu安装Nginx+PHP7.0.4+MySQL5.6

    安装Nginx 1.首先添加nginx_signing.key(必须,否则出错) $ wget http://nginx.org/keys/nginx_signing.key $ sudo apt-k ...

  9. ASP.NET Core:使用Dapper和SwaggerUI来丰富你的系统框架

    一.概述 1.用VS2017创建如下图的几个.NET Standard类库,默认版本为1.4,你可以通过项目属性进行修改,最高支持到1.6,大概五月份左右会更新至2.0,API会翻倍,很期待! 排名分 ...

  10. 关于RestfulAPI与SpringMVC之间的传值

    ##默认读者已经搭建好的SpringMVC的环境,并且对SpringMVC有着一定的了解,并且已经对RestfulAPI有了一定的了解 1,首先将WEB-INF下的web.xml里面的url-part ...