首先说下什么叫URL拼接,我们有这么一个HTML片段:

 
<a href="../../a.html">click me</a>

做为一只辛苦的爬虫,我们要跟踪到这个click me指向的页面,假设这个片段来自:http://www.xxxdu.com,那么目标页面是什么呢?

显然不是

 http://www.xxxdu.com/../../a.html

而是

 http://www.xxxdu.com/a.html
 

第一个结果看着很脑残,但是这就是Python的urljoin给出的结果,按理说urljoin应该解决这个“路径非正规化”(Normalize path )的问题,但是它没有:

>>> from urlparse import urljoin
>>> urljoin("http://www.xxx.com", "../../a.html")
'http://www.xxx.com/../../a.html'

OK,其实这个问题的解决根本不再URL上,因为URL已经拼接了,更准确的描述这个问题应该是路径的正规化,即xxx.com后面的这部分路径,如果我们把它想象成Unix路径,不就是求相对论路径”/../../a.html”的绝对路径么?

我们可以用查找、正则表达式把后面这部分分离出来,更省事的方法是urlparse:

>>> from urlparse import urlparse
>>> urlparse("http://www.xxx.com/../../a.html")
ParseResult(scheme='http', netloc='www.xxx.com', path='/../../a.html', params='', query='', fragment='')
 

上述结果的第2部分, arr[2]就是我们要的path啦。

然后Python提供了Unix路径的正规化函数posixpath.normpath

最后我们把正规化好的path重新组装成url,于是整个函数出炉:

from urlparse import urljoin
from urlparse import urlparse
from urlparse import urlunparse
from posixpath import normpath
 
def myjoin(base, url):
    url1 = urljoin(base, url)
    arr = urlparse(url1)
    path = normpath(arr[2])
    return urlunparse((arr.scheme, arr.netloc, path, arr.params, arr.query, arr.fragment))
 
if __name__ == "__main__":
    print myjoin("http://www.baidu.com", "abc.html")
    print myjoin("http://www.baidu.com", "/../../abc.html")
    print myjoin("http://www.baidu.com/xxx", "./../../abc.html")
    print myjoin("http://www.baidu.com", "abc.html?key=value&m=x")

输出结果:

http://www.baidu.com/abc.html
http://www.baidu.com/abc.html
http://www.baidu.com/abc.html
http://www.baidu.com/abc.html?key=value&m=x

Python相对完美的URL拼接函数的更多相关文章

  1. 接口测试get请求url拼接函数(python)

    get请求地址一般是 协议+域名+端口+路径+参数,除了协议和域名其他均可为空.  http(s)://domain:port/path?key1=value1&key2=value2& ...

  2. 检测一个js写的URL拼接函数

    有时,我看代码不太理解时,直接调用函数进行输出,是很一个不错的习惯. 今天遇到的调试的结果如下. <script> const U = function (opt, url) { var ...

  3. 翻译《Writing Idiomatic Python》(二):函数、异常

    原书参考:http://www.jeffknupp.com/blog/2012/10/04/writing-idiomatic-python/ 上一篇:翻译<Writing Idiomatic ...

  4. 【python】python函数式编程、高阶函数

    1.map() : python内置的高阶函数,接收一个函数f和一个list,并通过把函数f依次作用在list的每个元素上,得到一个新的list并            返回. def f(x): r ...

  5. python全栈开发 生成器 :生成器函数,推导式及生成器表达式

    python 全栈开发 1.生成器函数 2.推导式 3.生成器表达式 一.生成器函数 1.生成器: 生成器的本质就是迭代器 (1)生成器的特点和迭代器一样.取值方式和迭代器一样(__next__(), ...

  6. url拼接

    在做网页抓取的时候经常会遇到一个问题就是页面中的链接是相对链接,这个时候就需要对链接进行url拼接,才能得到绝对链接. url严格按照一定的格式构成,一般为如下5个字段: 详细可参考RFC:http: ...

  7. Python和Java的语法对比,语法简洁上python的确完美胜出

    Python是一种广泛使用的解释型.高级编程.通用型编程语言,由吉多·范罗苏姆创造,第一版发布于1991年.可以视之为一种改良(加入一些其他编程语言的优点,如面向对象)的LISP.Python的设计哲 ...

  8. Flask理论基础(一)视图函数和URL反转函数(url_for)

    一.视图函数 1.1 基本用法试图函数是 app.route 或者 bp.route(蓝图)装饰器装饰的函数.该函数实现了对URL路径的转换,也就是路由功能,例如下面代码定义了默认url ‘/’ 和‘ ...

  9. python数据分析03Python的数据结构、函数和文件

    我们会从Python最基础的数据结构开始:元组.列表.字典和集合.然后会讨论创建你自己的.可重复使用的Python函数.最后,会学习Python的文件对象,以及如何与本地硬盘交互. 3.1 数据结构和 ...

随机推荐

  1. vue - src for components || router(index.js)

    描述:重新编写一个组件 1.1 编写一个PrintName.vue <!--这里是模板 --> <template> <div class="hello&quo ...

  2. ASP.NET WEB API处理流程

    前言:大图请看 http://www.asp.net/posters/web-api/ASP.NET-Web-API-Poster.pdf Web Api Hosting 我们不仅可以通过Web应用程 ...

  3. Python进阶---python strip() split()函数实战(转)

    先看一个例子: >>> ipaddr = 10.122.19.10 File "", line 1 ipaddr = 10.122.19.10 ^ SyntaxE ...

  4. zabbix_get :command not found 解决办法

    zabbix_get 找不到命令是因为没有安装上zabbix_get ,解决办法: 1.yum list all |grep zabbix 返回一个列表,表中出现 zabbix-get.x86_84 ...

  5. 将项目从tomcat 迁移到JBoss5.0

    http://java-boy.iteye.com/blog/531411从Tomcat升级到JBoss5.1真是一个痛苦的过程,可能遇到很多问题.以下是我碰到的问题,及解决方法. 一.Hiberna ...

  6. Task WaitAll的用法

    var tasklst = new List<Task>(); ; i < urls.Count; i++) { tasklst.Add(Task.Factory.StartNew& ...

  7. android:imeOptions属性

    imeOptions软键盘setOnEditorActionListener  默认情况下软键盘右下角的按钮为“下一个”,点击会到下一个输入框,保持软键盘 设置 android:imeOptions= ...

  8. pandas所占内存释放

    df = pd.read_csv('....') 要调用循环处理多个文件时,内存占用情况严重,如果互相之间不需要调用,可以直接del df  释放内存

  9. 经典.net面试题目(转载)

    1. 简述 private. protected. public. internal 修饰符的访问权限. 答 . private :   私有成员, 在类的内部才可以访问. protected : 保 ...

  10. unity, particle play once and destroy

    粒子播放一次后销毁:        //ref: http://answers.unity3d.com/questions/219609/auto-destroying-particle-system ...