java爬取网页内容 简单例子(1)——使用正则表达式
【本文介绍】
爬取别人网页上的内容,听上似乎很有趣的样子,只要几步,就可以获取到力所不能及的东西,例如呢?例如天气预报,总不能自己拿着仪器去测吧!当然,要获取天气预报还是用webService好。这里只是举个例子。话不多说了,上看看效果吧。
【效果】
我们随便找个天气预报的网站来试试:http://www.weather.com.cn/html/weather/101280101.shtml
从图中可用看出,今天(6日)的天气。我们就以这个为例,获取今天的天气吧!
最终后台打印出:
今天:6日
天气:雷阵雨
温度:26°~34°
风力:微风
【思路】
1、通过url获取输入流————2、获取网页html代码————3、用正则表达式抽取有用的信息————4、拼装成想要的格式
其实最难的一点事第3点,如果正则表示式不熟,基本上在这一步就会挂掉了——例如我T_T。下面为了抽取到正确的数据,我匹配了多次,如果能一次匹配的话,那代码量就少多了!
【代码】
package com.zjm.www.test; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern; /**
* 描述:趴取网页上的今天的天气
* @author zjm
* @time 2014/8/6
*/
public class TodayTemperatureService { /**
* 发起http get请求获取网页源代码
* @param requestUrl String 请求地址
* @return String 该地址返回的html字符串
*/
private static String httpRequest(String requestUrl) { StringBuffer buffer = null;
BufferedReader bufferedReader = null;
InputStreamReader inputStreamReader = null;
InputStream inputStream = null;
HttpURLConnection httpUrlConn = null; try {
// 建立get请求
URL url = new URL(requestUrl);
httpUrlConn = (HttpURLConnection) url.openConnection();
httpUrlConn.setDoInput(true);
httpUrlConn.setRequestMethod("GET"); // 获取输入流
inputStream = httpUrlConn.getInputStream();
inputStreamReader = new InputStreamReader(inputStream, "utf-8");
bufferedReader = new BufferedReader(inputStreamReader); // 从输入流读取结果
buffer = new StringBuffer();
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
} } catch (Exception e) {
e.printStackTrace();
} finally {
// 释放资源
if(bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(inputStreamReader != null){
try {
inputStreamReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(inputStream != null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(httpUrlConn != null){
httpUrlConn.disconnect();
}
}
return buffer.toString();
} /**
* 过滤掉html字符串中无用的信息
* @param html String html字符串
* @return String 有用的数据
*/
private static String htmlFiter(String html) { StringBuffer buffer = new StringBuffer();
String str1 = "";
String str2 = "";
buffer.append("今天:"); // 取出有用的范围
Pattern p = Pattern.compile("(.*)(<li class=\'dn on\' data-dn=\'7d1\'>)(.*?)(</li>)(.*)");
Matcher m = p.matcher(html);
if (m.matches()) {
str1 = m.group(3);
// 匹配日期,注:日期被包含在<h2> 和 </h2>中
p = Pattern.compile("(.*)(<h2>)(.*?)(</h2>)(.*)");
m = p.matcher(str1);
if(m.matches()){
str2 = m.group(3);
buffer.append(str2);
buffer.append("\n天气:");
}
// 匹配天气,注:天气被包含在<p class="wea" title="..."> 和 </p>中
p = Pattern.compile("(.*)(<p class=\"wea\" title=)(.*?)(>)(.*?)(</p>)(.*)");
m = p.matcher(str1);
if(m.matches()){
str2 = m.group(5);
buffer.append(str2);
buffer.append("\n温度:");
}
// 匹配温度,注:温度被包含在<p class=\"tem tem2\"> <span> 和 </span><i>中
p = Pattern.compile("(.*)(<p class=\"tem tem2\"> <span>)(.*?)(</span><i>)(.*)");
m = p.matcher(str1);
if(m.matches()){
str2 = m.group(3);
buffer.append(str2);
buffer.append("°~");
}
p = Pattern.compile("(.*)(<p class=\"tem tem1\"> <span>)(.*?)(</span><i>)(.*)");
m = p.matcher(str1);
if(m.matches()){
str2 = m.group(3);
buffer.append(str2);
buffer.append("°\n风力:");
}
// 匹配风,注:<i> 和 </i> 中
p = Pattern.compile("(.*)(<i>)(.*?)(</i>)(.*)");
m = p.matcher(str1);
if(m.matches()){
str2 = m.group(3);
buffer.append(str2);
}
}
return buffer.toString();
} /**
* 对以上两个方法进行封装。
* @return
*/
public static String getTodayTemperatureInfo() {
// 调用第一个方法,获取html字符串
String html = httpRequest("http://www.weather.com.cn/html/weather/101280101.shtml");
// 调用第二个方法,过滤掉无用的信息
String result = htmlFiter(html); return result;
} /**
* 测试
* @param args
*/
public static void main(String[] args) {
String info = getTodayTemperatureInfo();
System.out.println(info);
}
}
【详解】
34-49行:通过url获取网页的源码,没什么好说的。
96行:在网页上按F12,查看"今天"的html代码,发现如下图,所以我们第一步就是要过滤掉除这一段html代码外的东西。
(.*)(<li class=\'dn on\' data-dn=\'7d1\'>)(.*?)(</li>)(.*) 这个正则表达式,很容易看出可以分为下面5组:
(.*) :匹配除换行符外任意东西0-N次
(<li class=\'dn on\' data-dn=\'7d1\'>) :匹配中间那段heml代码一次
(.*?) : .*?为匹配的懒惰模式,意思是匹配除换行符外任意东西尽可能少次
(</li>) :匹配中间那段html代码一次
(.*) :匹配除换行符外任意东西0-N次
这样,我们就可用m.group(3)拿到匹配中间(.*?)的那一串代码了。即我们需要的“今天”的天气的代码。
101行:中间那一段代码拿出来后如下图所示、还有很多无用的标签。我们要想办法继续除去。方法同上。
106行:手动拼接上我们需要的字符串。
经过以上的处理,就完成了一个简单的爬取啦。
中间正则表达式部分最不满意,各路网友如果有好的建议麻烦留下宝贵的评论,感激不尽~
java爬取网页内容 简单例子(1)——使用正则表达式的更多相关文章
- java爬取网页内容 简单例子(2)——附jsoup的select用法详解
[背景] 在上一篇博文java爬取网页内容 简单例子(1)——使用正则表达式 里面,介绍了如何使用正则表达式去解析网页的内容,虽然该正则表达式比较通用,但繁琐,代码量多,现实中想要想出一条简单的正则表 ...
- java爬虫爬取网页内容前,对网页内容的编码格式进行判断的方式
近日在做爬虫功能,爬取网页内容,然后对内容进行语义分析,最后对网页打标签,从而判断访问该网页的用户的属性. 在爬取内容时,遇到乱码问题.故需对网页内容编码格式做判断,方式大体分为三种:一.从heade ...
- Java爬取先知论坛文章
Java爬取先知论坛文章 0x00 前言 上篇文章写了部分爬虫代码,这里给出一个完整的爬取先知论坛文章代码. 0x01 代码实现 pom.xml加入依赖: <dependencies> & ...
- Java爬取同花顺股票数据(附源码)
最近有小伙伴问我能不能抓取同花顺的数据,最近股票行情还不错,想把数据抓下来自己分析分析.我大A股,大家都知道的,一个概念火了,相应的股票就都大涨. 如果能及时获取股票涨跌信息,那就能在刚开始火起来的时 ...
- MinerHtmlThread.java 爬取页面线程
MinerHtmlThread.java 爬取页面线程 package com.iteye.injavawetrust.miner; import org.apache.commons.logging ...
- MinerConfig.java 爬取配置类
MinerConfig.java 爬取配置类 package com.iteye.injavawetrust.miner; import java.util.List; /** * 爬取配置类 * @ ...
- Java爬取网络博客文章
前言 近期本人在某云上购买了个人域名,本想着以后购买与服务器搭建自己的个人网站,由于需要筹备的太多,暂时先搁置了,想着先借用GitHub Pages搭建一个静态的站,搭建的过程其实也曲折,主要是域名地 ...
- Java爬取校内论坛新帖
Java爬取校内论坛新帖 为了保持消息灵通,博主没事会上上校内论坛看看新帖,作为爬虫爱好者,博主萌生了写个爬虫自动下载的想法. 嗯,这次就选Java. 第三方库准备 Jsoup Jsoup是一款比较好 ...
- Java爬取B站弹幕 —— Python云图Wordcloud生成弹幕词云
一 . Java爬取B站弹幕 弹幕的存储位置 如何通过B站视频AV号找到弹幕对应的xml文件号 首先爬取视频网页,将对应视频网页源码获得 就可以找到该视频的av号aid=8678034 还有弹幕序号, ...
随机推荐
- ar命令学习
之前,学习Linux下使用静态库的时候涉及到了这三个命令: gcc -c my_strcpy.c my_strcmp.car rcs libmylib.a *.ogcc -o main main.c ...
- Spring mvc 返回JSON 在IE 下提示下载 解决办法
http://www.blogjava.net/iamlibo/archive/2013/11/21/406646.html ————————————————————————————————————— ...
- linux查看端口命令和kill
1.查看 netstat -atunlp 2kill:kill -9 PID
- 回文自动机 + DFS --- The 2014 ACM-ICPC Asia Xi’an Regional Contest Problem G.The Problem to Slow Down You
The Problem to Slow Down You Problem's Link: http://acm.hust.edu.cn/vjudge/problem/viewProblem.actio ...
- hive组件和执行过程
转自http://blog.csdn.net/lifuxiangcaohui/article/details/40262021 对Hive的基本组成进行了总结: 1.组件: 元存储(Metastore ...
- 关于Unity的C#基础学习(三)
面向对象 一.编码注意 1.每个C#的脚本只有唯一的一个类是继承自MonoBehaviour 2.类的名字要和我们的文件名字一样 3.代码的缩进 个人习惯:在类的内部来访问数据成员/成员函数的时候,用 ...
- 使用AngularJS实现的前后端分离的数据交互过程
一. AngularJS简介 AngularJS是什么 AngularJS是一个开源Web应用程序框架.最初是由MISKO Hevery和Adam Abrons于2009年开发,现在是由谷歌维护. A ...
- 下列JSP代码:
下列JSP代码: <html> <body> <% for(int i = 0; i < 10; i++) { //1 } %> </body> ...
- jQuery制作简洁的多级联动Select下拉框
今天我们要来分享一款很实用的jQuery插件,它是一个基于jQuery多级联动的省市地区Select下拉框,并且值得一提的是,这款联动下拉框是经过自定义美化过的,外观比浏览器自带的要漂亮许多.另外,这 ...
- 如何在ChemDraw中打出符号π
很多人日常使用ChemDraw是一款非常优秀的化学绘图软件,在其绘制化学结构式或者反应式的过程中,常常需要添加各种符号.比如有的用户会需要输入希腊字符π,但是不知道用什么方法添加.本教程就来给大家介绍 ...