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

click me

做为一只辛苦的爬虫,我们要跟踪到这个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网址拼接_Python相对完美的URL拼接函数相关推荐

  1. c调用python第三方库_Python使用ctypes模块调用DLL函数之C语言数组与numpy数组传递...

    在Python语言中,可以使用ctypes模块调用其它如C++语言编写的动态链接库DLL文件中的函数,在提高软件运行效率的同时,也可以充分利用目前市面上各种第三方的DLL库函数,以扩充Python软件 ...

  2. python网址正则表达式_python正则表达式抓取图片地址为什么要这样写?

    目标导向: 题主的问题是为什么,我的回答是:看效果: 完整代码: #!/usr/bin/env python import re, requests SAVE_DIR_PATH = 'E:/zhihu ...

  3. python网址正则表达式_python正则表达式验证ipv6地址

    下面是编程之家 jb51.cc 通过网络收集整理的代码片段. 编程之家小编现在分享给大家,也给大家做个参考. def ipv6_addr(addr): ''' Returns True if the ...

  4. python第一次考试_python 全栈开发,Day16(函数第一次考试)

    考试题 Python11 期第二次考试(基础数据类型与函数部分) 考试时长:3个小时 满分:105分 一,选择题(每题2分,共24分) 1.python不支持的数据类型有 A.char B.int C ...

  5. python中输入函数_python – 如何使用输入函数和def函数?

    你从未真正全局定义过x和y.当你执行def tiny_num(x,y)时,你只在函数中定义它. 当你执行tiny_num(x =输入("输入第一个数字: – ")时,y =输入(& ...

  6. python数组求和_Python NumPy中的数组求和函数sum | 坐倚北风

    在Python中可以使用NumPy中的sum函数来进行数值求和,sum方法的格式如下: numpy.sum(a, axis=None, dtype=None, out=None, keepdims=, ...

  7. python打蛇_Python 实现类似PHP的strip_tags函数功能,并且可以自定义设置保留标签...

    最近在研究 Python ,发现用的还是很不习惯,很多PHP里面很简单的功能在Python 里面都得找半天,而且很多功能都得自己实现. 今天做个采集,需要过滤内容中的标签,搞了一下午,貌似终于搞出来了 ...

  8. decode函数python在哪里_Python基础知识——encode和decode函数

    以前我们介绍过,Python2.x中默认的编码的基础类型是unicode编码的类型,在Python3.x才转化为基于unicode的字符串. 那么我们在Python2.x的学习中就会遇到各种各样的编码 ...

  9. python技术介绍_Python编程语言基础技术框架()之函数介绍

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

最新文章

  1. 有趣而又被忽略的Unity技巧
  2. 集合-2(Set(HashSet、TreeSet、LinkedHashSet)、List(ArrayList、LinkedList、Vector)、Map(HashMap、TreeMap...))
  3. 1689: 营救小明(bfs+priority_queue逆向思维)
  4. java thread.sleep 声明_java 线程Thread.Sleep详解(转载)
  5. rabbitmq如何保证消息不丢失_RabbitMQ的去重与防止消息的丢失
  6. oracle 用户禁止登录,[转] oracle限制用户在某个时间段内禁止登录数据库
  7. 好产品改变世界——《人人都是产品经理》即将上市
  8. 《SQL高级应用和数据仓库基础(MySQL版)》学习笔记 ·003【表的约束、表的CRUD操作(DDL语句)】
  9. 一个精心制作的页眉样式
  10. ZYNQ PL开发流程
  11. Oracle 12C 最新补丁下载与安装操作指北
  12. java全栈开发主要工作内容,java全栈工程师
  13. 电子签名的制作和使用
  14. Thymeleaf模板引擎使用详解
  15. 云服务器哪家最好,如何选择云服务器
  16. Android解决滑动冲突
  17. Go 1.9 sync Map 源码阅读笔记
  18. 迅为STM32MP157开发板手册更新记录
  19. 裸金属服务器跟云服务器区别有哪些?裸金属应用在哪些场景中?
  20. 爬虫利器BeautifulSoup之CSS选择器的基本使用

热门文章

  1. 配置公共字段全局填充createTime和updateTime
  2. 地图经纬度坐标相互转换度分秒
  3. JZOJ100029 陪审团
  4. Excel 去除重复项的几种常用技巧
  5. 读书笔记3——《如何高效学习》:斯科特·扬
  6. [二级C]专题习题-二维数组
  7. android app 的后台代码,包括后台的Android美食APP项目开源代码
  8. html中怎么设置渐变颜色设置,css中渐变色怎么设置
  9. C# break和continue用法
  10. JavaScript 简单学习