solrという検索エンジンに、httpのリクエストをしています。
以下は一般的なhttpリクエストの質問です。
q4 = 'val:"mul(pow(0.5,div(geodist(), 1)),37140)"'
q = 'q=' + urllib.parse.quote(q4)
q4の複雑な文字列に対して、httpリクエストを行う場合に、
urllib.parse.quoteにより、日本語でも可能になると、
分かりました。
上記のq4を変換すると、リクエストとして、下記のように、
文字コードに変換されます。
val%3A%22mul%28pow%280.5%2Cdiv%28geodist%28%29%2C%201%29%29%2C37140%29%22
しかし、solrという検索エンジンに、リクエストを送ると、
エラーになります。
一般的に上記の方法で何か間違った方法があり、何かおかしい点は、
ありますか。
・POSTMANのパラメータ { "rsc":"z_poi", "keyword":"ディズニーランド", "sortType":1, "longitude":140, "latitude":135, "rangetype":1, "polygon":[ { "latitude": 140, "longitude": 138 }, { "latitude": 145, "longitude": 145 }, { "latitude": 139, "longitude": 145 }, { "latitude": 138, "longitude": 139 }, { "latitude": 140, "longitude": 138 } ], "pos":1, "num":20 } ・solrquery.py import urllib.parse from janus.azazel.azazel import Azazel class SolrQuery: def __init__(self) -> None: self._logger = Azazel() def createPoiSearchQuary(self, req_data): print('req_data') print(req_data) self._logger.writeLogDebug("SolrQuery::createPoiSearchQuery start") # フリーワード【keyword】、ジャンル【genre】に以下の特殊文字が入ってる場合、その前に『/』マークを付ける。 if not req_data.get('keyword') is None: print('test1') req_data['keyword'] = SolrQuery.escapeword(req_data.get('keyword')) if not req_data.get('genre') is None: print('test2') req_data['genre'] = SolrQuery.escapeword(req_data.get('genre')) keywordlist = 1 # keywordlist = req_data.get('keyword').split(' ') if keywordlist > 1: #q1の式作成 q1 = '' count = 0 for kword in keywordlist: #重みづけ処理 kword = SolrQuery.waitplus(kword) if count > 0: q1 += 'AND ' + kword else: q1 += kword count += 1 q1 = '(' + q1 + ')' else: kword = req_data.get('keyword') kword = SolrQuery.waitplus(kword) q1 = kword self._logger.writeLogDebug('q1: {}'.format(q1)) #q2の式作成 q2 = '' if not req_data.get('genre') is None: genrelist = req_data.get('genre').split(',') count = 0 for gword in genrelist: if count > 0: q2 += ' OR (fq_genre_key_array:' + gword + ')' else: q2 += '(fq_genre_key_array:' + gword + ')' count += 1 q2 = ' AND (' + q2 + ')^=1' q2 = str(q2).replace("[","").replace("]","").replace("/","") q2 = '' print('q2') print(q2) #q3の式作成 q3 = '' if not req_data.get('area') is None: arealist = req_data.get('area').split(' ') for area in arealist: if len(req_data.get('area')) == 2: q3 += '(prefcode:' + area + ')' else: q3 += 'OR (prefcode:' + area[0:1] + ' AND ' + area[2:4] + ')' q3 = ' AND (' + q3 + ')^=1' # q = '(' + q1 + q2 + q3 + ')' q = q1 + q2 + q3 print('q') print(q) #置換前 置換後 後で作成 #q4の式作成 q4 = '' req_sort = req_data.get('sort') req_rangetype = req_data.get('rangetype') print('test10') print(req_sort,req_rangetype) #検索パラメータ設定 if req_data.get('radius') is None: req_data['radius'] = 10000 if req_sort == 1 or req_sort == 2: if req_sort == 1 and req_rangetype == 1: print('test5') # q4 = '_val_:"mul(pow(0.5,div(geodist(),' + str(req_data.get('radius')) + ' / 1000 / 2)),37140)"' q4 = '_val_:mul(pow(0.5,div(geodist(), 1)),37140)' elif req_sort == 1 and req_rangetype == 2: # q4 = '_val_:"mul(pow(0.5,div(geodist(),' + str(req_data.get('radius')) + ' / 1000 / 2)),37140)"' q4 = '_val_:mul(pow(0.5,div(geodist(), 1)),37140)' elif req_sort == 2 and req_rangetype == 1: # q4 = '_val_:"mul(pow(0.5,div(geodist(),' + str(req_data.get('radius')) + ' / 1000 / 2)),37140)"' q4 = '_val_:mul(pow(0.5,div(geodist(), 1)),37140)' elif req_sort == 2 and req_rangetype == 2: # q4 = '_val_:"mul(pow(0.5,div(geodist(),' + str(req_data.get('radius')) + ' / 1000 / 2)),37140)"' q4 = '_val_:mul(pow(0.5,div(geodist(), 1)),37140)' print('q4') print(q4) amp = '&' d = '&d=' + urllib.parse.quote(str(req_data.get('radius') // 1000)) # d = 'd=' + urllib.parse.quote(str(req_data.get('radius') // 1000)) print('d') print(d) fl = amp + 'fl=' + urllib.parse.quote('*,score,distance:geodist()') if not req_data.get('lonlat') is None else '' print('fl') print(req_data.get('lonlat')) print(fl) fq = amp + 'fq=' + urllib.parse.quote('{!geofilt}') if not req_data.get('lonlat') is None else '' print('fq') print(fq) # indent = 'indent=' + urllib.parse.quote('true') indent = amp +'indent=' + urllib.parse.quote('true') print('indent') print(indent) pt = amp + 'pt=' + urllib.parse.quote(str(SolrQuery.ptset(req_data.get('lonlat')))) if not req_data.get('lonlat') is None else '' print('pt') print(pt) qop = amp + 'q.op=' + urllib.parse.quote('OR') print('qop') print(qop) # q = amp + 'q=' + urllib.parse.quote(q + ' ' + q4) q = 'q=' + urllib.parse.quote(q + ' ' + q4) print('q') print(q) sfield = amp + 'sfield=' + urllib.parse.quote('geo_p_wgs') print('sfield') print(sfield) sort = amp + 'sort=' + urllib.parse.quote('score desc,uniquekey asc') if not req_data.get('lonlat') is None else '' print('sort') print(sort) if req_sort == 3: sort = amp + 'sort=' + urllib.parse.quote('yomi desc,uniquekey asc') if not req_data.get('lonlat') is None else '' fl = amp + 'fl=' + urllib.parse.quote('*,score') if not req_data.get('lonlat') is None else '' deftype = amp + 'deftype=' + urllib.parse.quote('edimax') print('deftype') print(deftype) start = amp + 'start=' + urllib.parse.quote(str(req_data.get('pos'))) if not req_data.get('pos') is None else '' print('start') print(start) rows = amp + 'rows=' + urllib.parse.quote(str(req_data.get('num'))) if not req_data.get('num') is None else '' print('rows') print(rows) # query = indent + qop + q + sfield + sort + deftype + start + rows + d # query = indent + qop + q + sfield + sort + deftype + start + rows + d + fl + fq + pt # query = q + qop + indent + fl + sort + sfield + pt + fq + deftype + start + rows + d query = q + qop + indent + fl + sort + sfield + pt + fq print('query') print(query) ・呼び出し元 solrquery = SolrQuery() query = solrquery.createPoiSearchQuary(req_data)↑上記の関数 res = SolrAccess.execute(query, CORE10)↓下記のexecute def execute(query:str, core:str, data:dict= {}): # 送信先のURL(開発環境疎通確認用) #url = 'http://solr-dev.dev-financial-nsw.com/solr/zennrin/select?indent=true&q.op=OR&q=*%3A*' # 送信先のURL(開発環境用) url = URL.format(core) + query # Basic認証の情報(開発環境用) user = USER password = PASS # Basic認証用の文字列を作成. basic_user_and_pasword = base64.b64encode('{}:{}'.format(user, password).encode('utf-8')) # Basic認証付きの、POSTリクエストを作成する. request = urllib.request.Request(url, headers={ "Authorization": "Basic " + basic_user_and_pasword.decode('utf-8') , "Content-Type" : "application/json", }, method='POST', data=json.dumps(data).encode('utf-8')) # 送信して、レスポンスを受け取る. con = urllib.request.urlopen(request) res = simplejson.load(con) return res
・エラーの内容 nus\solrAccess\solraccess.py", line 71, in execute con = urllib.request.urlopen(request) File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2544.0_x64__qbz5n2kfra8p0\lib\urllib\request.py", line 216, in urlopen return opener.open(url, data, timeout) File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2544.0_x64__qbz5n2kfra8p0\lib\urllib\request.py", line 525, in open response = meth(req, response) File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2544.0_x64__qbz5n2kfra8p0\lib\urllib\request.py", line 634, in http_response response = self.parent.error( File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2544.0_x64__qbz5n2kfra8p0\lib\urllib\request.py", line 563, in error return self._call_chain(*args) File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2544.0_x64__qbz5n2kfra8p0\lib\urllib\request.py", line 496, in _call_chain result = func(*args) File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2544.0_x64__qbz5n2kfra8p0\lib\urllib\request.py", line 643, in http_error_default raise HTTPError(req.full_url, code, msg, hdrs, fp) urllib.error.HTTPError: HTTP Error 400: Bad Request
回答1件
あなたの回答
tips
プレビュー