পাইথনে প্রদত্ত ইউআরএলগুলিতে প্যারাম যুক্ত করুন


125

মনে করুন আমাকে একটি ইউআরএল দেওয়া হয়েছিল।
এর মধ্যে ইতিমধ্যে জিইটি পরামিতি থাকতে পারে (উদাঃ http://example.com/search?q=question) অথবা এটি নাও (যেমন http://example.com/)।

এবং এখন আমার এটির মতো কিছু পরামিতি যুক্ত করতে হবে {'lang':'en','tag':'python'}। প্রথম ক্ষেত্রে আমি http://example.com/search?q=question&lang=en&tag=pythonএবং দ্বিতীয়টিতে যাচ্ছি - http://example.com/search?lang=en&tag=python

এটি করার কোনও মানক উপায় আছে?

উত্তর:


180

সেখানে সঙ্গে quirks একটি দম্পতি আছে urllibএবং urlparseমডিউল। এখানে একটি কার্যকারী উদাহরণ:

try:
    import urlparse
    from urllib import urlencode
except: # For Python 3
    import urllib.parse as urlparse
    from urllib.parse import urlencode

url = "http://stackoverflow.com/search?q=question"
params = {'lang':'en','tag':'python'}

url_parts = list(urlparse.urlparse(url))
query = dict(urlparse.parse_qsl(url_parts[4]))
query.update(params)

url_parts[4] = urlencode(query)

print(urlparse.urlunparse(url_parts))

ParseResult, ফল urlparse(), শুধুমাত্র পাঠযোগ্য এবং আমরা তা একটি রূপান্তর করতে হবে listআগে আমরা তার ডেটা সংশোধন করতে চেষ্টা করতে পারেন।


13
আপনি সম্ভবত urlparse.parse_qsপরিবর্তে ব্যবহার করতে চান parse_qsl। পরেরটি একটি তালিকা দেয় যেখানে আপনি ডিক চান। ডকস.পাইথন.আর . / লাইবারি/urlparse.html#urlparse.parse_qs দেখুন ।
ফ্লোরিয়ান ব্রুকার

11
@florian: পাইথন 2.7 মধ্যে অন্তত তারপর আপনি ফোন করতে হবে urlencodeযেমন urllib.urlencode(query, doseq=True)। অন্যথায়, মূল ইউআরএলে বিদ্যমান প্যারামিটারগুলি সঠিকভাবে সংরক্ষণ করা যায় না (কারণ সেগুলি @ পার্স_কিউএস @ @ টিউপল হিসাবে ফিরে এসেছে
rluba

5
পাইথন 3 তে কাজ করার জন্য আমি এটি আবার লিখেছি। কোড এখানে
দ্বৈততা_

12
ফলাফল urlparse()এবং urlsplit()আসলে namedtupleদৃষ্টান্ত। সুতরাং আপনি এগুলি সরাসরি কোনও ভেরিয়েবলের জন্য বরাদ্দ করতে পারেন এবং url_parts = url_parts._replace(query = …)এটি আপডেট করার জন্য ব্যবহার করতে পারেন।
ফিউমার্মেলেল

2
সাবধানতা - এই বাস্তবায়ন পুনরায় কিছু ক্যারিয়ার প্যারামিটারগুলি সরিয়ে দেয় যা কিছু RESTful পরিষেবাদি ব্যবহার করে। কিছুটা সংশোধন করে এটি ঠিক করা যায়। ক্যোয়ারী = urlparse.parse_qsl (url_parts [4]) ক্যোয়ারী + = params.items () তবে আপনি যদি ডিকটি ব্যবহার করে প্রস্থানিত ক্যোয়ারী প্যারামগুলি প্রতিস্থাপন করতে চান তবে কিছুটা বেশি সময় নেয়।
ombre42

51

কেন

আমি এই পৃষ্ঠার সমস্ত সমাধানের সাথে সন্তুষ্ট নই ( আসুন, আমাদের প্রিয় কপি-পেস্ট জিনিসটি কোথায়? ) তাই আমি এখানে উত্তরগুলির উপর ভিত্তি করে আমার নিজের লিখেছি। এটি সম্পূর্ণ এবং আরও পাইথোনিক হওয়ার চেষ্টা করে। আমি আরও ভোক্তা-পক্ষ ( জেএস ) বন্ধুত্বপূর্ণ হওয়ার জন্য যুক্তিতে ডিক এবং বুল মানগুলির জন্য একটি হ্যান্ডলার যুক্ত করেছি , তবে তারা এখনও alচ্ছিক, আপনি এগুলি ফেলে দিতে পারেন।

কিভাবে এটা কাজ করে

পরীক্ষা 1: নতুন যুক্তি যুক্ত করা, অ্যারে এবং বুল মানগুলি পরিচালনা করা:

url = 'http://stackoverflow.com/test'
new_params = {'answers': False, 'data': ['some','values']}

add_url_params(url, new_params) == \
    'http://stackoverflow.com/test?data=some&data=values&answers=false'

পরীক্ষা 2: ডিআইসিটি মানগুলি পরিচালনা করে বিদ্যমান আরোগুলি পুনর্লিখন:

url = 'http://stackoverflow.com/test/?question=false'
new_params = {'question': {'__X__':'__Y__'}}

add_url_params(url, new_params) == \
    'http://stackoverflow.com/test/?question=%7B%22__X__%22%3A+%22__Y__%22%7D'

টক সস্তা। আমাকে কোডটি দেখান

কোড নিজেই। আমি এটিকে বিশদে বর্ণনা করার চেষ্টা করেছি:

from json import dumps

try:
    from urllib import urlencode, unquote
    from urlparse import urlparse, parse_qsl, ParseResult
except ImportError:
    # Python 3 fallback
    from urllib.parse import (
        urlencode, unquote, urlparse, parse_qsl, ParseResult
    )


def add_url_params(url, params):
    """ Add GET params to provided URL being aware of existing.

    :param url: string of target URL
    :param params: dict containing requested params to be added
    :return: string with updated URL

    >> url = 'http://stackoverflow.com/test?answers=true'
    >> new_params = {'answers': False, 'data': ['some','values']}
    >> add_url_params(url, new_params)
    'http://stackoverflow.com/test?data=some&data=values&answers=false'
    """
    # Unquoting URL first so we don't loose existing args
    url = unquote(url)
    # Extracting url info
    parsed_url = urlparse(url)
    # Extracting URL arguments from parsed URL
    get_args = parsed_url.query
    # Converting URL arguments to dict
    parsed_get_args = dict(parse_qsl(get_args))
    # Merging URL arguments dict with new params
    parsed_get_args.update(params)

    # Bool and Dict values should be converted to json-friendly values
    # you may throw this part away if you don't like it :)
    parsed_get_args.update(
        {k: dumps(v) for k, v in parsed_get_args.items()
         if isinstance(v, (bool, dict))}
    )

    # Converting URL argument to proper query string
    encoded_get_args = urlencode(parsed_get_args, doseq=True)
    # Creating new parsed result object based on provided with new
    # URL arguments. Same thing happens inside of urlparse.
    new_url = ParseResult(
        parsed_url.scheme, parsed_url.netloc, parsed_url.path,
        parsed_url.params, encoded_get_args, parsed_url.fragment
    ).geturl()

    return new_url

দয়া করে সচেতন হন যে কিছু সমস্যা থাকতে পারে, আপনি যদি একটি সন্ধান করেন তবে দয়া করে আমাকে জানান এবং আমরা এই জিনিসটিকে আরও ভাল করে দেব


পাইথন 3 সমর্থন অন্তর্ভুক্ত করার জন্য urllib.parse ব্যতীত সম্ভবত একটি চেষ্টা যুক্ত করুন? স্নিপেটের জন্য ধন্যবাদ, খুব দরকারী!
ম্যাটভি

হয়তো আমদানিও যুক্ত করবেন?
ক্রিস্টোফ রাউসি

আননকোডগুলি এনকোডযুক্ত ইউআরএলগুলি যেমন http://stackoverflow.com/with%2Fencoded?data=some&data=values&answe%2rs=false। এছাড়াও, >>>নথিকাগুলি আপনার নথিগুলি বাছতে সহায়তা করতে তিন শেভরন ব্যবহার করুন
পেলসন

কেন পরিবর্তন parsed_get_args = dict(parse_qsl(get_args))করবেন নাparsed_get_args = parse_qs(get_args)
ম্যাট এম

41

আপনি যদি ইউআরএল এনকোডিং ব্যবহার করতে চান তবে স্ট্রিংগুলিতে যথেচ্ছ ডেটা থাকতে পারে (উদাহরণস্বরূপ, অ্যাম্পারস্যান্ডস, স্ল্যাশ ইত্যাদির মতো অক্ষরগুলি এনকোড করা দরকার)।

Urllib.urlencode দেখুন:

>>> import urllib
>>> urllib.urlencode({'lang':'en','tag':'python'})
'lang=en&tag=python'

পাইথন 3 এ:

from urllib import parse
parse.urlencode({'lang':'en','tag':'python'})

5
অজগর 3 এ, এটি urllib.parse.urlencode
sha0w_wa1k3r

23

আপনি ফার্ল মডিউলটি https://github.com/gruns/furl ব্যবহার করতে পারেন

>>> from furl import furl
>>> print furl('http://example.com/search?q=question').add({'lang':'en','tag':'python'}).url
http://example.com/search?q=question&lang=en&tag=python


17

আপনি যদি অনুরোধগুলি lib ব্যবহার করেন :

import requests
...
params = {'tag': 'python'}
requests.get(url, params=params)

1
@ চেফস প্রশ্নটি ... কিসের সাথে আপেক্ষিক? আপনি কোনও ওয়েব পৃষ্ঠায় নেই, এর সাথে সম্পর্কিত হওয়ার কোনও প্রসঙ্গ নেই।
ক্রিস্টোফ রাউসি

11

হ্যাঁ: urllib ব্যবহার করুন ।

ডকুমেন্টেশনের উদাহরণ থেকে :

>>> import urllib
>>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)
>>> print f.geturl() # Prints the final URL with parameters.
>>> print f.read() # Prints the contents

1
আপনি কিছু সংক্ষিপ্ত উদাহরণ দিতে পারেন?
z4y4ts

1
f.read () আপনাকে HTML পৃষ্ঠা দেখাবে। কলিং url দেখতে, f.geturl ()
চেচেনসন

5
ইউআরএল (যা আসলে বেসিক স্ট্রিং ম্যানিপুলেশন) পার্স করার জন্য এইচটিটিপি অনুরোধ ব্যবহার করার জন্য -1 এছাড়াও প্রকৃত সমস্যা বিবেচনা করা হয় না, কারণ URL টি কীভাবে ক্যোয়ারী স্ট্রিং সঠিকভাবে সংযোজন করতে সক্ষম হতে পারে তা আপনার জানতে হবে।
অকর্মা

হয় লেখক সম্পাদিত প্রশ্নটি হয় এই উত্তরটির সাথে সম্পর্কিত নয়।
সরললিজ

11

এই উত্তরের ভিত্তিতে , সাধারণ ক্ষেত্রে (পাইথন 3 কোড) ওয়ান-লাইনার:

from urllib.parse import urlparse, urlencode


url = "https://stackoverflow.com/search?q=question"
params = {'lang':'en','tag':'python'}

url += ('&' if urlparse(url).query else '?') + urlencode(params)

বা:

url += ('&', '?')[urlparse(url).query == ''] + urlencode(params)

4
আমি জানি আপনি "সাধারণ কেস" উল্লেখ করেছেন, তবে স্পষ্ট করে বলার জন্য: ?অ্যাঙ্কারে ( #?stuff) যদি থাকে তবে এটি সঠিকভাবে কাজ করবে না ।
ইয়ান দানেনডাল

7

আমি দুটি শীর্ষ উত্তরের চেয়ে এটিকে আরও মার্জিত বলে মনে করি:

from urllib.parse import urlencode, urlparse, parse_qs

def merge_url_query_params(url: str, additional_params: dict) -> str:
    url_components = urlparse(url)
    original_params = parse_qs(url_components.query)
    # Before Python 3.5 you could update original_params with 
    # additional_params, but here all the variables are immutable.
    merged_params = {**original_params, **additional_params}
    updated_query = urlencode(merged_params, doseq=True)
    # _replace() is how you can create a new NamedTuple with a changed field
    return url_components._replace(query=updated_query).geturl()

assert merge_url_query_params(
    'http://example.com/search?q=question',
    {'lang':'en','tag':'python'},
) == 'http://example.com/search?q=question&lang=en&tag=python'

শীর্ষস্থানীয় উত্তরগুলিতে আমি পছন্দ না করা সর্বাধিক গুরুত্বপূর্ণ বিষয়গুলি (সেগুলি সত্ত্বেও ভাল):

  • প্রশ্ন: queryইউআরএল উপাদানগুলিতে থাকা সূচকটি মনে রাখতে হবে
  • নীলকান্তমণি 64: আপডেটগুলি তৈরির খুব ভার্বোস উপায় ParseResult

আমার প্রতিক্রিয়াটি যা খারাপ তা হ'ল dictআনপ্যাকিংটি ব্যবহার করে যাদুকরভাবে দেখা মেশানো, তবে আমি পরিবর্তনের বিরুদ্ধে আমার কুসংস্কারের কারণে ইতিমধ্যে বিদ্যমান অভিধানটি আপডেট করা পছন্দ করি।


6

আমি Łukasz সংস্করণটি পছন্দ করেছি, তবে যেহেতু urllib এবং urlparse ফাংশনগুলি এই ক্ষেত্রে ব্যবহার করা কিছুটা বিশ্রী, তাই আমি মনে করি এটির মতো কিছু করা আরও সহজ for

params = urllib.urlencode(params)

if urlparse.urlparse(url)[4]:
    print url + '&' + params
else:
    print url + '?' + params

4
[4] এর পরিবর্তে .কিয়ার সম্পর্কে কীভাবে?
ডেবি মেন্ডেজ

4

সম্মিলিত অভিধানে urlparseবিদ্যমান ইউআরএল ছিন্ন করতে বিভিন্ন ফাংশন ব্যবহার করুন urllib.urlencode(), তারপরে urlparse.urlunparse()এগুলি আবার একসাথে রাখতে।

অথবা কেবল ফলাফলটি নিন urllib.urlencode()এবং এটিকে যথাযথভাবে ইউআরএলে সংমিশ্রণ করুন।


3

তবুও অন্য উত্তর:

def addGetParameters(url, newParams):
    (scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url)
    queryList = urlparse.parse_qsl(query, keep_blank_values=True)
    for key in newParams:
        queryList.append((key, newParams[key]))
    return urlparse.urlunparse((scheme, netloc, path, params, urllib.urlencode(queryList), fragment))

2

এখানে আমি এটি বাস্তবায়ন করেছি।

import urllib

params = urllib.urlencode({'lang':'en','tag':'python'})
url = ''
if request.GET:
   url = request.url + '&' + params
else:
   url = request.url + '?' + params    

কবজির মতো কাজ করেছেন। যাইহোক, আমি এটি বাস্তবায়নের জন্য আরও পরিষ্কার উপায় পছন্দ করতাম।

উপরোক্ত প্রয়োগের আর একটি উপায় এটিকে একটি পদ্ধতিতে রাখা হয়েছে।

import urllib

def add_url_param(request, **params):
   new_url = ''
   _params = dict(**params)
   _params = urllib.urlencode(_params)

   if _params:
      if request.GET:
         new_url = request.url + '&' + _params
      else:
         new_url = request.url + '?' + _params
   else:
      new_url = request.url

   return new_ur

1

অজগর 2.5 এ

import cgi
import urllib
import urlparse

def add_url_param(url, **params):
    n=3
    parts = list(urlparse.urlsplit(url))
    d = dict(cgi.parse_qsl(parts[n])) # use cgi.parse_qs for list values
    d.update(params)
    parts[n]=urllib.urlencode(d)
    return urlparse.urlunsplit(parts)

url = "http://stackoverflow.com/search?q=question"
add_url_param(url, lang='en') == "http://stackoverflow.com/search?q=question&lang=en"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.