作者sevenheart (啾啾)
看板java
标题[问题] java抓网页内容时,想连超连结那页的内容一起抓
时间Mon Aug 8 02:35:25 2011
在下超弱
希望有人愿意帮我这个忙orz
[愿景]
可以抓首页的原始码
|------------------------------
|
|
|
|------"www.help...."---------- //抓到一半遇到超连结
|=============== //把www.help....的原始码抓起来缩排直接放在下面
|===============
|===============
|------------------------------
|------------------------------
|------------------------------
|------------------------------
[背景]
//这边看不懂应该也没关系
对一个servlet程式
用java的一系列指令
最後用jhat把一个heap的内容呈现在
http://localhost:7000
(直接这样点是看不到东西的,必须开着使用指令的那个command line)
(就我的理解是 : 此时有一个JVM在执行,而我们看的就是他的内容)
[开头]
而这个网页编排相当单纯
所有的超连结都是<a href=" 开头...
於是我的程式试着抓了原本的这页,并放进一个档案中
到这边都没有问题
然後我加上一些条件
让他一遇到某一个指定的超连结
就从下一行开始直接开始抓那个超连结
我天真的想法是
用一个URL的array,第url[0]存首页,直接开
URL[] url = new URL[ MAX_URL ];
BufferedReader[] reader = new BufferedReader[ MAX_URL ];
url[0] = new URL("
http://tw.yahoo.com/");
reader[0] = new BufferedReader( new InputStreamReader( url[0].openStream()
) );
开始拼命读url[0]
while ( ( line = reader[0].readLine() ) != null )
接下来要是遇到指定超连结
就用url[1]去存
目前还在测试阶段,所以整个程式只抓一个指定的超连结
遇到就不管原本的首页(url[0]),直接进去url[1]抓到把超连结抓完再跳出来
[可是]
不清楚为什麽
再抓url[1]的内容时
我永远都只抓的到url[1]那页的"前三列"
抓完他就会回传null了
相当怪异
他不会在eclipse上显示任何有问题的讯息
但是他竟然会在原本我开来跑jhat的那个command line中显示
Exception in thread "Thread-3" java.lang.NumberFormatException: " is not a
valid
hex digit
at com.sun.tools.hat.internal.util.Misc.parseHex(Misc.java:62)
at
com.sun.tools.hat.internal.model.Snapshot.findThing(Snapshot.java:359
)
at
com.sun.tools.hat.internal.model.Snapshot.findClass(Snapshot.java:364
)
at
com.sun.tools.hat.internal.server.ClassQuery.run(ClassQuery.java:42)
at
com.sun.tools.hat.internal.server.HttpReader.run(HttpReader.java:181)
at java.lang.Thread.run(Thread.java:662)
百思不得其解
[徒劳]
用wireshark似乎听不到任何我用这个程式抓localhost时的封包
但是我抓google时就听得到
[我的程式码]
import java.net.MalformedURLException;
import java.net.URL;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.IOException;
public class for_asking
{
public static void main( String args[] )
{
int url_count = 0;
int i , j;
int MAX_URL = 5000;
int scope = 0;
int pos;
boolean START_TO_PARSE;
boolean IS_TEST = false;
String line; //read a line from the current page
String tempStr;
String tag_href = "<a href=";
String tag_end_href = "</a>";
String package_test = "Package test";
String TAB = " ";
String outputFileName = "output.html"; //输出档案名称
////////
try {
URL[] url = new URL[ MAX_URL ];
BufferedReader[] reader = new BufferedReader[ MAX_URL ];
FileWriter fw = new FileWriter(outputFileName);
BufferedWriter bw = new BufferedWriter(fw);
url_count = 0;
url[0] = new URL("
http://localhost:7000/");
reader[0] = new BufferedReader( new InputStreamReader(
url[0].openStream() ) );
while ( ( line = reader[0].readLine() ) != null )
{
START_TO_PARSE = false;
//** (1)先output原本这列
bw.write( line );
//是不是test的package
//我指定要找的超连结是出现在package test的下一列的超连结
pos = line.indexOf( package_test ); //没有超连结会回传-1
if( pos == -1 )
;
else
IS_TEST = true;
if( IS_TEST == true )
{
//**判断这列的html有没有超连结
pos = line.indexOf( tag_href ); //没有超连结会回传-1
//**如果这列没有超联结的话
if( pos == -1 )
continue;
//**如果找到超连结的话
/** (1)output
(2)抓出超连结的字串,用来生成下一层的URL
(3)往下一直找直到把原本Output的这列完全output完
(4)然後进该超连结(DFS),url_count++,scope++
* 读一列,判断有没有超连结
* **如果没有超连结的话
* ***(I)照原本的output
*
* **如果有超连结的话
* ***(I)output
* ***(II)抓出超连结
* ***(III)往下一直找直到把原本这列完全output完
* ***(IV)然後进该超连结(DFS),url_count++,scope++
* DFS
* ***(V)做完跳出来(进入外层的while)
(5)做完DFS跳出来(进入外层的while)
**/
else
{
j = line.indexOf( tag_end_href );
if( j == -1 ) //表示这列超连结没有结束
;//再说= =
else
{
//只找双引号中间
tempStr = line.substring( pos+9 , j-1 );
//** (2)取得新连结的URL(下一层的)
url[ scope+1 ] = new URL( url[scope++] , tempStr );
}
//** (3)接下来要先把这行输出完,刚有可能只是html的原始档乱换行,我们要找到真
正换行的地方(目前也只能处理网址没换列的情况)
for( i = j+4 ; i < line.length() ; ++i )
{
if( line.charAt(i) == '<' )
{
START_TO_PARSE = true;
break;
}
}//end for
//判断一下这列到底结束没,如果还没的话就继续下一列(else)
if( START_TO_PARSE == true )
;
else //原始码中结束一列,画面上该列未完
{
//继续读原始档中的下一列,直到读到下一列的
开头为止(上面scope会先往上加,然後等到正式开始parse的时候才会更新url_count)
while ( ( line = reader[ url_count ]
.readLine() ) != null )
{
bw.write(line+"\n");
//System.out.println(line);
for( i = 0 ; i < line.length() ; ++i )
{
if( line.charAt(i) == '<' )
{
START_TO_PARSE = true;
break;
}
}
if( START_TO_PARSE == true )
break;
}//end while(只要跳出来就代表可以往下了)
}//end else
}//end else(有超连结)
//如果有超连结的话,就要开始parse(经过上面的检查)
if( START_TO_PARSE == true )
{
++url_count;
START_TO_PARSE = false;
BufferedReader tmp = new BufferedReader(
new InputStreamReader(
url[scope].openStream() ) );
while ( ( line = tmp.readLine() ) != null )
{
//System.out.print("shit");
if( line.indexOf("</body>") == -1 ) //没读到最後一列才output
System.out.println(line);
}
--url_count;
--scope;
IS_TEST = false;
}
}//end if(IS_TEST)
//else没有超连结的话就继续抓原始档
}//end while(还没读完整个原始档)
reader[0].close();
bw.close();
fw.close();
} catch (MalformedURLException e) {
System.err.println(e); //ex. no protocol之类的 ...
} catch (IOException e) {
System.err.println(e); // ...
}
}//end main
}
救命阿>"<
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 218.173.162.19