package cn.itcast.httpserver;
import java.io.BufferedInputStream;
public class DownloadImage {
private String url;
public DownloadImage(String url) {
this.url = url;
}
public void run() {
/**
* 获取相关的html页面 解析html页面中<img>标签,并且获取src属性的值,把图片的地址放到一个集合中
*/
//获取html代码
String html = loadHtml(this.url);
//从html代码中获取所有的img标签的src属性
List<String> imgPaths = parseImagePath(html);
for (String imgPath : imgPaths) {
//获取网络图片url路径
String path = "http://127.0.0.1/"+imgPath;
Thread thread = new Thread(new ImageDownloadTask(path,"d:\\image\\download"));
thread.start();
}
}
//从html代码中获取所有的img标签的src属性
private List<String> parseImagePath(String html) {
List<String> imagePaths = new ArrayList<String>();
Pattern imgPattern = Pattern.compile("<img.*?/>");
Pattern srcPattern = Pattern.compile("<img.*src=([\"|'])(.*?)\\1.*>",Pattern.CASE_INSENSITIVE);
//匹配页面中所有img标签
Matcher matcher = imgPattern.matcher(html);
while(matcher.find()){
//匹配页面中所有img标签
String img = matcher.group();
/*int start = img.indexOf("src=\"");
int end = img.indexOf("\"",start+5);
//System.out.println(start+","+end);
String path = img.substring(start+5,end);*/
//通过匹配出来的img标签,获取img中src属性
Matcher srcMatcher = srcPattern.matcher(img);
if(srcMatcher.find()){
String path=srcMatcher.group(2);
//匹配到src中的值,加入到集合中
imagePaths.add(path);
}
}
return imagePaths;
}
/**
* 加载网络中的html代码
* @return
*/
private String loadHtml(String urlString) {
URL url;
BufferedReader reader = null;
HttpURLConnection connection = null;
try {
url = new URL(urlString);
connection = (HttpURLConnection) url.openConnection();
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String s = null;
StringBuilder sb = new StringBuilder();
while ((s = reader.readLine()) != null) {
sb.append(s);
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}finally{
if(reader!=null){
try {
reader.close();
} catch (IOException e) {}
}
if(connection!=null){
connection.disconnect();
}
}
return "";
}
public static class ImageDownloadTask implements Runnable{
private String urlString;
private String baseDir;
/**
* @param url 网络图片地址
* @param baseDir 保存到本地的文件目录
*/
public ImageDownloadTask(String url,String baseDir) {
this.urlString = url;
this.baseDir = baseDir;
}
@Override
public void run() {
HttpURLConnection httpURLConnection = null;
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
URL url = new URL(this.urlString);
httpURLConnection = (HttpURLConnection) url.openConnection();
input = new BufferedInputStream(httpURLConnection.getInputStream()) ;
//创建图片所保存的文件名 d:\\image\\download\\fadsfadsf234234.gif
File f =new File(this.baseDir,UUID.randomUUID().toString()+".gif");
//d:\\image\\download
if(!f.getParentFile().exists()){
f.getParentFile().mkdirs();
}
output = new BufferedOutputStream(new FileOutputStream(f));
byte[] bs = new byte[1024];
int len = 0;
while((len=input.read(bs))>0){
output.write(bs,0,len);
}
output.flush();
} catch (Exception e) {
e.printStackTrace();
}finally{
if(input!=null){
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(output!=null){
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
httpURLConnection.disconnect();
}
}
}
public static void main(String[] args) {
DownloadImage downloadImage = new DownloadImage("http://127.0.0.1/index.html");
downloadImage.run();
}
}
分享到:
相关推荐
- **网络编程**:Java提供了丰富的网络编程API,如Socket和HttpURLConnection,用于处理HTTP请求和响应,实现网页的下载。 - **多线程**:为了提高下载效率,离线浏览器通常会使用多线程下载不同资源,Java的...
- **输入/输出流**:掌握Java I/O流的概念,用于读取和写入文件或网络数据。 2. **Swing库**: - **JFrame**:作为主窗口,承载所有组件。 - **JPanel**:创建自定义组件区域。 - **JButton**:实现用户交互,...
这个项目描述指出,开发的网页浏览器是用Java语言编写的,这意味着开发者可能使用了Java的标准库,例如JavaFX或Swing来构建用户界面,使用Socket或者HttpURLConnection来进行网络通信。开发者提到运行程序前需要将...
4. **正则表达式与数据提取**:在Java中,`java.util.regex`包提供了正则表达式支持,可用于匹配和提取网页中的特定数据。 5. **数据存储**:爬取的数据通常需要存储,这可能涉及到数据库操作。Java的JDBC(Java ...
- `java.util.regex`:正则表达式处理,如`Pattern`和`Matcher`,用于复杂文本匹配和替换。 4. **集合操作**: - `java.util.ArrayList`、`LinkedList`、`HashSet`、`HashMap`等:这些是Java集合框架的基础,提供...
以上只是Java常用类的一小部分,实际上还有许多其他类和库,如正则表达式Pattern和Matcher,多线程并发工具类CyclicBarrier、CountDownLatch等,这些都是在开发过程中频繁使用的工具。通过深入理解和熟练运用这些类...
正则表达式也是字符串处理的重要部分,Pattern和Matcher类可以实现复杂模式匹配。 4. **日期时间处理**:在Java 8之前,日期时间处理主要依赖于Date、Calendar类,但它们的API设计不够友好。Java 8引入了新的日期...
10. **Java标准库**:例如,日期时间API(java.time包)、正则表达式(java.util.regex包)、XML处理(javax.xml包)等。 虽然无法直接查看压缩包中的具体代码示例,但根据《疯狂Java讲义》的描述,我们可以预期...
2. **网络编程**:Java网络爬虫需要使用Java的Socket编程或者HttpURLConnection类来建立网络连接,发送HTTP请求并接收响应。这部分可能会涉及到URL、URLConnection、HttpClient等API。 3. **HTML解析**:爬虫抓取到...
8. 其他关键类库:Java2还包括了日期时间API(java.time)、数学运算(java.math)、正则表达式(java.util.regex)、国际化(java.text)以及XML处理(javax.xml)等多个领域的重要类库,为开发者提供了全面的支持...
Java的Socket编程或HTTP客户端库(如HttpURLConnection)可以用来连接QQ服务器,发送注册请求,并接收服务器的响应。在发送数据时,需要对敏感信息如密码进行加密,以保证网络安全。服务器通常会对注册信息进行处理...
在Java中,进行网络通信主要通过`java.net`包提供的类,如`URL`、`URLConnection`和`Socket`等。`URL`(统一资源定位符)对象表示网络资源的位置,而`URLConnection`则是连接这些资源的桥梁。 2. **创建URL对象**...
11. **Java标准库的其他部分**:还包括XML处理(`javax.xml`包)、数据库连接(JDBC,`java.sql`包)、国际化(`java.text`和`java.util.Locale`)以及大量的实用工具类(如`java.util.regex`正则表达式和`java.util...
这通常通过正则表达式和其他验证技术实现。 5. **安全性**:为了保护用户信息的安全,密码通常不会以明文形式存储,而是通过哈希算法进行加密。Java提供了多种加密库,如Jasypt或Java Cryptography Extension (JCE)...
5. **数据验证**:为了确保用户输入的有效性,项目中可能包含了数据验证的逻辑,比如邮箱格式检查、密码强度验证等,这可能通过正则表达式或者其他验证库实现。 6. **安全性**:用户密码通常需要加密存储,项目可能...
Java提供了一系列字符串处理方法,如split()、replace()等,以及正则表达式支持。 7. **算法与数据结构**:在比较价格时,可能会使用排序算法(如快速排序、归并排序)来快速找到最低价。此外,使用适当的数据结构...
我们可以使用`java.io.BufferedReader` 读取响应内容,然后使用正则表达式或库如Jsoup(HTML解析)或Jackson/Google Gson(JSON解析)来提取所需的数据。 4. **线程和并发**:如果系统需要实时更新多只股票的信息,...
这可能涉及到字符串处理,如正则表达式,以及可能的对象映射技术,如Jackson或Gson,将JSON数据转化为Java对象。 7. **数据缓存**:为了提高用户体验,应用可能采用缓存策略,将最近查询过的单词和其释义存储在本地...
3. **字符串处理**:String类和StringBuilder/StringBuffer类,以及正则表达式相关方法。 4. **日期时间**:Date、Calendar和java.time包下的新API,用于处理日期和时间。 **三、多线程** 在Java中,多线程是并发...