函数计算实战-java爬虫程序从指定网站获取图片并存储到对象存储中的例子

简介: 阿里云函数计算推出了Java8版本的Runtime,本文结合一个java的实例完成函数计算的代码编写,该示例主要是模拟一个图片爬虫,把指定网站的指定页面的图片全部获取并保存到对象存储中。

前段时间阿里云函数计算推出了Java8版本的编译环境,我结合一个java语言来完成函数计算的代码编写,该示例主要是模拟一个网站图片爬虫,把指定网站的指定页面的图片全部获取并保存到对象存储中,画了一个简单的架构图如下:

流程讲解:

用户输入某个网站地址,并把爬虫系统部署到函数计算上,执行后函数计算会自动把某网站的图片抓取到本地,并通过内网的方式上传到对象存储(OSS)上。这里涉及到两段代码,一段是网站爬取图片的代码,一段是把图片上传到对象存储(略),我们下面结合上面的框图来看看代码构成。

  •  在函数计算上执行的代码:


/*
 * Created on 2017-9-16
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package com.aliyun.function.crawler;

/**
 * @author fuhw
 * 
 * TODO To change the template for this generated type comment go to Window -
 * Preferences - Java - Code Style - Code Templates
 */
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.StreamRequestHandler;

public class index implements StreamRequestHandler {
	
	private static final String URL = "https://www.csdn.com";
	private static final String ECODING = "UTF-8";
	private static final String IMGURL_REG = "<img.*src=(.*?)[^>]*?>";
	private static final String IMGSRC_REG = "http:\"?(.*?)(\"|>|\\s+)";
	
	@Override public void handleRequest(InputStream inputStream,
			OutputStream outputStream, Context context) throws IOException {
		List<String> imgUrl ;
		try {
			catchImg cm = new catchImg();
			String HTML = cm.getHTML(URL);
			imgUrl = cm.getImageUrl(HTML);
			List<String> imgSrc = cm.getImageSrc(imgUrl);
			cm.Download(imgSrc);	
		} catch (Exception e) {
			System.out.println("fail download image! ");
		}

		outputStream.write("download image is OK!".getBytes());
	}
}

  •  爬虫系统代码:
package com.aliyun.function.crawler;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class catchImg {

	// 地址
	private static final String URL = "http://www.csdn.net";

	// 编码
	private static final String ECODING = "UTF-8";

	// 获取img标签正则
	private static final String IMGURL_REG = "<img.*src=(.*?)[^>]*?>";

	// 获取src路径的正则
	private static final String IMGSRC_REG = "http:\"?(.*?)(\"|>|\\s+.(gif|png|jpg|bmp|jpeg|tif|tiff))";
	
	public static void main(String[] args) throws Exception {
		catchImg cm = new catchImg();
		//获得html文本内容
		String HTML = cm.getHTML(URL);
		//获取图片标签
		List<String> imgUrl = cm.getImageUrl(HTML);
		//获取图片src地址
		List<String> imgSrc = cm.getImageSrc(imgUrl);
		//下载图片
		cm.Download(imgSrc);
	}

	/***************************************************************************
	 * 获取HTML内容
	 * 
	 * @param url
	 * @return
	 * @throws Exception
	 */
	public String getHTML(String url) throws Exception {
		URL uri = new URL(url);
		URLConnection connection = uri.openConnection();
		InputStream in = connection.getInputStream();
		byte[] buf = new byte[1024];
		int length = 0;
		StringBuffer sb = new StringBuffer();
		while ((length = in.read(buf, 0, buf.length)) > 0) {
			sb.append(new String(buf, ECODING));
		}
		in.close();
		return sb.toString();
	}

	/***************************************************************************
	 * 获取ImageUrl地址
	 * 
	 * @param HTML
	 * @return
	 */
	public List<String> getImageUrl(String HTML) {
		Matcher matcher = Pattern.compile(IMGURL_REG).matcher(HTML);
		List<String> listImgUrl = new ArrayList<String>();
		while (matcher.find()) {
			listImgUrl.add(matcher.group());
		}
		return listImgUrl;
	}

	/***************************************************************************
	 * 获取ImageSrc地址
	 * 
	 * @param listImageUrl
	 * @return
	 */
	public List<String> getImageSrc(List<String> listImageUrl) {
		List<String> listImgSrc = new ArrayList<String>();
		for (String image : listImageUrl) {
			Matcher matcher = Pattern.compile(IMGSRC_REG).matcher(image);
			while (matcher.find()) {
				String str = matcher.group().substring(0,
						matcher.group().length() - 1);
				listImgSrc.add(str);
			}
		}
		return listImgSrc;
	}

	/***************************************************************************
	 * 下载图片
	 * 
	 * @param listImgSrc
	 */
	public void Download(List<String> listImgSrc) {
		try {
			//System.out.println("listImgSrc size = "+listImgSrc.size());
			for (String url : listImgSrc) {
				String imageName = url.substring(url.lastIndexOf("/") + 1, url
						.length());
				URL uri = new URL(url);
				InputStream in = uri.openStream();
//				FileOutputStream fo = new FileOutputStream("/tmp/"
				FileOutputStream fo = new FileOutputStream(""
						+ new File(imageName));
				byte[] buf = new byte[1024];
				int length = 0;
				System.out.println("Start : " + url);
				while ((length = in.read(buf, 0, buf.length)) != -1) {
					fo.write(buf, 0, length);
				}
				in.close();
				fo.close();
				//System.out.println("success");
			}
		} catch (Exception e) {
			//e.printStackTrace();
			//System.out.println("fail download in void Download function");
		}
	}
}
  • 注意事项:

1、在本地java环境调试代码的时候,工程里需要引入两个包:

1)aliyun-java-sdk-fc包:http://search.maven.org/#search%7Cga%7C1%7Caliyun-java-sdk-fc

2)fc-java-core包:http://search.maven.org/#search%7Cga%7C1%7Cfc-java-core

2、把图片上传到OSS的代码参考:https://help.aliyun.com/document_detail/32013.html

3、在控制台上的程序入口书写: com.aliyun.function.crawler.index::handleRequest,格式是:包名+入口文件名::入口函数名

4、由于java是编译类型的程序,需要本地编译好后打成jar包通过函数计算控制台上传到远程,打jar包可以通过两种方式,一种可以在eclipse操作界面:

一种通过Java命令行打jar包:jar -cvf fc.jar catchImg.class index.class


5、在编写函数计算的时候,需要注意两个地方,一个是java的运行环境不能直接通过在线编译的方式来做,另外,函数入口名的书写,看下图的标注:


  • 执行看效果




相关实践学习
【玩转ComfyUI】基于函数计算一键部署AI生图平台ComfyUI
本次实验将带大家通过使用阿里云产品函数计算FC,快速使用ComfyUI实现更高质量的图像生成。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
目录
相关文章
|
10月前
|
数据采集 弹性计算 Kubernetes
单机扛不住,我把爬虫搬上了 Kubernetes:弹性伸缩与成本优化的实战
本文讲述了作者在大规模爬虫项目中遇到的挑战,包括任务堆积、高失败率和成本失控。通过将爬虫项目迁移到Kubernetes并使用HPA自动伸缩、代理池隔离和Redis队列,作者成功解决了这些问题,提高了性能,降低了成本,并实现了系统的弹性伸缩。最终,作者通过这次改造学到了性能、代理隔离和成本控制的重要性。
310 2
单机扛不住,我把爬虫搬上了 Kubernetes:弹性伸缩与成本优化的实战
|
9月前
|
数据采集 Web App开发 数据安全/隐私保护
实战:Python爬虫如何模拟登录与维持会话状态
实战:Python爬虫如何模拟登录与维持会话状态
|
9月前
|
数据采集 运维 监控
爬虫与自动化技术深度解析:从数据采集到智能运维的完整实战指南
本文系统解析爬虫与自动化核心技术,涵盖HTTP请求、数据解析、分布式架构及反爬策略,结合Scrapy、Selenium等框架实战,助力构建高效、稳定、合规的数据采集系统。
1305 62
爬虫与自动化技术深度解析:从数据采集到智能运维的完整实战指南
|
9月前
|
数据采集 机器学习/深度学习 人工智能
反爬虫机制深度解析:从基础防御到高级对抗的完整技术实战
本文系统阐述了反爬虫技术的演进与实践,涵盖基础IP限制、User-Agent检测,到验证码、行为分析及AI智能识别等多层防御体系,结合代码实例与架构图,全面解析爬虫攻防博弈,并展望智能化、合规化的发展趋势。
3007 62
反爬虫机制深度解析:从基础防御到高级对抗的完整技术实战
|
11月前
|
数据采集 JSON Java
Java爬虫获取1688店铺所有商品接口数据实战指南
本文介绍如何使用Java爬虫技术高效获取1688店铺商品信息,涵盖环境搭建、API调用、签名生成及数据抓取全流程,并附完整代码示例,助力市场分析与选品决策。
|
9月前
|
数据采集 监控 数据库
Python异步编程实战:爬虫案例
🌟 蒋星熠Jaxonic,代码为舟的星际旅人。从回调地狱到async/await协程天堂,亲历Python异步编程演进。分享高性能爬虫、数据库异步操作、限流监控等实战经验,助你驾驭并发,在二进制星河中谱写极客诗篇。
Python异步编程实战:爬虫案例
|
10月前
|
数据采集 存储 XML
Python爬虫技术:从基础到实战的完整教程
最后强调: 父母法律法规限制下进行网络抓取活动; 不得侵犯他人版权隐私利益; 同时也要注意个人安全防止泄露敏感信息.
1090 19
|
9月前
|
数据采集 人工智能 JSON
Prompt 工程实战:如何让 AI 生成高质量的 aiohttp 异步爬虫代码
Prompt 工程实战:如何让 AI 生成高质量的 aiohttp 异步爬虫代码
|
11月前
|
数据采集 存储 NoSQL
Scrapy 框架实战:构建高效的快看漫画分布式爬虫
Scrapy 框架实战:构建高效的快看漫画分布式爬虫
|
10月前
|
数据采集 Web App开发 机器学习/深度学习
Selenium爬虫部署七大常见错误及修复方案:从踩坑到避坑的实战指南
本文揭秘Selenium爬虫常见“翻车”原因,涵盖浏览器闪退、元素定位失败、版本冲突、验证码识别等七大高频问题,结合实战案例与解决方案,助你打造稳定高效的自动化爬虫系统,实现从“能用”到“好用”的跨越。
1176 0

相关产品

  • 函数计算