网页数据抓取——使用jsoup

时间:2022-10-31 07:41:02
今天有家公司发了一道题目过来,需求是

1.       要求索引系统能够根据演员名字、电视剧名字、关键字、导演、拍摄时间等信息给出索引结果;

2.       从数据源抓取数据建立数据索引系统,请描述该如何建,你会采用什么样的处理方法;

3.       从奇艺网选择一个网页,用java写一个解析器,可以用第三方工具包,解析该网页,把建立数据库需要的信息抓取出来。

于是我就想,使用一个抓取工具,把 [视频名称,上映年份,导演名称,主演名称,制片人的名字,编剧的名字以及该电影的类型(例如悬疑或者言情等),还有这些影片所对应的播放链接] 抓取出来,存入MySQL数据库即可。

以爱奇艺网站某网址为例:http://www.iqiyi.com/dianshiju/20121030/d4c71c9013e203f1.html

首先,在网上找到一个Java的HTML解析器叫jsoup,下载地址如下:

http://jsoup.org/download

找到一个demo地址如下:

http://www.gbin1.com/technology/javautilities/20120720jsoupjquerysnatchpage/

我自己在eclipse中搭建了一下,导入上述地址的两个代码之后,确实可以运行,我需要爱奇艺网址里面两个class的信息,一个叫name_list,一个叫crumb_new。也确实抓取成功了。但是接下来我不知道怎样使用正则表达式把这些抓取出来的内容存入数据库。。。。o(╯□╰)o

-----------------------------------------2013/3/30------------------------------------------------

在demo中,有这样的两句话

Document doc = Jsoup.connect(url).timeout(0).get();
Elements items = doc.select(elem);

从而得到的items进行

items.text()

操作,就可以转变为文本。应该是String格式。


再接着,用正则表达式进行提取就可以啦~

修改过后的代码是这两部分

<!DOCTYPE html>
<html lang="en">
<head>
<title>页面元素自动抓取</title>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Original Hover Effects with CSS3" />
<meta name="keywords" content="css3, transitions, thumbnail, animation, hover, effect, description, caption" />
<meta name="author" content="Terry li - GBin1.com" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var url, element, element2, runid;
$('#start').click(function(){
url = $('#url').val();
element = $('#element').val();
element2 = $('#element2').val();

//Run for first time
$('#msg').html('请耐心等待, 页面抓取中 ...').fadeIn(400);
//$('#content').html('');
$('#content').load('siteproxy.jsp #result', {url:url, elem:element, elem2:element2}, function(){
$('#msg').html('抓取已完成').delay(1500).fadeOut(400);
})
});

$('#stop').click(function(){
$('#msg').html('抓取已暂停').fadeIn(400).delay(1500);
});

});
</script>
<style>
body{
font-size:14px;
line-height: 25px;
background: #fff;
}

ul{
list-style: none outside none;
}

input{
padding: 10px;
margin: 10px;
width: 300px;
font-size:14px;
border: 1px solid #CCC;
}

#element{
width: 100px;
}

#start,#stop{
padding: 8px;
margin: 10px;
width: 100px;
font-size:14px;
background: #303030;
color: #CCC;
}

#msg{
padding: 5px;
margin: 10px;
display: none;
}

.item{
background: #E3E3E3;
padding: 10px;
margin: 10px;
font-size: 14px;
font-family: Arial;
}

a{
text-decoration: none;
}

header{
margin:20px;
padding: 0;
}

h1,h2,h3{
font-size:14px;
font-family: Arial;
}
</style>
</head>
<body>
<div style="float:left"><input type="text" id="url" value="http://www.iqiyi.com/dianshiju/20121030/d4c71c9013e203f1.html"/></div>
<div style="float:left"><input type="text" id="element" value=".crumb_new"/></div>
<div style="float:left"><input type="text" id="element2" value=".name_list"/></div>
<div style="float:left"><input type="button" id="start" value="开始抓取"/></div><div style="float:left"><input type="button" id="stop" value="暂停抓取"/></div><div style="float:left" id="msg"></div>
<div style="clear:both"></div>
<div id="content"></div>
</body>
</html>



<!DOCTYPE html>
<%@ page contentType="text/html; charset=GBK"%>
<%@ page import="org.jsoup.Jsoup" %>
<%@ page import="org.jsoup.nodes.*" %>
<%@ page import="org.jsoup.select.Elements" %>
<%@ page import="java.io.FileWriter" %>
<%@ page import="java.io.BufferedWriter" %>
<head>
<title>jsoup</title>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
</head>

<body>
<header> <h1> 视频信息 </h1> </header>

<ul id="result">
<%
String url = request.getParameter("url");
String elem = request.getParameter("elem");
String elem2 = request.getParameter("elem2");
try{
Document doc = Jsoup.connect(url).timeout(0).get();
// String path = request.getContextPath()+"\info.txt";
FileWriter writer = new FileWriter("D:\\info.txt", true);
BufferedWriter bw = new BufferedWriter(writer);

Elements items = doc.select(elem);
// System.out.println(items.text());
System.out.println(items.text().replaceAll("(.*)首页.*", "$1"));
bw.write("视频名称: "+items.text().replaceAll("(.*)爱奇艺首页.*", "$1"));
bw.newLine();
for (Element item : items) {
Elements links = item.select("a");
for(Element link: links){
link.attr("href",link.attr("abs:href"));
}

Elements imgs = item.select("img");
for(Element img: imgs){
img.attr("src",img.attr("abs:src"));
}
String html = item.html();
out.println("<li class=\"item\">" + html + "</li>");
}

Elements item2s = doc.select(elem2);
bw.write("上映年份: "+item2s.text().replaceAll(".*上映: ([^:]+) [^:]+:.*", "$1"));
bw.newLine();
bw.write("导演: "+item2s.text().replaceAll(".*导演: ([^:]+) [^:]+:.*", "$1"));
bw.newLine();
bw.write("主演: "+item2s.text().replaceAll(".*主演: ([^:]+) [^:]+:.*", "$1"));
bw.newLine();
bw.write("制片人: "+item2s.text().replaceAll(".*制片人: ([^:]+) [^:]+:.*", "$1"));
bw.newLine();
bw.write("编剧: "+item2s.text().replaceAll(".*编剧: ([^:]+) [^:]+:.*", "$1"));
bw.newLine();
bw.write("类型: "+item2s.text().replaceAll(".*类型: ([^:]+) [^:]+:.*", "$1"));
bw.newLine();
System.out.println(item2s.text());
for (Element item : item2s) {
Elements links = item.select("a");
for(Element link: links){
link.attr("href",link.attr("abs:href"));
}

Elements imgs = item.select("img");
for(Element img: imgs){
img.attr("src",img.attr("abs:src"));
}
String html = item.html();
out.println("<li class=\"item\">" + html + "</li>");
}
bw.close();
}catch(Exception e){
e.printStackTrace();
}
%>
</ul>
</body>
</html>





不过,这种提取方法非常的粗粒度,复用性很差,我还需要继续研究出更好的实现方法来。