#python #json #python-3.x #web-scraping
#python #json #python-3.x #веб-очистка
Вопрос:
Я пытаюсь проанализировать все значения URL-адресов, доступных на разной глубине, в некотором содержимом json. Я прикрепляю файл, содержащий URL-адреса разной глубины, для вашего рассмотрения.
Вот как они структурированы (усечены):
{'hasSub': True,
'navigationTitle': 'Products',
'nodeName': 'products',
'pages': [{'hasSub': True,
'navigationTitle': 'Enclosures',
'nodeName': 'PG0002SCHRANK1',
'pages': [{'hasSub': True,
'navigationTitle': 'Hygienic Design',
'nodeName': 'PG0125SCHRANK1',
'pages': [{'hasSub': False,
'navigationTitle': 'Hygienic Design Terminal '
'box HD',
'nodeName': 'PRO0130',
'target': '_self',
'url': '/com-en/products/PG0002SCHRANK1/PG0125SCHRANK1/PRO0130'},
{'hasSub': False,
'navigationTitle': 'Hygienic Design Compact '
'enclosure HD, '
'single-door',
'nodeName': 'PRO0131',
'target': '_self',
'url': '/com-en/products/PG0002SCHRANK1/PG0125SCHRANK1/PRO0131'},
Если я рассмотрю вышеуказанный контент, результат, который я ищу:
/com-en/products/PG0002SCHRANK1/PG0125SCHRANK1/PRO0130
/com-en/products/PG0002SCHRANK1/PG0125SCHRANK1/PRO0131
Сценарий, который я написал для создания содержимого json:
import requests
from pprint import pprint
url = 'https://www.rittal.com/.rest/nav/menu/tree?'
params = {
'path': 'com',
'locale': 'en',
'deep': '10'
}
with requests.Session() as s:
s.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
s.headers['Accept'] = 'application/json, text/plain, */*'
r = s.get(url,params=params)
pprint(r.json()['pages'][0])
Как я могу удалить все URL-адреса с разной глубины из содержимого json?
Ответ №1:
Хорошо, кажется, я нашел решение в другом месте для извлечения всех доступных ссылок из любого вложенного json.
import requests
from pprint import pprint
url = 'https://www.rittal.com/.rest/nav/menu/tree?'
params = {
'path': 'com',
'locale': 'en',
'deep': '10'
}
def json_extract(obj, key):
arr = []
def extract(obj, arr, key):
if isinstance(obj, dict):
for k, v in obj.items():
if isinstance(v, (dict, list)):
extract(v, arr, key)
elif k == key:
arr.append(v)
elif isinstance(obj, list):
for item in obj:
extract(item, arr, key)
return arr
values = extract(obj, arr, key)
return values
with requests.Session() as s:
s.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
s.headers['Accept'] = 'application/json, text/plain, */*'
r = s.get(url, params=params).json()
for item in json_extract(r,'url'):
print(item)
Количество ссылок, создаваемых скриптом, составляет около 3500.
Ответ №2:
Что вы можете сделать, так это выполнить рекурсию по JSON. Это лучший способ справиться с разной глубиной URL-адресов.
Следующая рекурсия извлечет самые глубокие URL-адреса путем рекурсии по JSON.
import requests
from pprint import pprint
url = 'https://www.rittal.com/.rest/nav/menu/tree'
params = {
'path': 'com',
'locale': 'en',
'deep': '10'
}
def recurse(data):
if 'pages' in data:
for page in data['pages']:
recurse(page)
elif 'url' in data and data['url'].startswith('/com-en/'):
urls.append(data['url'])
urls = []
with requests.Session() as s:
s.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
s.headers['Accept'] = 'application/json, text/plain, */*'
r = s.get(url, params=params).json()
recurse(r)
pprint(urls)
Вот как это работает:
- Рекурсивный случай — если на текущем уровне есть страницы, выполните рекурсию для каждой
page
на текущем уровне - Базовый вариант — если URL-адрес отображается на текущем уровне, добавьте его в список URL-адресов
Кроме того, если вы отключите elif
for an if
, он предоставит вам все URL-адреса на любом уровне.
Обновление: кажется, в этом JSON есть 2 URL-адреса rouge. В частности, один есть https://www.eplan-software.com/solutions/eplan-platform/
, а другой пуст! Таким образом, я добавил условие data['url'].startswith('/com-en/')
для добавления только тех URL-адресов, которые соответствуют ожидаемому шаблону.