使用HttpParser类解析网页
Posted Lingdu丶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用HttpParser类解析网页相关的知识,希望对你有一定的参考价值。
之前发过一篇文章:利用String类制作简单的网络爬虫
这是是基于String类里的substring()方法对字符串进行截取,从而得到想要的内容。
这种方法如果只是截取简单数据的话,还是可以实现的。
但是如果我要获取指定的数据(这个数据可能成千上万条),这时后用String类里面的方法就会很麻烦,而且要编写的代码会变的非常多。
现在我们要引用一个网页解析的工具类来帮助我们更方便的解析网页。
下载 HtmlParser类
官方地址:http://htmlparser.sourceforge.net/
在线API文档:http://htmlparser.sourceforge.net/javadoc/index.html
进去htmlparser下载1.6的版本
下载完成之后解压缩出来
导入jar包
右键单击项目
创建一个Folder ,名字为 lib
将 htmlparser.jar 拷贝进去
右键项目->Properties->java Build Path
添加一个jar包
最后OK就可以了
在代码上创建一个 Parser 对象试试看看行不行
这样就把引用了网上下载的jar包,现在就可以对网页进行解析了。
解析网页
这里随便找个 电影网站 来进行测试
获取单个视频的下载链接
- 进去 日韩电影 这里
然后随便打开一个 电影 标题,我这里就选择第一个
- 打开之后发现这个页面是介绍 电影的
/20170129/53099.html
F12进去调试模式
- 分析下载地址
发现整个页面就只有一个ftp的标识
ftp://ygdy8:ygdy8@y219.dydytt.net:9239/[阳光电影www.ygdy8.com].蜡笔小新:梦境世界大突击.BD.720p.日国粤三语中字.mkv
发现了规律之后,那我们是不是只提取含有ftp开头的字符串就可以了呢?
- 代码实现
/**
*获取电影的下载地址
*/
public static void test1() {
try {
Parser parser = new Parser("http://www.dytt8.net/html/gndy/dyzz/20170208/53190.html");
//提取所有匹配的节点保存到节点列表
//LinkStringFilter("ftp") 节点字符串过滤器,过滤所有包涵 "ftp" 的字符串
NodeList nodeList = parser.extractAllNodesThatMatch(new LinkStringFilter("ftp"));
//遍历节点列表
for (int i = 0; i < nodeList.size(); i++) {
//将节点列表的第一个元素保存到标签里
LinkTag tag = (LinkTag) nodeList.elementAt(i);
//打印标签
System.out.println(tag.getLink());
}
} catch (ParserException e1) {
e1.printStackTrace();
}
}
运行之后确实是获取到下载地址
2、获取单个列表里面所有的电影介绍页地址
我们知道每个电影的介绍页面都是不同的网页
比如刚刚的页面,它的后缀是:/html/gndy/dyzz/20170129/53099.html
分析一下页面源码:http://www.dytt8.net/html/gndy/dyzz/index.html
发现这个列表是在table里面的
每行都有一个电影的各种信息
那我们能不能获取一下每个页面的介绍地址呢?
“/html/gndy/dyzz/20170129/53099.html”
首先还是一样,分析一下规律
查找内容时发现在当前table下每个a标签都有一个class属性是“ulink”
发现了规律之后我们就用代码实现一下吧
- 代码实现
/**
* http://www.ygdy8.net/html/gndy/dyzz/index.html
* 从网页里获取25个电影的介绍地址
*/
public static void test2() {
try {
Parser parser = new
Parser("http://www.ygdy8.net/html/gndy/dyzz/index.html");
//过滤所有class属性是"ulink"的标签
NodeList nodeList = parser.extractAllNodesThatMatch(new
HasAttributeFilter("class","ulink"));
System.out.println("找到:" + nodeList.size() + "条数据。");
for (int i = 0; i < nodeList.size(); i++) {
//拿到节点的链接标签
LinkTag tag = (LinkTag) nodeList.elementAt(i);
System.out.println(tag.getLink());
}
} catch (ParserException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
这样就拿到个每个介绍页面的链接
3、 获取所有的列表页面
刚刚第2步的时候已经拿到单个列表页面的所有介绍页面,那我们也可以获取所有的列表页面
同样,分析一下网页源码,找一下规律
查找option标签可以发现 有161条数据
再过滤一下里option包涵有value属性的总共有159个,因为前两个不是列表标签,所以找到的总共有157个
知道了规律之后,我们就可以获取了
- 代码实现
/**
* http://www.ygdy8.net/html/gndy/dyzz/index.html
* 从网页获取157个电影分页的地址
*/
public static void test3() {
try {
Parser parser = new Parser("http://www.ygdy8.net/html/gndy/dyzz/index.html");
//获取所有包涵value属性的option标签
NodeList nodeList = parser.extractAllNodesThatMatch(
new TagNameFilter("option")).extractAllNodesThatMatch(
new HasAttributeFilter("value"));
//System.out.println("找到:" + nodeList.size() + "条数据。");
for (int i = 0; i < nodeList.size(); i++) {
//拿到第i个元素
OptionTag tag = (OptionTag) nodeList.elementAt(i);
//如果获取带有value属性的标签,并且标签里面包涵有list内容
if (tag.getAttribute("value").contains("list")) {
System.out.println(tag.getAttribute("value"));
}
}
} catch (ParserException e1) {
e1.printStackTrace();
}
这样就成功拿到了所有的列表
实战
现在我要把这三个方法整合起来:
1、 获取到所有列表
2、 遍历每个列表的介绍页面
3、 通过介绍页面获取下载地址
完整源码
package com.lingdu.htmlparser;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
public class HtmlParserDemo {
/**
* 保存电影下载地址
* @param i 第i条数据
* @param content 内容
* @param pathName 保存路径
*/
public static void saveMovieDownloadAddress(int i, String content, String pathName) {
if (!pathName.equals("")) {
File fileName = new File(pathName);
try {
PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName,true),"UTF-8")));
pw.println(i + " : " + content);
pw.flush();
pw.close();
System.out.println("保存------>" + content + " 成功!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
/**
* 3、通过介绍地址获取电影的下载地址
*/
public static List<String> getDownloadUrl(String movieUrl) {
List<String> list = new ArrayList<String>();
try {
Parser parser = new Parser("http://www.ygdy8.net" + movieUrl);
//提取所有匹配的节点保存到节点列表
//LinkStringFilter("ftp") 节点字符串过滤器,过滤所有包涵 "ftp" 的字符串
NodeList nodeList = parser.extractAllNodesThatMatch(new LinkStringFilter("ftp"));
//遍历节点列表
for (int i = 0; i < nodeList.size(); i++) {
//将节点列表的第一个元素保存到标签里
LinkTag tag = (LinkTag) nodeList.elementAt(i);
//打印标签
//System.out.println(tag.getLink());
list.add(tag.getLink());
}
} catch (ParserException e1) {
e1.printStackTrace();
}
return list;
}
/**
* 2、从网页里获取所有电影的介绍地址
*/
public static List<String> getAllMoviePageFromOneList(String oneListUrl) {
//保存所有电影的介绍地址
List<String> list = new ArrayList<String>();
try {
Parser parser = new Parser("http://www.ygdy8.net/html/gndy/dyzz/" + oneListUrl);
NodeList nodeList = parser.extractAllNodesThatMatch(new HasAttributeFilter("class","ulink"));
System.out.println("找到:" + nodeList.size() + "条数据。");
for (int i = 0; i < nodeList.size(); i++) {
//拿到节点的链接标签
LinkTag tag = (LinkTag) nodeList.elementAt(i);
//System.out.println(tag.getLink());
list.add(tag.getLink());
}
} catch (ParserException e1) {
e1.printStackTrace();
}
return list;
}
/**
* 1、从网页获取电影的分页的地址
*/
public static List<String> getAllListFromUrl(String url) {
//创建一个list集合用来存放所有的列表页面
List<String> list = new ArrayList<String>();
try {
Parser parser = new Parser(url);
//获取所有包涵value属性的option标签
NodeList nodeList = parser.extractAllNodesThatMatch(
new TagNameFilter("option")).extractAllNodesThatMatch(
new HasAttributeFilter("value"));
//System.out.println("找到:" + nodeList.size() + "条数据。");
for (int i = 0; i < nodeList.size(); i++) {
//拿到第i个元素
OptionTag tag = (OptionTag) nodeList.elementAt(i);
//如果获取带有value属性的标签,并且标签里面包涵有list内容
if (tag.getAttribute("value").contains("list")) {
//System.out.println(tag.getAttribute("value"));
list.add(tag.getAttribute("value"));
}
}
} catch (ParserException e1) {
e1.printStackTrace();
}
//list_23_1.html
return list;
}
/**
* 整合逻辑
* 将所有的方法集合运行
*/
public static void logicIntegration() {
//保存所有的分页列表的页面
List<String> allList = getAllListFromUrl("http://www.ygdy8.net/html/gndy/dyzz/index.html");
//保存所有电影页面地址
List<String> allMoviePageUrl = new ArrayList<String>();
//保存所有电影的下载地址
List<String> allDownloadUrl = new ArrayList<String>();
//统计次数
int i = 0;
for (String str1 : allList) {
System.out.println("\\n页面:-------------------->" + str1 + "--------------------");
allMoviePageUrl = getAllMoviePageFromOneList(str1);
for (String str2 : allMoviePageUrl) {
allDownloadUrl = getDownloadUrl(str2);
for (String str3 : allDownloadUrl) {
i += 1;
//Movie DownLoad Address.txt是文件名,可以自己定义
saveMovieDownloadAddress(i,str3,"Movie DownLoad Address.txt");
//System.out.println(str3);
}
}
}
}
public static void main(String[] args) {
logicIntegration();
}
}
全部保存完毕!
以上是关于使用HttpParser类解析网页的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )(代码片段