จะเข้าร่วม URL แบบสัมบูรณ์และแบบสัมพัทธ์ได้อย่างไร


109

ฉันมีสอง URL:

url1 = "http://127.0.0.1/test1/test2/test3/test5.xml"
url2 = "../../test4/test6.xml"

ฉันจะรับ url สัมบูรณ์สำหรับ url2 ได้อย่างไร



คำตอบ:


222

คุณควรใช้urlparse.urljoin :

>>> import urlparse
>>> urlparse.urljoin(url1, url2)
'http://127.0.0.1/test1/test4/test6.xml'

ด้วย Python 3 (โดยที่urlparse เปลี่ยนชื่อเป็น urllib.parse ) คุณสามารถใช้มันได้ดังต่อไปนี้ :

>>> import urllib.parse
>>> urllib.parse.urljoin(url1, url2)
'http://127.0.0.1/test1/test4/test6.xml'

5
เราใช้urljoinกับพารามิเตอร์ 3 หรือโหมดอย่างไรหรือคุณแนะนำไลบรารีใดสำหรับสิ่งนี้
Mesut Tasci

@mesuutt พยายามสร้างลูปและเข้าร่วมแต่ละส่วนด้วย URL ที่เข้าร่วมก่อนหน้านี้
Cédric Julien

2
@ CédricJulien: การวนซ้ำธรรมดาจะไม่ทำงานเนื่องจากเส้นทางใด ๆ ที่มี/แกนนำจะ "รีเซ็ต" และส่งคืนแบบแผน + netloc + lasturl:urlparse.urljoin('http://www.a.com/b/c/d', '/e') => 'http://www.a.com/e'
MestreLion

หากใช้ urljoin แสดงว่ามีปัญหา ตัวอย่างเช่น urljoin('http://www.a.com/', '../../b/c.png')ผลที่ได้คือแต่ไม่'http://www.a.com/../../b/c.png' http://www.a.com/b/c.pngมีวิธีใดบ้างที่จะได้รับhttp://www.a.com/b/c.png?
bigwind

1
ลิงก์ไปยังเอกสาร Python 3 ชี้ไปที่เอกสาร Python 2 จำเป็นต้องอัปเดตในคำตอบคือdocs.python.org/3.6/library/…
รุนแรง

9

หากเส้นทางสัมพัทธ์ของคุณประกอบด้วยหลายส่วนคุณจะต้องเชื่อมต่อแยกกันเนื่องจากurljoinจะแทนที่เส้นทางสัมพัทธ์ไม่ใช่เข้าร่วม posixpathวิธีที่ง่ายที่สุดที่จะทำคือการใช้

>>> import urllib.parse
>>> import posixpath
>>> url1 = "http://127.0.0.1"
>>> url2 = "test1"
>>> url3 = "test2"
>>> url4 = "test3"
>>> url5 = "test5.xml"
>>> url_path = posixpath.join(url2, url3, url4, url5)
>>> urllib.parse.urljoin(url1, url_path)
'http://127.0.0.1/test1/test2/test3/test5.xml'

ดูเพิ่มเติม: วิธีรวมส่วนประกอบของเส้นทางเมื่อคุณสร้าง URL ใน Python


7
es = ['http://127.0.0.1', 'test1', 'test4', 'test6.xml']
base = ''
map(lambda e: urlparse.urljoin(base, e), es)

3
วิธีที่ดีในการสนับสนุนรายการค่า คุณสามารถลบผลข้างเคียงของคุณ (ตัวแปร "ฐาน" ของคุณ) โดยใช้การลด reduce(lambda a, b: urlparse.urljoin(a, b), es) แผนที่คือlist[n] - to -> list[n]A ลดคือlist[n] - to -> a calculated value
Peter Perron

5
>>> from urlparse import urljoin
>>> url1 = "http://www.youtube.com/user/khanacademy"
>>> url2 = "/user/khanacademy"
>>> urljoin(url1, url2)
'http://www.youtube.com/user/khanacademy'

เรียบง่าย


3

สำหรับ python 3.0+ วิธีเข้าร่วม URL ที่ถูกต้องคือ:

from urllib.parse import urljoin
urljoin('https://10.66.0.200/', '/api/org')
# output : 'https://10.66.0.200/api/org'

1

คุณสามารถใช้reduceเพื่อบรรลุวิธีการของ Shikhar ในแบบที่สะอาดกว่า

>>> import urllib.parse
>>> from functools import reduce
>>> reduce(urllib.parse.urljoin, ["http://moc.com/", "path1/", "path2/", "path3/"])
'http://moc.com/path1/path2/path3/'

โปรดสังเกตว่าด้วยวิธีนี้แต่ละส่วนควรมีเครื่องหมายทับไปข้างหน้าโดยไม่มีเครื่องหมายทับข้างหน้า (เพื่อระบุว่าเป็นส่วนของเส้นทางที่กำลังเชื่อมต่อ) สิ่งนี้ถูกต้อง / ให้ข้อมูลมากกว่าโดยบอกคุณว่าpath1/เป็นส่วนของเส้นทาง URI ไม่ใช่เส้นทางแบบเต็ม/path1/หรือไม่รู้จักpath1ซึ่งอาจเป็นได้ (และถือว่าเป็นเส้นทางแบบเต็ม)

หากคุณต้องการเพิ่มลง/ในส่วนที่ขาดคุณสามารถทำได้:

uri = uri if uri.endswith("/") else f"{uri}/"

หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับความละเอียด URI Wikipediaมีตัวอย่างที่ดี

อัพเดต

เพียงแค่สังเกตว่า Peter Perron แสดงความคิดเห็นเกี่ยวกับการลดคำตอบของ Shikhar แต่ฉันจะทิ้งสิ่งนี้ไว้ที่นี่เพื่อสาธิตวิธีการทำ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.