网络爬虫-如何将相对路径转为绝对路径

最近在写一个蜘蛛程序,碰到了一个问题,就是如何将页面内超链接的相对路径转为绝对路径,Google了一遍,有很多例子,看了一下,全是不太正确的做法,考虑太片面了,它们的做法大致是这样:
如当前页面是:http://localhost:5995/web/index.html
代码如下:

String url = "http://localhost:5995/web/index.html";
int offset = url.lastIndexOf("/");
String cate = url.substring(0, 0ffset + 1);
String absPath = cate + "页面内的相对路径";

上面的代码只是在当前请求的路径不是服务器端的目录时适用,有些站点没有屏蔽对目录的访问,就拿上面的url做例子,当前站点的目录结构如下:
web
├─images
│ ├─logo.gif
│ ├─bg.gif
│ ├─banner.swf
│ └─style.css
├─scripts
│ ├─swfobject.js
│ ├─common.js
│ └─AjaxRequest.js
└─upload
├─201001090001.rar
├─201001090002.rar
├─201001090003.rar
├─201001090004.rar
└─201001090005.rar
假设此站点没有屏蔽对目录的访问,那么在浏览器上请求http://localhost:5995/web/scripts,查看源代码:

目录清单 -- /web/scripts/

--------------------------------------------------------------------------------

[To Parent Directory]

Wednesday, December 16, 2009 12:48 PM 8,670 swfobject.js
Monday, December 07, 2009 05:09 PM 1,450 common.js
Thursday, December 31, 2009 01:54 PM 3,309 AjaxRequest.js


--------------------------------------------------------------------------------
版本信息: ASP.NET Development Server 8.0.0.0

查看源代码:

<html>
<head>
<title>目录清单 -- /web/scripts/</title>
<style>
body {font-family:"Verdana";font-weight:normal;font-size: 8pt;color:black;}
p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px}
b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}
h1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
h2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
pre {font-family:"Lucida Console";font-size: 8pt}
.marker {font-weight: bold; color: black;text-decoration: none;}
.version {color: gray;}
.error {margin-bottom: 10px;}
.expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }
</style>
</head>
<body bgcolor="white">

<h2> <i>目录清单 -- /web/scripts/</i> </h2></span>

<hr width=100% size=1 color=silver>

<PRE>
<A href="/web/">[To Parent Directory]</A>

Wednesday, December 16, 2009 12:48 PM 8,670 <A href="swfobject.js">swfobject.js</A>
Monday, December 07, 2009 05:09 PM 1,450 <A href="common.js">common.js</A>
Thursday, December 31, 2009 01:54 PM 3,309 <A href="AjaxRequest.js">AjaxRequest.js</A>
</PRE>
<hr width=100% size=1 color=silver>

<b>版本信息:</b> ASP.NET Development Server 8.0.0.0

</font>

</body>
</html>

蜘蛛程序分析到"swfobject.js","common.js","AjaxRequest.js"后,如果按上面截取的做法,肯定就错了。这里就不能截取最后的"/",应该是"http://localhost:5995/web/scripts" + "/" + "swfobject.js",但是浏览器为什么能准确分析出来呢?当在页面http://localhost:5995/web/scripts上将鼠标放在超链接[u]swfobject.js[/u]上,状态栏显示了它的绝对路径为http://localhost:5995/web/scripts/swfobject.js而不是http://localhost:5995/web/swfobject.js。于是我猜想,肯定在HTTP响应头信息里有相应的信息,于是用下面的代码测试:


try {
URL base = new URL("http://localhost:5995/web/scripts");
Map<String, List<String>> props = base.openConnection().getHeaderFields();
for (Iterator<String> iterator = props.keySet().iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
System.out.println(key + "=" + props.get(key));
}
} catch (IOException e) {
e.printStackTrace();
}

打印信息如下:

localhost:5995
null=[HTTP/1.1 200 OK]
Date=[Sat, 09 Jan 2010 01:00:25 GMT]
Content-type=[text/html; charset=utf-8]
Content-Length=[1494]
Connection=[Close]
Server=[ASP.NET Development Server/8.0.0.0]

从打印内容里,根本看不出里面有什么东西可以区别目录和html文件的,后来又想,如果用Socket模拟浏览器请求,或许有意想不到的收获呢!先贴代码:

public static void main(String[] args) {
try {
Socket s = new Socket("127.0.0.1", 5995);
OutputStream os = s.getOutputStream();
os.write(("GET /web/scripts HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Connection: keep-alive\r\n" +
"\r\n").getBytes());
os.flush();
InputStream is = s.getInputStream();
int c = -1;
while ((c = is.read()) != -1) {
System.out.print((char)c);
}
os.close();
is.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}

打印信息如下:

HTTP/1.1 302 Found
Server: ASP.NET Development Server/8.0.0.0
Date: Sat, 09 Jan 2010 01:11:42 GMT
Content-Length: 135
Location: /web/scripts/
Connection: Close

<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a href='/website1/scripts/'>here</a>.</h2>
</body></html>

我想不用我说大家都知道了吧?关键在于浏览器第一次请求http://localhost:5995/web/scripts时,服务器给浏览器一个302的响应,告诉浏览器这个资源被移动到别的地方了,你访问这个路径吧:Location: /web/scripts/,于是浏览器再请求http://localhost:5995/web/scripts/这次后面就多了个"/",于是浏览器就知道这个页面内的所有相对路径的超链接的绝对路径了。^_^
现在知道了用URLConnection测试时,它做了二次请求,所以看不到302的响应。
Python的绝对路径是指从文件系统的根目录开始的完整路径,而相对路径是相对于当前工作目录的路径。 要获取当前工作目录的路径,可以使用以下代码: ```python import os print(os.getcwd()) ``` 这将打印出当前工作目录的路径,即相对路径位置。 在Windows中,绝对路径可以直接使用反斜杠作为路径分隔符,例如`E:\python\爬虫课件`。由于反斜杠在Python中被用作转义符,因此在使用Windows的路径标识时,需要在路径前面加上一个`r`,表示原始字符串常量,以保持字符的原始意义,例如`r'E:\python\爬虫课件'`。 相对路径与当前工作目录有关,是相对于当前工作目录的路径。例如,如果当前工作目录是`E:\python`,那么相对路径`爬虫课件`表示的是`E:\python\爬虫课件`。如果当前工作目录是`E:\python\project`,那么相对路径`../爬虫课件`表示的是`E:\python\爬虫课件`。相对路径使用`.`表示当前目录,使用`..`表示上一级目录。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [python绝对路径相对路径](https://blog.csdn.net/weixin_45619473/article/details/124776708)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [python的绝对路径相对路径](https://blog.csdn.net/weixin_42830697/article/details/120015478)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值