使用爬虫从网上抓取到一个网页内容,要想能正确显示,必须要获取网页的原始编码,否则会出现乱码。首先需要获取网页内容,最简单的办法就是通过JDK自带的HttpURLConnection类,要实现更复杂的抓取操作,请使用开源的爬虫框架,如Crawler4j,Web-Harvest,JSpider,WebMagic,Heritrix,Nutch等,我并不是来说爬虫相关技术的,只是网页内容的获取需要使用到爬虫技术,所以顺带提提有关爬虫的框架,具体你们自己去研究。这里为了简便起见,我就以JDK自带的HttpURLConnection类来抓取网页内容,抓取示例代码如下:
package com.yida.test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; /** * 提取网页内容 * @author Lanxiaowei * */ public class FetchWebPageTest { public static void main(String[] args) throws IOException { String charset = "UTF-8"; String line = ""; StringBuffer buffer = new StringBuffer(); URL url = new URL("http://www.baidu.com"); //开始访问该URL HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection(); //获取服务器响应代码 int responsecode = urlConnection.getResponseCode(); String contentType = urlConnection.getContentType(); //打印出content-type值,然后就可以从content-type中提取出网页编码 System.out.println("content-type:" + contentType); if(responsecode == 200){ //获取网页输入流 BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(),charset)); while((line = reader.readLine()) != null){ buffer.append(line).append("\n"); } System.out.println(buffer.toString()); } else{ System.out.println("获取不到网页的源码,服务器响应代码为:"+responsecode); } urlConnection.disconnect(); } }
关键点在这一句代码:
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(),charset));
这里的charset表示网页内容的字符集编码,上面的示例代码中charset是直接定义为UTF-8,实际我们期望是能自动判断,因为并不是所有网页内容的字符集编码都为UTF-8,这也是我们今天这篇文章的主题:如何获取网页内容的原始字符集编码。
首先,我们可以通过URLConnection类的getContentType()方法的返回值中获取,比如:
String contentType = urlConnection.getContentType();
返回值类似这样:
content-type:text/html; charset=utf-8
然后我们从字符串中提取出字符集编码,剩下这就是字符串处理了,没什么难度,你们都懂的!
当然,URLConnection类的getContentType()方法的返回值并不能保证一定会包含字符集编码,这时我们就需要另辟蹊径,我们都知道一般HTML页面源代码中都会包含<meta标签,如:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>欢迎页面</title> </head> <body> 欢迎页面 </body> </html>
关键点在这里:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
我们可以通过正则表达式从中提取出编码,示例代码如下:
package com.yida.test; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 从HTML网页的meta元素中提取页面编码 * 这里采用的是正则表达式方式提取,你也可以采用XML解析的方式来提取[HTML其实就是XML] * @author Lanxiaowei * */ public class CharsetExtractTest { public static void main(String[] args) { //test1(); test2(); } /** * 常规情况 */ public static void test1() { String content="<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" + "<head>\n" + "<meta http-equiv = \"Content-Type\" content = \"text/html; charset=utf-8\" />\n" + "<meta content=\"java获取 html网页编码\" name=\"Keywords\"/>...\n"; Pattern pattern = Pattern.compile("<meta\\s+http-equiv\\s*=\\s*\"Content-Type\"\\s+content\\s*=\\s*\"[\\s\\S]*?charset=(\\S+?)\"\\s*/>"); Matcher matcher=pattern.matcher(content); if(matcher.find()){ System.out.println(matcher.group(1)); } } /** * 非常规情况,比如http-equiv和content属性颠倒了 */ public static void test2() { String content="<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" + "<head>\n" + "<meta content = \"text/html; charset=utf-8\" http-equiv = \"Content-Type\" />\n" + "<meta content=\"java获取 html网页编码\" name=\"Keywords\"/>...\n"; String regex = "(<meta\\s+http-equiv\\s*=\\s*\"Content-Type\"\\s+content\\s*=\\s*\"[\\s\\S]*?charset=(\\S+?)\"\\s*/>)|" + "(<meta\\s+content\\s*=\\s*\"[\\s\\S]*?charset=(\\S+?)\"\\s+http-equiv\\s*=\\s*\"Content-Type\"\\s*/>)"; Pattern pattern = Pattern.compile(regex); Matcher matcher=pattern.matcher(content); if(matcher.find()){ System.out.println(matcher.group(4)); } } }
但遗憾的是,并不是每个网页内容都包含meta标签,因为总有些人不遵守HTML规范,这是我们该怎么办?还好我们还有一招可以来应对这种情形,那就是IBM的icu4j类库,icu4j可以从指定的字节数据从自动推断出其采用的字符集编码,具体示例代码如下:
package com.yida.test; import java.io.IOException; import java.io.InputStream; import com.ibm.icu.text.CharsetDetector; import com.ibm.icu.text.CharsetMatch; /** * 使用icu4j探测内容编码,这里的内容可以来自于字符串,字节数组,输入流等等 * * @author Lanxiaowei * */ public class Icu4jTest { public static void main(String[] args) { String data = "ICU4J 是IBM的国际化开发组件ICU的Java语言实现版本。"; String encode = getEncode(data); System.out.println("encode:" + encode); } public static String getEncode(String data) { return getEncode(data.getBytes()); } public static String getEncode(byte[] data) { CharsetDetector detector = new CharsetDetector(); detector.setText(data); CharsetMatch match = detector.detect(); //取Confidence值最大的 String encoding = match.getName(); System.out.println("The Content in " + match.getName()); CharsetMatch[] matches = detector.detectAll(); System.out.println("All possibilities"); for (CharsetMatch m : matches) { System.out.println("CharsetName:" + m.getName() + " Confidence:" + m.getConfidence()); } return encoding; } public static String getEncode(InputStream data) throws IOException { CharsetDetector detector = new CharsetDetector(); detector.setText(data); CharsetMatch match = detector.detect(); String encoding = match.getName(); System.out.println("The Content in " + match.getName()); CharsetMatch[] matches = detector.detectAll(); System.out.println("All possibilities"); for (CharsetMatch m : matches) { System.out.println("CharsetName:" + m.getName() + " Confidence:" + m.getConfidence()); } return encoding; } }
还有一点需要注意的就是,如果抓取到的网页内容输入流不管是使用GBK还是UTF-8,都全是乱码,那很有可能是该网页所在服务器对其采用GZip压缩,所以在获取到网页输入流时首先需要对其进行GZip解压缩,那如何确定对方服务器是否有对网页进行GZip压缩呢,一般可以通过响应头信息中获取到,如果响应头里包含了如下信息:
Accept-Encoding: gzip,deflate
则表明该网页被GZip压缩过,在获取网页内容之前,需要一个GZip解压缩过程,特此提醒!GZip解压缩示例代码如下:
InputStream is = urlConnection.getInputStream(); //用GZIPInputStream 对原始的输入流包装一下 GZIPInputStream gis = new GZIPInputStream(he.getContent()); BufferedReader reader = new BufferedReader(new InputStreamReader(gis,charset));
上述所有示例代码打包上传到我的百度网盘,代码下载地址如下:
http://pan.baidu.com/s/1kTgQi0Z
如果你还有什么问题请加我Q-Q:7-3-6-0-3-1-3-0-5,
或者加裙
一起交流学习!
相关推荐
下面是一个简单的Java代码示例,展示了如何使用这些库来获取网页的编码格式: ```java import net.sourceforge.cpptools.detector.CPDetectionResult; import ...
### JAVA获取网页有效邮箱地址 #### 知识点解析 本篇文章主要介绍了一种通过Java程序来抓取网页上的有效邮箱地址的方法。该程序能够接收一个网页URL作为输入,然后解析网页源代码并从中提取出所有符合标准格式的...
例如,可以执行一个JavaScript脚本来获取网页的canvas元素,然后调用`toDataURL()`方法将canvas内容转换为Base64编码的图像数据。 5. **处理图像数据**:在Java端接收到Base64编码的图像数据后,将其解码并保存为...
在Java编程语言中,开发一个图形用户界面(GUI)来获取网页源代码涉及到多个关键知识点。这个项目使用了Java Swing库来创建JFrame窗口,并利用Java的网络编程能力来抓取网页内容。以下是对这些技术的详细解释: 1. ...
在Java编程环境中,获取微信...总之,Java获取微信小程序OpenID是一个涉及客户端和服务器端交互的过程,涉及到微信API的调用、数据安全处理等多个方面。理解并掌握这一过程,对于开发与微信小程序集成的应用至关重要。
### Java获取网页中图片的方法与判断网页代码中是否包含有效图片 在当今互联网时代,从网页中抓取图片是常见的需求之一,特别是在数据抓取、网络爬虫或内容分析等应用中。Java作为一种广泛使用的编程语言,提供了...
总结来说,Java获取邮箱联系人库文件是一个涉及网络编程、HTML解析和网页模拟的复杂过程。借助如`flyerhzm-contactlist-855a71f`这样的工具库和辅助调试工具,如httpwatch,开发者可以更高效地完成这一任务。在实际...
Java获取网页数据步骤方法详解 Java获取网页数据是指使用Java语言从互联网上获取网页数据的过程。这个过程主要包括使用HttpClient请求网页、获取网页源码、查看源码是否有需要提取的数据、对源码进行拆解、获取需要...
2. **打开连接并获取页面内容**:使用`openStream()`方法打开与URL的连接,并获取网页的HTML内容。这一步通常涉及到HTTP请求,但在这里我们假设已经完成了这个步骤,因为描述中提到的是直接修改URL。 3. **使用...
在Java编程语言中,"获取积分"通常是指在软件系统中处理用户积分的逻辑,这可能涉及到用户行为的记录、积分计算、积分存储以及积分查询等多个方面。在开发这样的功能时,我们需要关注以下几个核心知识点: 1. **...
Java后端将从RTSP源获取的视频流通过WebSocket推送到前端,`<video>`标签则负责实时解码并显示这些数据。 6. **录像功能**:项目可能使用JavaCV库来捕获视频流,并将其保存为本地文件。FFmpeg可以在此过程中帮助...
本教程将详细介绍如何通过URL地址获取网页并生成jpg图片,同时解决32位和64位运行环境下的兼容性问题。我们将主要使用Java语言来实现这一功能,因为它具有丰富的库和跨平台的特性。 首先,我们需要一个能够处理网络...
首先,通过`API Key`和`API Secret`获取请求码(Request Token),然后引导用户访问授权页面,用户同意授权后,新浪会将授权码(Access Token)返回到你设置的回调URL。 一旦获得Access Token,就可以将其存储起来...
本示例的"GetURL.java"文件可能包含了获取网页HTML内容,然后从中提取出链接URL的功能。 5. **HTML解析**: 要从HTML文档中提取URL,通常需要解析HTML。Java有多种库可用于解析HTML,如Jsoup,它提供了方便的方法...
### Java字符串编码转换详解 #### 一、Java 字符串编码转换基础 在Java中,字符串的处理是非常常见的操作之一,而字符编码是确保数据正确显示的关键因素。本篇文章将重点介绍Java中字符串编码的转换方法及其在Web...
在IT领域,特别是Java...总之,使用Java读取网页并生成静态页面涉及到网络编程、输入输出流操作、编码处理、异常管理等多个方面的知识。掌握这些核心技能,不仅能够提升个人编程能力,还能在实际项目中发挥重要作用。
java用来获取网页编码的jar,可以用来判定目标链接的页面的编码格式
Java 实现免费代理IP的获取方式 并动态实时校验是否有效,java文件项目内含有Jsoup的Jar包(Jsoup是加工过的,含请求),有2个主入口程序: 其一:用于请求代理IP,并立即校验是否是一个有效的代理IP,如果有效,...
Java网页登录页面是Web开发中的基础模块,它用于获取用户的身份信息并验证其合法性。在这个过程中,我们通常会涉及到HTML、CSS、JavaScript等前端技术来构建界面,而后端则使用Java JSP(JavaServer Pages)处理请求...
在Java编程中,获取某个...以上就是使用Java获取城市天气信息的基本步骤和涉及的技术点,实际开发中可能需要根据具体需求进行调整和优化。在实现过程中,学习和理解HTTP协议、JSON解析以及错误处理机制是非常重要的。