0

My python code looks like below. Basically, I am joining two part of url using urljoin module of urlib. The issue that I am facing is during the URL join my output looks like below. As shown below the input from a which is a list is getting displayed at start part of url and end has start information. My expected output is also mentioned below.

To summarize, I want user to input total number of terms and the entered terms should be passed into query part of URL (i.e. query[]=" "&query[]= " "). Not sure if I am missing something.

Thanks in advance for help!

Code

from urllib.parse import urljoin

num_terms=int(input("Enter total number of search terms:")) #Asking user for number of terms

a=input("Enter all search terms: ").split(",",num_terms) #User enters all the terms

start,end=input("Enter start and end date").split() #User enters start and end date

base_url="http://mytest.org"
join_url="/comments/data?"+"terms[]={}"+"&terms[]={}"*int(num_terms-1)+"&start={}&end={}".format(a,start,end)

url=urljoin(base_url,join_url) #Joining url
url

Output:

Enter total number of search terms:3
Enter all search terms: ty ou io
Enter start and end date2345 7890
"http://mytest.org/comments/data?terms[]={}&terms[]={}&terms[]={}start=['ty ou io']&end=2345"

Expected Output

"http://mytest.org/comments/data?terms[]=ty&terms[]=ou&terms[]=io&start=2345&end=7890"
9
  • Are you using this link somewhere in code or you just need to construct one? Commented Jul 7, 2022 at 18:52
  • Can you be more clear on your requirement. I see issue with join_url. Commented Jul 7, 2022 at 18:52
  • @OlvinRoght...link will be use to make API call and fetch the data....the link provided in question is demo purpose only and resembles to the actual url Commented Jul 7, 2022 at 18:54
  • @manjari..correct the issue is with join_url. I would like to get user input for search terms and save those input to the terms part of URL Commented Jul 7, 2022 at 18:58
  • 1
    @biggboss2019, try requests.get("https://httpbin.org/get", params={"terms[]": ["ty", "ou", "io"], "start": 2345, "end": 7890}) and check what happens ;) Commented Jul 7, 2022 at 19:14

4 Answers 4

1

One issue I spotted: the search terms don't have any (,) which you used to split the string.

# the base URL path
url_base = "http://mytest.org/comments/data?"

# you don't need a search term number here
# the split below will do the job

# ask for search item directly, must have at least one item
a = input("Enter all search terms (separate by ,): ").split(",")
while len(a) < 1:
    a = input("Enter all search terms (separate by ,): ").split(",")

# ask for the start and end dates, no guarantee they are correct
# so use loop to force the user does the check for you 
dates = input("Enter the start and end date (separate by ,): ").split(",")
while len(dates) != 2:
    dates = input("Enter the start and end date (separate by ,): ").split(",")

# form the URL 
url_search = "&".join([f"terms[]={x}" for x in a])
url_date = "start=" + dates[0] + "&end=" + dates[1]

# the final result
url_final = "&".join([url_base, url_search, url_date])

# print the result
print(url_final)

The output is like:

Enter all search terms (separate by ,): ty,ou,io
Enter the start and end date (separate by ,): 2000,2022
http://mytest.org/comments/data?&terms[]=ty&terms[]=ou&terms[]=io&start=2000&end=2022
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you! Now the only issue is when user enters 1 date it should thow an error . The above date code is running forever
There were two other issues with the join_url assignment in the original code: a was not unpacked, and only the last section of the string was being formatted due to a lack of parentheses.
@biggboss2019 Look into try-except statements. docs.python.org/3/tutorial/errors.html
@biggboss2019 well, in that case you just need to edit the logic of while len(dates) != 2: to some error-catching clause
1

As author mentioned in this comment he/she will use requests to make an API call, so constructing URL isn't necessary, you can just use functionality of module you're using. You can let requests build query string internally by passing dict with URL params to params argument (read Passing Parameters In URLs):

import requests

response = requests.get(
    "http://mytest.org/comments/data",
    {
        "terms[]": ["ty", "ou", "io"],
        "start": 2345,
        "end": 7890
    }
)

Comments

0

One problem is your code is only formatting the last bit of the url. That is,

"&start={}&end={}".format(a,start,end)

is the only part where the formatting applies; you need to add parentheses.

The other thing is that we need to unpack the list of terms, a, in the .format function:

join_url=("/comments/data?"+"terms[]={}"+"&terms[]={}"*int(num_terms-1)+"&start={}&end={}").format(*a,start,end)

But I'd recommend using f-strings instead of .format:

join_url=("/comments/data?"+'&'.join([f"terms[]={term}"for term in a])+f"&start={start}&end={end}")

(I also used str.join for the terms instead of string multiplication.)

2 Comments

HI Bob, output is getting displayed as 'mytest.org/comments/data?terms[]=as we ty&start=123&end=567'. The expected output will be 'mytest.org/comments/data?terms[]=as &terms[]=we&terms[]= ty&start=123&end=567'
biggboss2019 That's because your code splits at the , character, not a space. I made the same mistake while testing your code, you may want to change that
0

A simple for loop should suffice:

terms = ""
for i in range(num_terms):
    terms += f"terms[]={a[i]}&"

Basically, format takes a single value, it does not iterate over a list as you wanted. This is a simple way to achieve your goal. You could probably use list comprehension as well.

[f"terms[]={term}"for term in a]

Output:

Enter total number of search terms:3
Enter all search terms: au,io,ua
Enter start and end date233 444
http://mytest.org/comments/data?terms[]=au&terms[]=io&terms[]=ua&&start=233&end=444

2 Comments

Receiving list index out of range error. I am doing something like this after start,end line of the code -> terms = "" for i in range(num_terms): terms += f"terms[]={a[i]}&" base_url="mytest.org" join_url=("/comments/data?"+terms+f"&start={start}&end={end}") url=urljoin(base_url,join_url) #Joining url url
If you are using your example input, then the problem is quite simply that you are giving the wrong input. Instead of ty ou io, input ty,ou,io. That will work since you are using a comma as the delimiter in split

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.