4 Commits

Author SHA1 Message Date
Markus Heiser
a1d5add718 fixup! [fix] fix invalid escape error in Baidu Images & default config typo 2025-03-15 17:14:54 +01:00
Zhijie He
38caa49540 [fix] fix invalid escape error in Baidu Images & default config typo 2025-03-15 17:14:54 +01:00
Zhijie He
4ce7f1accc [feat]: engines add images & kaifa from baidu.com 2025-03-15 17:14:54 +01:00
Ivan Gabaldon
11b5ae186b container: add default support for IPv6 (#4448)
* Initial update

* update docs and test files
2025-03-15 11:20:37 +01:00
9 changed files with 142 additions and 25 deletions

View File

@@ -23,7 +23,7 @@ Volume:
EOF EOF
} }
export DEFAULT_BIND_ADDRESS="0.0.0.0:8080" export DEFAULT_BIND_ADDRESS="[::]:8080"
export BIND_ADDRESS="${BIND_ADDRESS:-${DEFAULT_BIND_ADDRESS}}" export BIND_ADDRESS="${BIND_ADDRESS:-${DEFAULT_BIND_ADDRESS}}"
# Parse command line # Parse command line

View File

@@ -59,7 +59,7 @@ and can relied on the default configuration :origin:`searx/settings.yml` using:
use_default_settings: true use_default_settings: true
server: server:
secret_key: "ultrasecretkey" # change this! secret_key: "ultrasecretkey" # change this!
bind_address: "0.0.0.0" bind_address: "[::]"
``engines:`` ``engines:``
With ``use_default_settings: true``, each settings can be override in a With ``use_default_settings: true``, each settings can be override in a

View File

@@ -9,8 +9,11 @@
from urllib.parse import urlencode from urllib.parse import urlencode
from datetime import datetime from datetime import datetime
import time
import json
from searx.exceptions import SearxEngineAPIException from searx.exceptions import SearxEngineAPIException
from searx.utils import html_to_text
about = { about = {
"website": "https://www.baidu.com", "website": "https://www.baidu.com",
@@ -23,33 +26,86 @@ about = {
} }
paging = True paging = True
categories = ["general"] categories = []
base_url = "https://www.baidu.com/s"
results_per_page = 10 results_per_page = 10
baidu_category = 'general'
time_range_support = True
time_range_dict = {"day": 86400, "week": 604800, "month": 2592000, "year": 31536000}
def init(_):
if baidu_category not in ('general', 'images', 'it'):
raise SearxEngineAPIException(f"Unsupported category: {baidu_category}")
def request(query, params): def request(query, params):
keyword = query.strip() page_num = params["pageno"]
query_params = { category_config = {
"wd": keyword, 'general': {
"rn": results_per_page, 'endpoint': 'https://www.baidu.com/s',
"pn": (params["pageno"] - 1) * results_per_page, 'params': {
"tn": "json", "wd": query,
"rn": results_per_page,
"pn": (page_num - 1) * results_per_page,
"tn": "json",
},
},
'images': {
'endpoint': 'https://image.baidu.com/search/acjson',
'params': {
"word": query,
"rn": results_per_page,
"pn": (page_num - 1) * results_per_page,
"tn": "resultjson_com",
},
},
'it': {
'endpoint': 'https://kaifa.baidu.com/rest/v1/search',
'params': {
"wd": query,
"pageSize": results_per_page,
"pageNum": page_num,
"paramList": f"page_num={page_num},page_size={results_per_page}",
"position": 0,
},
},
} }
params["url"] = f"{base_url}?{urlencode(query_params)}" query_params = category_config[baidu_category]['params']
query_url = category_config[baidu_category]['endpoint']
if params.get("time_range") in time_range_dict:
now = int(time.time())
past = now - time_range_dict[params["time_range"]]
if baidu_category == 'general':
query_params["gpc"] = f"stf={past},{now}|stftype=1"
if baidu_category == 'it':
query_params["paramList"] += f",timestamp_range={past}-{now}"
params["url"] = f"{query_url}?{urlencode(query_params)}"
return params return params
def response(resp): def response(resp):
try:
data = resp.json()
except Exception as e:
raise SearxEngineAPIException(f"Invalid response: {e}") from e
results = []
if "feed" not in data or "entry" not in data["feed"]: text = resp.text
if baidu_category == 'images':
# baidu's JSON encoder wrongly quotes / and ' characters by \\ and \'
text = text.replace(r"\/", "/").replace(r"\'", "'")
data = json.loads(text, strict=False)
parsers = {'general': parse_general, 'images': parse_images, 'it': parse_it}
return parsers[baidu_category](data)
def parse_general(data):
results = []
if not data.get("feed", {}).get("entry"):
raise SearxEngineAPIException("Invalid response") raise SearxEngineAPIException("Invalid response")
for entry in data["feed"]["entry"]: for entry in data["feed"]["entry"]:
@@ -69,8 +125,53 @@ def response(resp):
"url": entry["url"], "url": entry["url"],
"content": entry.get("abs", ""), "content": entry.get("abs", ""),
"publishedDate": published_date, "publishedDate": published_date,
# "source": entry.get('source')
} }
) )
return results
def parse_images(data):
results = []
if "data" in data:
for item in data["data"]:
if not item:
# the last item in the JSON list is empty, the JSON string ends with "}, {}]"
continue
replace_url = item.get("replaceUrl", [{}])[0]
width = item.get("width")
height = item.get("height")
img_date = item.get("bdImgnewsDate")
publishedDate = None
if img_date:
publishedDate = datetime.strptime(img_date, "%Y-%m-%d %H:%M")
results.append(
{
"template": "images.html",
"url": replace_url.get("FromURL"),
"thumbnail_src": item.get("thumbURL"),
"img_src": replace_url.get("ObjURL"),
"title": html_to_text(item.get("fromPageTitle")),
"source": item.get("fromURLHost"),
"resolution": f"{width} x {height}",
"img_format": item.get("type"),
"filesize": item.get("filesize"),
"publishedDate": publishedDate,
}
)
return results
def parse_it(data):
results = []
if not data.get("data", {}).get("documents", {}).get("data"):
raise SearxEngineAPIException("Invalid response")
for entry in data["data"]["documents"]["data"]:
results.append(
{
'title': entry["techDocDigest"]["title"],
'url': entry["techDocDigest"]["url"],
'content': entry["techDocDigest"]["summary"],
}
)
return results return results

View File

@@ -502,8 +502,24 @@ engines:
categories: music categories: music
- name: baidu - name: baidu
baidu_category: general
categories: [general]
engine: baidu engine: baidu
shortcut: baidu shortcut: bd
disabled: true
- name: baidu images
baidu_category: images
categories: [images]
engine: baidu
shortcut: bdi
disabled: true
- name: baidu kaifa
baidu_category: it
categories: [it]
engine: baidu
shortcut: bdk
disabled: true disabled: true
- name: wikipedia - name: wikipedia

View File

@@ -12,7 +12,7 @@ search:
server: server:
port: 9000 port: 9000
bind_address: "0.0.0.0" bind_address: "[::]"
secret_key: "user_settings_secret" secret_key: "user_settings_secret"
base_url: false base_url: false
image_proxy: false image_proxy: false

View File

@@ -5,7 +5,7 @@ use_default_settings:
- wikinews - wikinews
server: server:
secret_key: "user_secret_key" secret_key: "user_secret_key"
bind_address: "0.0.0.0" bind_address: "[::]"
default_http_headers: default_http_headers:
Custom-Header: Custom-Value Custom-Header: Custom-Value
engines: engines:

View File

@@ -5,6 +5,6 @@ use_default_settings:
- wikinews - wikinews
server: server:
secret_key: "user_secret_key" secret_key: "user_secret_key"
bind_address: "0.0.0.0" bind_address: "[::]"
default_http_headers: default_http_headers:
Custom-Header: Custom-Value Custom-Header: Custom-Value

View File

@@ -5,7 +5,7 @@ use_default_settings:
- wikinews - wikinews
server: server:
secret_key: "user_secret_key" secret_key: "user_secret_key"
bind_address: "0.0.0.0" bind_address: "[::]"
default_http_headers: default_http_headers:
Custom-Header: Custom-Value Custom-Header: Custom-Value
engines: engines:

View File

@@ -1,7 +1,7 @@
use_default_settings: true use_default_settings: true
server: server:
secret_key: "user_secret_key" secret_key: "user_secret_key"
bind_address: "0.0.0.0" bind_address: "[::]"
default_http_headers: default_http_headers:
Custom-Header: Custom-Value Custom-Header: Custom-Value
result_proxy: result_proxy: