欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

网络爬虫

程序员文章站 2022-07-05 12:58:52
...

简介

1. 什么是网络爬虫:
网络爬虫(又被称为网也蜘蛛,网络机器人,在FOAF社区中间,更经常称为网页追逐者。)
作用
网络蜘蛛是用过网页的链接地址来寻找网页。
从网站某一个页面(通常是首页)开始,读取网页的内容,找到在网页中的其它链接地址,然后通过这些链接地址寻找下一个网页,这样一直循环下去,直到把这个网站所有的网页都抓取完为止。如果把整个互联网当成一个网站,那么网络蜘蛛就可以用这个原理把互联网上所有的网页都抓取下来。
网络爬虫的思路以及实现
解析网络类资源的方法,通过网络URL,是利用HTTPclient技术,获取网络资源类容。

// 解析网络资源类的方法
	// 用过网络URL,是利用HTTPclient技术,获取网络资源类容
	    //定义需要过滤的文件后缀
	private static String[] fiterUrls = new String[] { ".com/tv/", ".htm" };
	//定义队列(所放的是需要再次解析的URL)
	private static Queue<String> waitForCrawler = new LinkedList<String>();
	//爬取目标的总数
	private static long total = 0;
	public static void parseUrl() {
		while (waitForCrawler.size() > 0) {
			// 摘取队列的url,并摘除掉
			String url = waitForCrawler.poll();
			
			CloseableHttpClient httpClient = HttpClients.createDefault();
			// 获取一个请求
			HttpGet httpGet = new HttpGet(url);
			// 关闭响应
			CloseableHttpResponse response = null;
			try {
				response = httpClient.execute(httpGet);
				HttpEntity entity = response.getEntity();
				// System.out.println(entity.getContentType().toString());
				// System.out.println(entity.getContentType().getValue());
				/**
				 * 获取此类型的url,需要再次解析
				 */
				if ("text/html; charset=GB2312".equals(entity.getContentType().getValue())) {
					/**
					 * 获取网页内容
					 */
					String pageContent = EntityUtils.toString(entity, "utf-8");
					// System.out.println("网页内容"+pageContent);
					parsepageContent(pageContent, url);
				}

			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {

				e.printStackTrace();
			} finally {
				// 关闭资源
				if (response != null) {
					try {
						response.close();
					} catch (IOException e) {
						
						e.printStackTrace();
					}
				}
				if (httpClient != null) {
					try {
						httpClient.close();
					} catch (IOException e) {

						e.printStackTrace();
					}
				}
			}
		}

	}

通过网络爬虫框架对网进行再次解析
1.

private static void parsepageContent(String pageContent, String realDir) {
		// 节点
		Document doc = Jsoup.parse(pageContent);
		//获取节点元素
		Elements aEles = doc.select("a");
		for (Element aEle : aEles) {
			// 获取网页url
			String aHref = aEle.attr("href");
			// System.out.println(aHref);
			// 获取真实url地址
			String url = realDir + aHref;
			System.out.println(url);
			if (url == null || "".equals(url)) {
				return;
			}
			/**
			 * 1目标链接  2 需要过滤的链接 3需要迭代解析的链接
			 */
			boolean f = true;// 假设就是我们需要的目标资源
			/**
			 * 循环遍历所有url
			 */

			for (String filterUrl : fiterUrls) {
				// 如果所遍历的url与你定义不需要的文件后缀,就过滤掉
				if (url.endsWith(filterUrl)) {
					f = false;
					break;
				}
			}
			if (f && url.endsWith(".html")) {
				System.out.println("爬取了第" + (++total) + "个目标文件,url为:" + url);
			     
			} else {
			//需要再次爬取的URL
				addUrl(url);
			}

		}

	}

添加到爬虫队列,等待再次爬取

private static void addUrl(String url) {
		System.out.println(url + "被添加到爬虫队列");
		waitForCrawler.add(url);
	}

初始化方法

public static void init() {
		// String url = "https://www.qq.com/";
		//网络URL被放进队列中,默认一个被解析的网络url
		addUrl("https://www.qq.com/");
		parseUrl();
	}

main方法测试

	public static void main(String[] args) {
		// // 默认一个网页的链接地址
		// String url = "https://www.qq.com/";
		// // 解析url
		// parseUrl(url, url);
		init();
	}

网络爬虫框架所需要的jar包
HTTPclient点击下载
jsoup点击下载
log4j点击下载
引用到你的项目里面就ok了
注意此时的网络爬虫的性能是非常差的。所以进行了进一步优化
利用异步线程池进行优化
1.默人解析爬虫队列的URL(全局变量),创建能存放10个异步线程的线程池

	       public static boolean exeFlag = true;// 默认解析爬虫队列中的url
		// 创建能存放10个异步线程的线程池
		ExecutorService executorService = Executors.newFixedThreadPool(10);

2,使用异步线程池进行逻辑解析

// 使用线程中的线程池中的异步线程解析逻辑
				executorService.execute(new Runnable() {
					@Override
					public void run() {
						while (waitForCrawler.size() > 0) {
							// 摘取队列的url,并以除掉
							String url = waitForCrawler.poll();
							CloseableHttpClient httpClient = HttpClients.createDefault();
							// 获取一个请求
							HttpGet httpGet = new HttpGet(url);
							// 设置连接时间5秒,等待服务器响应数据时间10秒
							RequestConfig config = RequestConfig.custom().setConnectTimeout(5000)
									.setSocketTimeout(10000).build();

							httpGet.setConfig(config);

3,这是逻辑判断的else

	// 获取正在执行爬虫任务的线程数
				if (((ThreadPoolExecutor) executorService).getActiveCount() == 0) {
					exeFlag = false;
					break;
				}

4,为了尽可能避免意外的发生,给点一个休眠时间

	Thread.sleep(1000);
相关标签: 网络蜘蛛