函数计算实战-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的运行环境不能直接通过在线编译的方式来做,另外,函数入口名的书写,看下图的标注:


  • 执行看效果




相关实践学习
基于函数计算一键部署掌上游戏机
本场景介绍如何使用阿里云计算服务命令快速搭建一个掌上游戏机。
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
目录
相关文章
|
12天前
|
数据采集 存储 Java
高德地图爬虫实践:Java多线程并发处理策略
高德地图爬虫实践:Java多线程并发处理策略
|
12天前
|
JavaScript Java 测试技术
基于Java的服装品牌的推广及应用网站的设计与实现(源码+lw+部署文档+讲解等)
基于Java的服装品牌的推广及应用网站的设计与实现(源码+lw+部署文档+讲解等)
29 0
|
12天前
|
数据采集 Web App开发 搜索推荐
突破目标网站的反爬虫机制:Selenium策略分析
突破目标网站的反爬虫机制:Selenium策略分析
|
12天前
|
数据采集 中间件 Python
Scrapy爬虫:利用代理服务器爬取热门网站数据
Scrapy爬虫:利用代理服务器爬取热门网站数据
|
12天前
|
网络协议 算法 Java
Java中如何通过代理实现对HTTP2网站的访问?
Java中如何通过代理实现对HTTP2网站的访问?
|
12天前
|
数据采集 网络安全 UED
揭秘豆瓣网站爬虫:利用lua-resty-request库获取图片链接
本文探讨了如何使用Lua的lua-resty-request库和爬虫代理IP技术从豆瓣网站高效获取图片链接。通过定制请求头部和代理服务,可以应对反爬虫机制,提高爬虫的稳定性和匿名性。示例代码展示了一种方法,但实际应用需考虑版权和法律法规。
揭秘豆瓣网站爬虫:利用lua-resty-request库获取图片链接
|
12天前
|
运维 监控 Serverless
Serverless 应用引擎产品使用之在使用阿里云函数计算部署网站时,网站打开不稳定如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
247 1
|
12天前
|
存储 Serverless 网络安全
Serverless 应用引擎产品使用之阿里云函数计算中的Web云函数可以抵抗网站对DDoS攻击如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
12天前
|
弹性计算 监控 Serverless
Serverless 应用引擎操作报错合集之阿里函数计算中调用zip-oss-fc函数返回时候出现错误代码如何解决
Serverless 应用引擎(SAE)是阿里云提供的Serverless PaaS平台,支持Spring Cloud、Dubbo、HSF等主流微服务框架,简化应用的部署、运维和弹性伸缩。在使用SAE过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
Serverless 应用引擎操作报错合集之阿里函数计算中调用zip-oss-fc函数返回时候出现错误代码如何解决
|
12天前
|
数据采集 JavaScript 前端开发
如何判断一个网站是否采取了反爬虫措施
通过观察请求响应、分析请求频率限制和检测JavaScript动态加载来初步判断网站是否使用反爬虫措施。使用Python `requests` 发送请求并检查响应头和内容,寻找验证码、限制信息。尝试短时间内多次请求,看是否被限制。使用Selenium模拟浏览器行为,获取动态加载内容。注意,这些方法仅为初步判断,实际可能需更深入分析,并确保爬取行为合法合规。

热门文章

最新文章

相关产品

  • 函数计算