java网页爬虫的实现
爬取某数字网站公司信息第一步第二步第三步第四步详细代码爬取某数字网站公司信息第一步首先先分析页面url,爬虫最重要的就是获取页面的url,观察要爬取页面的url查看其规律找到其构成元素,一般都会有id、页面信息等然后分析页面请求数据后返回的数据类型,有的页面信息直接在html代码中,有的返回的是json,根据不同情况分别解析便可第二步模仿浏览器访问,否则可能会被封ip,代码如下// 创建httpclient实例 CloseableHttpClient httpclient = HttpClients.createDefault(); String url = “https://“www.hah.com””; // 创建httpget实例 HttpGet httpget = new HttpGet(url); // 模拟浏览器 ✔ httpget.setHeader(“User-Agent”, “Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:50.0) Gecko/20100101 Firefox/60.0”); // 使用代理 IP ✔// HttpHost proxy = new HttpHost(“192.168.1.124”, 8080); RequestConfig config = RequestConfig.custom() //设置连接超时 ✔ .setConnectTimeout(10000) // 设置连接超时时间 10秒钟 .setSocketTimeout(10000) // 设置读取超时时间10秒钟 .build(); httpget.setConfig(config); // 执行get请求 CloseableHttpResponse response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); // 获取返回实体(页面代码) String content = EntityUtils.toString(entity, “utf-8”); //System.out.println(content);12345678910111213141516171819202122第三步解析页面:如果页面返回的是html代码,有两种方法解析(1)、用jsoup获得html标签,找到你想获得的信息所在标签,可根据其class定位它,在分别获取属性值和内容便可,例: //获取class中值为 ico bz-border的标签 Elements s3 = text.getElementsByAttributeValue(“class”, “ico bz-border”); //获取a标签 Elements a = text.getElementsByTag(“a”); //获取a中的href属性值 String href = a.get(0).attr(“href”); //获取a标签中的内容 String ka = a.get(1).text();12345678(2)、用正则表达式解析获得html标签,属性值等,可以分层获取解析,如果不能解析,可利用string API中的方法截取字符串等例: //获取class中值为 ico bz-border的标签 Elements s3 = text.getElementsByAttributeValue(“class”, “ico bz-border”); //获取a标签 Elements a = text.getElementsByTag(“a”); //获取a中的href属性值 String href = a.get(0).attr(“href”); //获取a标签中的内容 String ka = a.get(1).text();12345678//用正则解析代码 String a = “<a[>]*>([<])"; String aTag = "<a[>]*>([<])”; Pattern aPattern = Pattern.compile(aTag); Matcher aMatcher = aPattern.matcher(content); //System.out.println(“解析a为:”+ amatcher.find()); String reg = “[^\u4e00-\u9fa5]”; //判断地址是否规范 String judge = “false”; while (aMatcher.find()) { String allMessage = aMatcher.group(); //System.out.println(“解析a为:”+allMessage); //使用正则表达式 Pattern pattern = Pattern.compile("[^\u4E00-\u9FA5]"); //[\u4E00-\u9FA5]是unicode2的中文区间 Matcher matcher = pattern.matcher(allMessage); String doubleAddress = matcher.replaceAll(""); // System.out.println(“解析doubleAddress为:”+doubleAddress); //System.out.println(“汉字长度为”+matcher.replaceAll("")); //System.out.println(“汉字为:”+doubleAddress); if(doubleAddress.equals(“搜职位”)){ judge = “true”; } }12345678910111213141516171819202122232425解析页面:如果页面返回的是json,直接解析json即可第四步把数据存储数据库或导出文件即可//导出文件public class ExportExcel { HSSFWorkbook workbook = new HSSFWorkbook();// 创建工作簿对象 中有多个sheet //显示的导出表的标题 private String title; //导出表的列名 private String[] rowName; private List<List<Object[]>> list = new ArrayList<List<Object[]>>(); private List<Object[]> countList = new ArrayList<>(); private String[] categoryName; //构造方法,传入要导出的数据 public ExportExcel(String title, String[] rowName, List<List<Object[]>> list, String[] categoryName, List<Object[]> countList) { this.list = list; this.rowName = rowName; this.title = title; this.categoryName = categoryName; this.countList = countList; } public ExportExcel(String title, String[] rowName) { this.rowName = rowName; this.title = title; } public void exportPersonInfo2(String sheetTitle,List countList) throws Exception { try { HSSFSheet sheet = workbook.createSheet(sheetTitle);// 创建工作表 sheet.setColumnWidth(1, 4000); sheet.setColumnWidth(2, 20000); HSSFCellStyle style = this.getStyle(workbook); HSSFCellStyle numberStyle = this.getNumberStype(workbook); HSSFCellStyle headStyle = this.getColumnTopStyle(workbook); int columnNum = rowName.length; HSSFRow rowRowName = sheet.createRow(2); // 在索引2的位置创建行(最顶端的行开始的第二行) HSSFRow rowRowName2 = sheet.createRow(3); // 在索引2的位置创建行(最顶端的行开始的第二行) // 将列头设置到sheet的单元格中 for (int n = 0; n < columnNum; n++) { HSSFCell cellRowName = rowRowName.createCell(n); //创建列头对应个数的单元格 cellRowName.setCellType(HSSFCell.CELL_TYPE_STRING); cellRowName.setCellStyle(headStyle); HSSFCell cellRowName2 = rowRowName2.createCell(n); //创建列头对应个数的单元格 cellRowName2.setCellType(HSSFCell.CELL_TYPE_STRING); cellRowName2.setCellStyle(headStyle); sheet.addMergedRegion(new CellRangeAddress(2, 3, n, n)); //设置列头单元格的数据类型 HSSFRichTextString text = new HSSFRichTextString(rowName[n]); cellRowName.setCellValue(text); //设置列头单元格的值 // HSSFCell cell = row.createCell((short) cellIndex); //创建表头 HSSFRow row=sheet.createRow(1); //合并列 HSSFCell cell=row.createCell(0); cell.setCellValue(sheetTitle);// CellRangeAddress callRangeAddress1 = new CellRangeAddress(1,1,0,2);; cell.setCellType(HSSFCell.CELL_TYPE_STRING); cell.setCellStyle(headStyle); } //将查询出的数据设置到sheet对应的单元格中 List dataList = countList; System.out.println(dataList.size()); for (int i = 0; i < dataList.size(); i++) { HSSFRow row = sheet.createRow(i + 6);//创建所需的行数 HSSFCell cell1 = row.createCell(0, HSSFCell.CELL_TYPE_STRING); cell1.setCellStyle(style); cell1.setCellValue(i + 1); HSSFCell cell2 = row.createCell(1, HSSFCell.CELL_TYPE_STRING); cell2.setCellStyle(style); cell2.setCellValue(dataList.get(i).getCompanyName()); HSSFCell cell3 = row.createCell(2, HSSFCell.CELL_TYPE_STRING); cell3.setCellStyle(style); cell3.setCellValue(dataList.get(i).getCompanyUrl()); } } catch (Exception e) { e.printStackTrace(); } } }12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879详细代码package com.mbyte.easy.admin.controller;import java.io.IOException;import java.util.Arrays;import java.util.Scanner;import java.util.regex.Matcher;import java.util.regex.Pattern;import com.mbyte.easy.admin.entity.FiveEightCity;import com.mbyte.easy.admin.service.IFiveEightCityService;import com.sun.org.apache.xerces.internal.parsers.DOMParser;import net.sourceforge.pinyin4j.PinyinHelper;import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;import org.apache.http.HttpEntity;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.config.RequestConfig;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.util.EntityUtils;import javax.xml.parsers.ParserConfigurationException;import static java.lang.Integer.parseInt;public class TestHttp { /** * 获取总页数 * @param args * @throws IOException / public static void main(String[] args) throws IOException { // 创建httpclient实例 CloseableHttpClient httpclient = HttpClients.createDefault(); System.out.print(“请输入需要查找的公司关键字:”); Scanner in = new Scanner(System.in); String Keyword=in.next(); System.out.print(“请输入需要查找的公司所在城市:”); Scanner in1 = new Scanner(System.in); String city = in1.next(); TestHttp pinyin11 = new TestHttp(); String cityPI = pinyin11.getPinYin(city); System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"+cityPI); String url = “https://”+cityPI+"..com/job/?key="+Keyword+"&classpolicy=main_null,job_A&final=1&jump=1"; // 创建httpget实例 HttpGet httpget = new HttpGet(url); // 模拟浏览器 ✔ httpget.setHeader(“User-Agent”, “Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:50.0) Gecko/20100101 Firefox/60.0”); // 使用代理 IP ✔// HttpHost proxy = new HttpHost(“192.168.1.124”, 8080); RequestConfig config = RequestConfig.custom() //设置连接超时 ✔ .setConnectTimeout(10000) // 设置连接超时时间 10秒钟 .setSocketTimeout(10000) // 设置读取超时时间10秒钟 .build(); httpget.setConfig(config); // 执行get请求 CloseableHttpResponse response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); // 获取返回实体(页面代码) String content = EntityUtils.toString(entity, “utf-8”); //System.out.println(content); //用正则解析代码 String a = "<a[>]*>([<])"; String aTag = "<a[>]*>([<])"; Pattern aPattern = Pattern.compile(aTag); Matcher aMatcher = aPattern.matcher(content); //System.out.println(“解析a为:”+ amatcher.find()); String reg = “[^\u4e00-\u9fa5]”; //判断地址是否规范,如果没有搜职位即是主页面 String judge = “false”; while (aMatcher.find()) { String allMessage = aMatcher.group(); //System.out.println(“解析a为:”+allMessage); //使用正则表达式 Pattern pattern = Pattern.compile("[^\u4E00-\u9FA5]"); //[\u4E00-\u9FA5]是unicode2的中文区间 Matcher matcher = pattern.matcher(allMessage); String doubleAddress = matcher.replaceAll(""); // System.out.println(“解析doubleAddress为:”+doubleAddress); //System.out.println(“汉字长度为”+matcher.replaceAll("")); //System.out.println(“汉字为:”+doubleAddress); if(doubleAddress.equals(“搜职位”)){ judge = “true”; } } //获取页面信息的总页数 String iTag = "<i[>]*>([<])"; Pattern iPattern = Pattern.compile(iTag); Matcher iMatcher = iPattern.matcher(content); String allPage = “-1”; while (iMatcher.find()){ String iMessage = iMatcher.group(); //System.out.println(“解析i为:”+ iMessage); if(iMessage.length()>=27 && iMessage.length()<=28){ Pattern pattern = Pattern.compile("[^\u4E00-\u9FA5]"); //[\u4E00-\u9FA5]是unicode2的中文区间 Matcher matcher = pattern.matcher(iMessage); String haveChinese = matcher.replaceAll(""); if(haveChinese.length()0){ //System.out.println(“解析i为:”+ iMessage); String regEx3 = “[0-9]”; allPage = matchResult(Pattern.compile(regEx3),iMessage); //System.out.println(“解析allPage为:”+ allPage); } } } //System.out.println(“解析allPage为:”+ allPage); //System.out.println(“judge:”+ judge); TestHttp testHttp = new TestHttp(); int page = parseInt(allPage); //加入判断看信息是否正确,且信息有几页,采用不同的方式调用爬取方法 if(judge.equals(“true”)){ if(page == -1){ System.out.println(“没有与”"+Keyword+"“关键字匹配的信息!”); }else if(page == 1){ testHttp.branchPage(page,Keyword); }else{ for(int i = 1 ; i <= page ; i++){ testHttp.branchPage(i,Keyword); } } }else{ System.out.println(“输入的”"+city+"“地址不存在!”); } } / * 获取字符串中的数字 * @param p * @param str * @return / public static String matchResult(Pattern p,String str) { StringBuilder sb = new StringBuilder(); Matcher m = p.matcher(str); while (m.find()) for (int i = 0; i <= m.groupCount(); i++) { sb.append(m.group()); } return sb.toString(); } /* * 爬取信息 * @param page * @param keyword * @throws IOException */ public void branchPage(int page,String keyword) throws IOException { // 创建httpclient实例 CloseableHttpClient httpclient = HttpClients.createDefault(); String url = “https://bd.58.com/job/?key=” + keyword + “&classpolicy=main_null,job_A&final=1&jump=1&page=” + page; // 创建httpget实例 HttpGet httpget = new HttpGet(url); // 模拟浏览器 ✔ httpget.setHeader(“User-Agent”, “Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:50.0) Gecko/20100101 Firefox/60.0”); // 使用代理 IP ✔// HttpHost proxy = new HttpHost(“192.168.1.124”, 8080); RequestConfig config = RequestConfig.custom() //设置连接超时 ✔ .setConnectTimeout(10000) // 设置连接超时时间 10秒钟 .setSocketTimeout(10000) // 设置读取超时时间10秒钟 .build(); httpget.setConfig(config); // 设置爬取时间间隔 5s try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } // 执行get请求 CloseableHttpResponse response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); // 获取返回实体(页面代码) String content = EntityUtils.toString(entity, “utf-8”); //System.out.println(content); System.out.println("================================================================================================");// String a = “<a[>]*>([<])"; //用正则解析代码,解析a标签 String aTag = "<a[>]*>([<])”; Pattern aPattern = Pattern.compile(aTag); Matcher aMatcher = aPattern.matcher(content); //System.out.println(“解析a为:”+ amatcher.find()); String reg = “[^\u4e00-\u9fa5]”; while (aMatcher.find()) { String allMessage = aMatcher.group(); if (allMessage.length() >= 235 && allMessage.length() <= 262) { //使用正则表达式,用StringAPI获取想要信息 Pattern pattern = Pattern.compile("[^\u4E00-\u9FA5]"); //[\u4E00-\u9FA5]是unicode2的中文区间 Matcher matcher = pattern.matcher(allMessage); String doubleAddress = matcher.replaceAll(""); //System.out.println(“汉字长度为”+matcher.replaceAll("")); if (doubleAddress.length() > 8) { String href = allMessage.substring(10, 43); if(href.indexOf(“https”) != -1){ String hrefs = href.replaceAll(" “, “”); //System.out.println(“hrefs:” + hrefs); if(href.length() > hrefs.length()){ String hrefUrl = hrefs.substring(0, 28); if(hrefUrl.indexOf(”"") != -1){ String hrefUrls = hrefUrl.substring(0,hrefUrl.length()-1); System.out.println(“链接:” + hrefUrls); int length = doubleAddress.length() / 2; String address = doubleAddress.substring(0, length); System.out.println(“地址:” + address); } }else{ if(href.indexOf(""") != -1){ String hrefUrls = href.substring(0,href.length()-1); System.out.println(“链接:” + hrefUrls); int length = doubleAddress.length() / 2; String address = doubleAddress.substring(0, length); System.out.println(“地址:” + address); }else{ System.out.println(“链接:” + href); int length = doubleAddress.length() / 2; String address = doubleAddress.substring(0, length); System.out.println(“地址:” + address); } } } } } } } /** * 将汉字转换成拼音 * @param inputString * @return */ public static String getPinYin(String inputString) { HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat(); format.setCaseType(HanyuPinyinCaseType.LOWERCASE); format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); format.setVCharType(HanyuPinyinVCharType.WITH_V); char[] input = inputString.trim().toCharArray(); String output = “”; try { for (int i = 0; i < input.length; i++) { if (java.lang.Character.toString(input[i]).matches("[\u4E00-\u9FA5]+")) { String[] temp = PinyinHelper.toHanyuPinyinStringArray(input[i], format); output += temp[0]; } else output += java.lang.Character.toString(input[i]); } } catch (BadHanyuPinyinOutputFormatCombination e) { e.printStackTrace(); } return output; }}

Java网络爬虫实现相关推荐

  1. Java网络爬虫实操(5)

    上一篇:Java网络爬虫实操(4) 大家好,前几篇文章介绍的URL都是返回HTML内容的,然后再从HTML字符串里解析出我们想要的数据. 但是,随着前端编程技术的发展,至少十多年前开始ajax.jso ...

  2. java 网络爬虫 正则表达式_【干货】Java网络爬虫基础知识

    原标题:[干货]Java网络爬虫基础知识 引言 Java 网络爬虫具有很好的扩展性可伸缩性,其是目前搜索引擎开发的重要组成部分.例如,著名的网络爬虫工具 Nutch 便是采用 Java 开发,该工具以 ...

  3. Java网络爬虫实操(3)

    上一篇:Java网络爬虫实操(2) 本篇文章主要介绍NetDiscovery框架中pipeline模式的一些实际使用方法. 1) 什么是pipeline pipeline是一种常见的算法模式,针对不断 ...

  4. Java网络爬虫实操(8)

    上一篇:Java网络爬虫实操(7) 大家好,本篇文章介绍一下NetDiscovery爬虫框架里的downloader对象 1) 前言 面向对象设计仍然是目前编程的核心思想,从下面截图可以了解爬虫框架的 ...

  5. 第三十六期:学 Java 网络爬虫,需要哪些基础知识?

    说起网络爬虫,大家想起的估计都是 Python ,诚然爬虫已经是 Python 的代名词之一,相比 Java 来说就要逊色不少.有不少人都不知道 Java 可以做网络爬虫,其实 Java 也能做网络爬 ...

  6. Java网络爬虫该如何学习

    文章目录 引言 怎么入门网络爬虫 课程特色 学完本课程能收获什么 引言 互联网以及移动技术的飞速发展,使得全球数据量呈现前所未有的爆炸式增长态势.例如,用户在互联网上的搜索数据.交易数据.评论数据.社 ...

  7. java网络爬虫,乱码问题终于完美解决

    java网络爬虫,乱码问题终于完美解决 参考文章: (1)java网络爬虫,乱码问题终于完美解决 (2)https://www.cnblogs.com/-LilyBlog-/p/7593841.htm ...

  8. 在不同领域,大家用爬虫怎么盈利的-Java网络爬虫系统性学习与实战系列(4)

    在不同领域,大家用爬虫怎么盈利的-Java网络爬虫系统性学习与实战系列(4) 文章目录 概述 出行抢票软件 微博上的僵尸粉 电商比价/返利平台 社区抓取数据和内容 联系方式 系列文章地址: Java网 ...

  9. Java网络爬虫基础概述

    Java网络爬虫基础 Http基础 网络资源一般是Web服务器上的一些各种格式的文件,通过Http协议传输互联网上的数据. 在Java中,通常通过URL标出网络资源的位置和Web服务器建立链接,获取网 ...

  10. 了解爬虫的风险与以及如何规避风险-Java网络爬虫系统性学习与实战系列(3)

    了解爬虫的风险与以及如何规避风险-Java网络爬虫系统性学习与实战系列(3) 文章目录 概述 法律风险 民事风险 刑事风险 个人信息的法律风险 著作权的风险(文章.图片.影视等数据) 5不要 3准守 ...

最新文章

  1. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 获取 linker 中的 dlopen 函数地址 并 通过 远程调用 执行该函数 )
  2. Py之wordcloud:python中非常有趣的词云图wordcloud简介、安装、使用方法、案例应用详细攻略
  3. 如何降低微服务测试成本?
  4. 为什么要学习C++,它到底能做什么?
  5. Golang面向API编程-interface(接口)
  6. Windows 7 文件夹共享
  7. Objective-C 2.0 with Cocoa Foundation--- 5,Class类型,选择器Selector以及函数指针
  8. 巨人退场!索尼前CEO平井一夫正式退休 结束35年索尼生涯
  9. ListView setOnItemClickListener无法响应点击事件解决
  10. Producer Consumer
  11. Shell循环输入符合条件为止
  12. 入职与离职手续、五险一金、档案
  13. Hibernate(6)——映射类型
  14. 计算机网络和internet选项,小编教你电脑ie的internet选项在哪
  15. C++基础算法学习——汉洛塔问题
  16. 处理文件上传后返回json数据在IE出现文件下载问题(框架是spring boot)
  17. 「CF230A」龙的战争(详细分析)
  18. 服务器性能管理系统,服务器系统性能管理是什么
  19. Mybatis常见错误 Could not find resource com/mybatis/mapper/UserInfoMapper.xml
  20. Java后端处理video快进快退播放以及断点续传的原理和代码

热门文章

  1. Jayway JsonPath介绍
  2. vue自定义指令directives
  3. AndroidStudio中使用Junit进行单元测试
  4. Nginx中使用htpasswd
  5. htpasswd作用
  6. input输入框去除前后空格
  7. Mapreduce中的Combiner合并
  8. JS类型转换常见的方法集合
  9. 【Oracle】基础知识面试题
  10. redis持久化分析