Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Join multiple components to build a URL

I am trying to build a URL by joining some dynamic components. I thought of using something like os.path.join() BUT for URLs in my case. From research I found urlparse.urljoin() does the same thing. However, it looks like it only take two arguments at one time.

I have the following so far which works but looks repetitive:

    a = urlparse.urljoin(environment, schedule_uri)
    b = urlparse.urljoin(a, str(events_to_hours))
    c = urlparse.urljoin(b, str(events_from_date))
    d = urlparse.urljoin(c, str(api_version))
    e = urlparse.urljoin(d, str(id))
    url = e + '.json'

Output = http://example.com/schedule/12/20160322/v1/1.json

The above works and I tried to make it shorter this way:

url_join_items = [environment, schedule_uri, str(events_to_hours),
                  str(events_from_date), str(api_version), str(id), ".json"]
new_url = ""
for url_items in url_join_items:
    new_url = urlparse.urljoin(new_url, url_items)

Output: http://example.com/schedule/.json

But the second implementation does not work. Please suggest me how to fix this or the better way of doing it.

EDIT 1: The output from the reduce solution looks like this (unfortunately): Output: http://example.com/schedule/.json

like image 342
summerNight Avatar asked Mar 23 '16 21:03

summerNight


People also ask

How do you combine URLs in python?

Use the urljoin method from the urllib. parse module to join a base URL with another URLs, e.g. result = urljoin(base_url, path) . The urljoin method constructs a full (absolute) URL by combining a base URL with another URL.

How do you create a URL in Python?

E.g. urllib. parse. urlunparse(('http', 'example.com', '/path', None, 'a=1', 'fragment')) . This library only gives you the most primitive components to build a valid URL; you have to understand how to assemble those components.


1 Answers

Using join

Have you tried simply "/".join(url_join_items). Does not http always use the forward slash? You might have to manually setup the prefix "https://" and the suffix, though.

Something like:

url = "https://{}.json".format("/".join(url_join_items))

Using reduce and urljoin

Here is a related question on SO that explains to some degree the thinking behind the implementation of urljoin. Your use case does not appear to be the best fit.

When using reduce and urljoin, I'm not sure it will do what the question intends, which is semantically like os.path.join, but for urls. Consider the following:

from urllib.parse import urljoin
from functools import reduce

parts_1 = ["a","b","c","d"]
parts_2 = ["https://","server.com","somedir","somefile.json"]
parts_3 = ["https://","server.com/","somedir/","somefile.json"]

out1 = reduce(urljoin, parts_1)
print(out1)

d

out2 = reduce(urljoin, parts_2)
print(out2)

https:///somefile.json

out3 = reduce(urljoin, parts_3)
print(out3)

https:///server.com/somedir/somefile.json

Note that with the exception of the extra "/" after the https prefix, the third output is probably closest to what the asker intends, except we've had to do all the work of formatting the parts with the separator.

like image 135
svohara Avatar answered Oct 13 '22 13:10

svohara