java爬虫抓取动态网页(之前学习j2ee的原理是什么?网络爬虫的搭建原理)
优采云 发布时间: 2022-04-01 08:20java爬虫抓取动态网页(之前学习j2ee的原理是什么?网络爬虫的搭建原理)
之前学习j2ee的构建,基本就完成了。
接下来,我要学习爬虫技术。学习一门技术,首先要知道它是如何工作的。
那么网络爬虫的原理是什么?
网络爬虫是一种自动提取网页的程序。它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成部分。传统爬虫从一个或多个初始网页的URL开始,获取初始网页上的URL。
URL,在抓取网页的过程中,不断地从当前页面中提取新的URL,放入队列中,直到满足系统的某个停止条件。
接下来,我将在记录问题和解决方案的同时研究网络爬虫的实现。加油^_^!!
这里我在网上找了一个demo,先给大家演示一下:下面是一个用Java模拟的程序,把新浪页面上的链接提取出来,存到一个文件里:
package testspider;
/**
* Descriptions
*
* @version 2017年3月31日
* @since JDK1.6
*
*/
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class WebSpider {
public static void main(String[] args) {
URL url = null;
URLConnection urlconn = null;
BufferedReader br = null;
PrintWriter pw = null;
String regex = "http://[\\w+\\.?/?]+\\.[A-Za-z]+";
Pattern p = Pattern.compile(regex);
try {
url = new URL("http://www.sina.com.cn/");
urlconn = url.openConnection();
pw = new PrintWriter(new FileWriter("f:/url.txt"), true);//这里我们把收集到的链接存储在了E盘底下的一个叫做url的txt文件中
br = new BufferedReader(new InputStreamReader(
urlconn.getInputStream()));
String buf = null;
while ((buf = br.readLine()) != null) {
Matcher buf_m = p.matcher(buf);
while (buf_m.find()) {
pw.println(buf_m.group());
}
}
System.out.println("获取成功!");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
pw.close();
}
}
}
创建一个java项目,直接把代码放进去。运行后会抓取新浪所有的url,存放在本地的F:/url.txt
只需选择一个要访问的网址,例如
可以获取图片。这只是爬虫的一个简单实现。接下来,我将深入研究它的实现。
网络爬虫:
开发工具:eclipse JDK1.6
网上找的demo没有使用服务器。所以我不再需要服务器了。也没有涉及数据库。将爬取的信息存储在本地目录中。
首先,构建一个java项目。第一个类根据URL获取对应的网页内容。
package webspilder;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
@SuppressWarnings("deprecation")
public class DownloadPage
{
/**
* 根据URL抓取网页内容
*
* @param url
* @return
*/
public static String getContentFormUrl(String url)
{
/* 实例化一个HttpClient客户端 */
@SuppressWarnings({"resource"})
HttpClient client = new DefaultHttpClient();
HttpGet getHttp = new HttpGet(url);
String content = null;
HttpResponse response;
try
{
/*获得信息载体*/
response = client.execute(getHttp);
HttpEntity entity = response.getEntity();
VisitedUrlQueue.addElem(url);
if (entity != null)
{
/* 转化为文本信息 */
content = EntityUtils.toString(entity);
/* 判断是否符合下载网页源代码到本地的条件 */
if (FunctionUtils.isCreateFile(url))
//&& FunctionUtils.isHasGoalContent(content) != -1
{
FunctionUtils.createFile(FunctionUtils
.getGoalContent(content), url);
}
}
} catch (ClientProtocolException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
} finally
{
client.getConnectionManager().shutdown();
}
return content;
}
}
第二个类将 URL 与正则表达式匹配,下载文件并将其保存在本地。如果有数据库,可以保存在数据库中。
<p>package webspilder;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FunctionUtils
{
/**
* 匹配超链接的正则表达式
*/
private static String pat = "http://([\\w*\\.]*[\\w*])";
private static Pattern pattern = Pattern.compile(pat);
private static BufferedWriter writer = null;
/**
* 爬虫搜索深度
*/
public static int depth = 0;
/**
* 以"/"来分割URL,获得超链接的元素
*
* @param url
* @return
*/
public static String[] divUrl(String url)
{
return url.split("/");
}
/**
* 判断是否创建文件
*
* @param url
* @return
*/
public static boolean isCreateFile(String url)
{
Matcher matcher = pattern.matcher(url);
return matcher.matches();
}
/**
* 创建对应文件
*
* @param content
* @param urlPath
*/
public static void createFile(String content, String urlPath)
{
/* 分割url */
String[] elems = divUrl(urlPath);
StringBuffer path = new StringBuffer();
File file = null;
for (int i = 1; i < elems.length; i++)
{
if (i != elems.length - 1)
{
path.append(elems[i]);
path.append(File.separator);
file = new File("D:" + File.separator + path.toString());
}
if (i == elems.length - 1)
{
Pattern pattern = Pattern.compile("[\\w*\\.]*[\\w*]");
Matcher matcher = pattern.matcher(elems[i]);
if ((matcher.matches()))
{
if (!file.exists())
{
file.mkdirs();
}
String fileName = elems[i];
file = new File("D:" + File.separator + path.toString()
+ File.separator + fileName + ".html");
System.out.println("文件存储路径为:"+"D:" + File.separator + path.toString()
+ fileName + ".html");
try
{
file.createNewFile();
writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(file)));
writer.write(content);
writer.flush();
writer.close();
System.out.println("创建文件成功");
} catch (IOException e)
{
e.printStackTrace();
}
}
}
}
}
/**
* 获取页面的超链接并将其转换为正式的A标签
*
* @param href
* @return
*/
public static String getHrefOfInOut(String href)
{
/* 内外部链接最终转化为完整的链接格式 */
String resultHref = null;
/* 判断是否为外部链接 */
if (href.startsWith("http://"))
{
resultHref = href;
} else
{
/* 如果是内部链接,则补充完整的链接地址,其他的格式忽略不处理,如:a href="#" */
if (href.startsWith("/"))
{
resultHref = "http://www.oschina.net" + href;
}
}
return resultHref;
}
/**
* 截取网页网页源文件的目标内容
*
* @param content
* @return
*/
public static String getGoalContent(String content)
{
int sign = content.indexOf("