2

How i can change multiple parameters value in this url: https://google.com/?test=sadsad&again=tesss&dadasd=asdaas

You can see my code: i can just change 2 value!

This is the response https://google.com/?test=aaaaa&dadasd=howwww

again parameter not in the response! how i can change the value and add it to the url?

def between(value, a, b):
    pos_a = value.find(a)
    if pos_a == -1: return ""
    pos_b = value.rfind(b)
    if pos_b == -1: return ""
    adjusted_pos_a = pos_a + len(a)
    if adjusted_pos_a >= pos_b: return ""
    return value[adjusted_pos_a:pos_b]

def before(value, a):
    pos_a = value.find(a)
    if pos_a == -1: return ""
    return value[0:pos_a]

def after(value, a):
    pos_a = value.rfind(a)
    if pos_a == -1: return ""
    adjusted_pos_a = pos_a + len(a)
    if adjusted_pos_a >= len(value): return ""
    return value[adjusted_pos_a:]


test = "https://google.com/?test=sadsad&again=tesss&dadasd=asdaas"
if "&" in test:
    print(test.replace(between(test, "=", "&"), 'aaaaa').replace(after(test, "="), 'howwww'))
else:
    print(test.replace(after(test, "="), 'test'))

Thanks!

Torxed
  • 22,866
  • 14
  • 82
  • 131
test test
  • 77
  • 1
  • 11
  • You should really utilize [Retrieving parameters from a URL](https://stackoverflow.com/questions/5074803/retrieving-parameters-from-a-url) if possible. – Torxed Feb 16 '19 at 13:14
  • If you read my code, you can see, i get parameter from find it! so i dont know parameter name! – test test Feb 16 '19 at 13:16
  • You can iterate over them, it's a dictionary. – Torxed Feb 16 '19 at 13:58

3 Answers3

1

I would use urllib since it handles this for you.

First lets break down the URL.

import urllib

u = urllib.parse.urlparse('https://google.com/?test=sadsad&again=tesss&dadasd=asdaas')

ParseResult(scheme='https', netloc='google.com', path='/', params='', query='test=sadsad&again=tesss&dadasd=asdaas', fragment='')

Then lets isolate the query element.

data = dict(urllib.parse.parse_qsl(u.query))

{'test': 'sadsad', 'again': 'tesss', 'dadasd': 'asdaas'}

Now lets update some elements.

data.update({
    'test': 'foo',
    'again': 'fizz',
    'dadasd': 'bar'})

Now we should encode it back to the proper format.

encoded = urllib.parse.urlencode(data)

'test=foo&again=fizz&dadasd=bar'

And finally let us assemble the whole URL back together.

new_parts = (u.scheme, u.netloc, u.path, u.params, encoded, u.fragment)
final_url = urllib.parse.urlunparse(new_parts)

'https://google.com/?test=foo&again=fizz&dadasd=bar'
gold_cy
  • 13,648
  • 3
  • 23
  • 45
  • Ok thanks, but in this `data.update` should i know the parameters name to change it! what should i do if i don't know `parameters name`? – test test Feb 16 '19 at 14:03
  • yes you should know the parameters to update, if you're planning to use a `query` param you need to know the fields ahead of time, but you can also pull the `params` from `data` since you will retrieve that from the original url so there's no way you won't not know it – gold_cy Feb 16 '19 at 14:05
1

From your code it seems like you are probably fairly new to programming, so first of all congratulations on having attempted to solve your problem.

As you might expect, there are language features you may not know about yet that can help with problems like this. (There are also libraries specifically for parsing URLs, but point you to those wouldn't help your progress in Python quite as much - if you are just trying to get some job done they might be a godsend).

Since the question lacks a little clarity (don't worry - I can only speak and write English, so you are ahead of me there), I'll try to explain a simpler approach to your problem. From the last block of your code I understand your intent to be:

"If there are multiple parameters, replace the value of the first with 'aaaaa' and the others with 'howwww'. If there is only one, replace its value with 'test'."

Your code is a fair attempt (at what I think you want to do). I hope the following discussion will help you. First, set url to your example initially.

>>> url = "https://google.com/?test=sadsad&again=tesss&dadasd=asdaas"

While the code deals with multiple arguments or one, it doesn't deal with no arguments at all. This may or may not matter, but I like to program defensively, having made too many silly mistakes in the past. Further, detecting that case early simplifies the remaining logic by eliminating an "edge case" (something the general flow of your code does not handle). If I were writing a function (good when you want to repeat actions) I'd start it with something like

 if "?" not in url:
    return url

I skipped this here because I know what the sample string is and I'm not writing a function. Once you know there are arguments, you can split them out quite easily with

>>> stuff, args = url.split("?", 1)

The second argument to split is another defensive measure, telling it to ignore all but the first question mark. Since we know there is at least one, this guarantees there will always be two elements in the result, and Python won't complain about a different number of names as values in that assignment. Let's confirm their values:

>>> stuff, args
('https://google.com/', 'test=sadsad&again=tesss&dadasd=asdaas')

Now we have the arguments alone, we can split them out into a list:

>>> key_vals = args.split("&")
>>> key_vals
['test=sadsad', 'again=tesss', 'dadasd=asdaas']

Now you can create a list of key,value pairs:

>>> kv_pairs = [kv.split("=", 1) for kv in key_vals]
>>> kv_pairs
[['test', 'sadsad'], ['again', 'tesss'], ['dadasd', 'asdaas']]

At this point you can do whatever is appropriate do the keys and values - deleting elements, changing values, changing keys, and so on. You could create a dictionary from them, but beware repeated keys. I assume you can change kv_pairs to reflect the final URL you want.

Once you have made the necessary changes, putting the return value back together is relatively simple: we have to put an "=" between each key and value, then a "&" between each resulting string, then join the stuff back up with a "?". One step at a time:

>>> [f"{k}={v}" for (k, v) in kv_pairs]
['test=sadsad', 'again=tesss', 'dadasd=asdaas']

>>> "&".join(f"{k}={v}" for (k, v) in kv_pairs)
'test=sadsad&again=tesss&dadasd=asdaas'

>>> stuff + "?" + "&".join(f"{k}={v}" for (k, v) in kv_pairs)
'https://google.com/?test=sadsad&again=tesss&dadasd=asdaas'
holdenweb
  • 33,305
  • 7
  • 57
  • 77
  • this is a great write up and explanation however for beginners I think it is better to lead them towards proven tools for things like this, hence using urllib that way there is less chance of making an error with string manipulation – gold_cy Feb 16 '19 at 14:13
  • Sure. There's an answer that reflects this advice which I have upvoted, and I'm pretty confident it will do better than this one. – holdenweb Feb 16 '19 at 14:16
  • 1
    Thank you, that helped me more :) – test test Feb 16 '19 at 14:34
0

Is it necessary to do it from scartch? If not use the urllib already included in vanilla Python.

from urllib.parse import urlparse, parse_qsl, urlencode, urlunparse

url = "https://google.com/?test=sadsad&again=tesss&dadasd=asdaas"
parsed_url = urlparse(url)
qs = dict(parse_qsl(parsed_url.query))
# {'test': 'sadsad', 'again': 'tesss', 'dadasd': 'asdaas'}

if 'again' in qs:
    del qs['again']
# {'test': 'sadsad', 'dadasd': 'asdaas'}

parts = list(parsed_url)
parts[4] = urlencode(qs)
# ['https', 'google.com', '/', '', 'test=sadsad&dadasd=asdaas', '']
new_url = urlunparse(parts)
# https://google.com/?test=sadsad&dadasd=asdaas
josepdecid
  • 1,737
  • 14
  • 25