网络爬虫系列之二:对下载页面进行链接解析
来源:互联网 发布:搜狗大数据 编辑:程序博客网 时间:2024/05/22 11:49
在我的上一篇博客中,通过URL就已经成功下载了第一个页面。然后我第二步的工作就是要通过这个已经下载好的页面得到更多的URL。
在这篇博客中主要完成了对页面中的链接进行解析,并将它们拼成可以访问的样子。更多细致的工作需要在后面进行完善。
事实上,这个步骤并不一定需要依靠程序来完成。或许我们可以通过人工来完成这个步骤。甚至通过人工操作,我们可以得到更加相关的链接。但这对于我这样的程序员而言确实是太麻烦了,所以,我想我需要一个程序来帮我完成第二部分,就是从已经下载好的页面中获得新的URL链接。
完成这个步骤之后,就可以从上一篇博客的例子中进行页面的下载,并将下载后的页面读取之后进行页面内链接的提取,再下载,再提取,照这样下去,理论上来说就拥有了整个互联网上的所有页面了。
显而易见,下一步,也就是下一篇博客的内容就是讲这两个步骤整合到一个体系中,让它自己完成爬取工作了。
一、部分代码解析
1、使用正则表达式来匹配需要的链接
Pattern p = Pattern.compile("<a\\s+href\\s*=\\s*\"?(.*?)[\"|>]",Pattern.CASE_INSENSITIVE);Matcher m = p.matcher(pageContents.toString());
通过上面这一小段代码可以将页面中"<a href="xxx.xxx">"中xxx.xxx匹配出来。
比如说,匹配http://www.csu.edu.cn/,可以得到如下结果:总计35条
... ...3:xxgk.htm4:jgsz.htm5:http://rsc.its.csu.edu.cn/6:jyjx.htm......32:http://news.its.csu.edu.cn/readnewsarticle?atcid=2014040111305185333:http://news.its.csu.edu.cn/readnewsarticle?atcid=2014040208441541834:http://news.its.csu.edu.cn/readnewsarticle?atcid=2014040115060587235:
2、可以看到结果中存在空的链接和重复的链接等可能是不需要的链接(如:第35条),所以还必须在代码中进行判断。(筛选后剩下32条)
3、并且其中有一部分链接地址是相对链接,是不能够直接访问到资源的,如:jgsz.htm,这样的链接必须在前面加上域名、端口等。。
二、程序源代码
package csdnBlog;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.net.MalformedURLException;import java.net.URL;import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * 此类用于解析页面中存在的链接 * * @author <span style="color:blue"><b>胡征南</b></span> * */public class RetrieveLinks {public static void main(String[] args) {String urlString = "http://www.csu.edu.cn/";List<String> links = retrieveLinks(urlString);for (int i = 0; i < links.size(); i++) {System.out.println(i + 1 + ":" + links.get(i));}}/** * 解析链接 * * @param urlString * @return */public static ArrayList<String> retrieveLinks(String urlString) {URL url = null;try {url = new URL(urlString);} catch (MalformedURLException e1) {e1.printStackTrace();}// 判断链接是否已经存在HashSet<String> crawledList = new HashSet<String>();StringBuffer pageContents = new StringBuffer();try {String fileName = "download.html";FileInputStream fis = new FileInputStream(fileName);byte[] buffer = new byte[1204];while (fis.read(buffer) != -1) {String temp = new String(buffer, "utf-8");pageContents.append(temp);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}// 正则表达式校验Pattern p = Pattern.compile("<a\\s+href\\s*=\\s*\"?(.*?)[\"|>]",Pattern.CASE_INSENSITIVE);Matcher m = p.matcher(pageContents.toString());// 用于保存查找到的链接ArrayList<String> linkList = new ArrayList<String>();while (m.find()) {String link = m.group(1).trim();// 判断链接是否合法if (link.length() < 1) {continue;}if (link.charAt(0) == '#') {continue;}// 判断链接是否已经存在if (crawledList.contains(link)) {continue;}crawledList.add(link);// 将相对地址添加完整if (link.indexOf("://") == -1) {link = "http://" + url.getHost()+ (url.getPort() == -1 ? "" : ":" + url.getPort())+ "/" + link;}linkList.add(link);}return linkList;}}
三、运行截图
图1. 控制台运行截图
图2. 工程目录截图
通过这种方式,就可以从已经下载好的页面中获得更多的链接了。
-------------------------------------------------------------------分割线,2014年4月16日更新--------------------------------------------------------------------------
1、将判断绝对地址的方式改为了使用正则表达式判断
更新代码如下:
package csdnBlog;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.net.MalformedURLException;import java.net.URL;import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * 此类用于解析页面中存在的链接 * * @author <span style="color:blue"><b>胡征南</b></span> * */public class RetrieveLinks {public static void main(String[] args) {String urlString = "http://www.163.com/";List<String> links = retrieveLinks(urlString);for (int i = 0; i < links.size(); i++) {System.out.println(i + 1 + ":" + links.get(i));}}/** * 解析链接 * * @param urlString * @return */public static ArrayList<String> retrieveLinks(String urlString) {URL url = null;try {url = new URL(urlString);} catch (MalformedURLException e1) {e1.printStackTrace();}// 判断链接是否已经存在HashSet<String> crawledList = new HashSet<String>();StringBuffer pageContents = new StringBuffer();try {String fileName = Utils.urlToFileName(urlString);FileInputStream fis = new FileInputStream(fileName);byte[] buffer = new byte[1204];while (fis.read(buffer) != -1) {String temp = new String(buffer, "utf-8");pageContents.append(temp);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}// 正则表达式校验Pattern p = Pattern.compile("<a\\s+href\\s*=\\s*\"?(.*?)[\"|>]",Pattern.CASE_INSENSITIVE);Matcher m = p.matcher(pageContents.toString());// 用于保存查找到的链接ArrayList<String> linkList = new ArrayList<String>();while (m.find()) {String link = m.group(1).trim();// 判断链接是否合法if (link.length() < 1) {continue;}if (link.charAt(0) == '#') {continue;}// 判断链接是否已经存在if (crawledList.contains(link)) {continue;}crawledList.add(link);// 将相对地址添加完整// (\w+\.){2}\w+Pattern p2 = Pattern.compile("(\\w+\\.){2}\\w+");Matcher m2 = p2.matcher(link);if (!m2.find()) {link = "http://" + url.getHost()+ (url.getPort() == -1 ? "" : ":" + url.getPort())+ link;}if (link.indexOf("http://") == -1 && link.indexOf("https://") == -1) {link = "http://" + link;}linkList.add(link);}return linkList;}}
其中使用到的工具类可以在第一篇博客中找到。。点此返回上一篇博客。。
相关代码资源下载地址:http://download.csdn.net/detail/huzhengnan/7203185
- 网络爬虫系列之二:对下载页面进行链接解析
- HelloWorld系列之--------手动下载网络页面
- 爬虫之页面链接获取
- 网络爬虫之链接网页
- Java爬虫系列之二网页解析【爬取知乎首页信息】
- 网络爬虫之建立socket链接
- 网络爬虫之简单链接抓取
- PHP爬虫之解析页面的方法
- R网络爬虫之批量下载
- R网络爬虫之表格下载
- 【Python爬虫系列】内容解析之BeautifulSoup
- 测试之道--网络爬虫系列1
- 当路町-网络下载应用系列之三-认识磁力链接Magnet URL
- 网络爬虫系列之三:简单爬虫初步
- java网络爬虫——下载页面图片
- WebCollector下载整站页面(JAVA网络爬虫)
- Python网络爬虫对知乎首页进行爬取
- Python之网络爬虫(二)
- 公钥密码标准(PKCS)
- Boost智能指针——shared_ptr
- ARC & NON-ARC混合编译
- windows 下完全删除oracle
- 经典导航栏02,滑动效果,适合做faq或menu
- 网络爬虫系列之二:对下载页面进行链接解析
- 3 种提高编程技能的有趣方法
- 基类与派生类的构造函数调用问题
- Android编程之手绘 ,画图
- C++编程练习(10)----“图的最小生成树“(Prim算法、Kruskal算法)
- MyEclipse8.5自动提示功能的修改
- 棋牌游戏3D化的趋势
- Cracking the coding interview--Q18.1
- Delphi 7下使用Log4Delphi 0.8日志组件