Я пытался разобрать сайт, но не могу получить всю информацию о странице. Точнее, у меня должна быть вся информация между <fgis-root> и </fgis-root>, но никакой информации нет. Как я могу это исправить?

from bs4 import BeautifulSoup
import urllib3

http = urllib3.PoolManager()

url = 'https://pub.fsa.gov.ru/ral/view/8/applicant'
response = http.request('GET', url)
soup = BeautifulSoup(response.data)
print(soup)
3
Dmitrii Timoshenko 6 Июл 2019 в 02:50

4 ответа

Лучший ответ

Поскольку содержимое, которое вы ищете, генерируется из JavaScript, вам нужно эмулировать браузер. Вы можете использовать selenium, чтобы сделать это:

from selenium import webdriver

with webdriver.Firefox() as driver: # e.g. using Firefox webdriver
    driver.get('your_url_here')
    i = driver.find_elements_by_tag_name("fgis-root")

Также ознакомьтесь с здесь всеми доступными методами, которые selenium обеспечивает поиск элементов на странице.

2
game0ver 6 Июл 2019 в 00:22

Проблема, с которой вы столкнулись, является распространенной проблемой в веб-поиске.

На веб-странице https://pub.fsa.gov.ru/ral/view/8/applicant загружается файл javascript по адресу https: // pub .fsa.gov.ru / main.73d6a501bd7bda31d5ec.js, этот файл отвечает за динамическую загрузку контента.

Корень проблемы в том, что urllib3, запросы или любой другой http-клиент в python не отображает javascript внутри этой веб-страницы. Таким образом, у вас есть только первоначальный ответ, предоставленный вам сервером, который во многих случаях не содержит необходимой вам информации.

Решением будет использование селена. Это позволит вам взаимодействовать с браузером, таким как chrome или firefox программно, эти браузеры фактически отображают результаты.

Вы не указали конкретную информацию, которую вы пытаетесь удалить с этого веб-сайта, я рекомендую использовать явное ожидание, пока элемент, который вы хотите найти, присутствует в DOM. Дополнительную информацию об ожиданиях вы можете найти в селене здесь.

Пример использования

Вы должны адаптировать этот код для очистки данных, которые вы хотите очистить.

# Imports
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException

# Constants
URL = 'https://pub.fsa.gov.ru/ral/view/8/applicant'
ELEMENT_XPATH = '/html/body/fgis-root/div/fgis-ral/fgis-card-view/div/div/fgis-view-applicant/fgis-card-block/div/div[2]'

def main():
    options = Options()
    options.headless = True
    driver = webdriver.Chrome(options=options)
    driver.get(URL)
    try:
        element = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.XPATH, ELEMENT_XPATH))
        )
        print(element.text) 
    except TimeoutException:
        print("Could not find the desired element")
    finally:
        driver.quit()

if __name__ == '__main__':
    main()
1
ch0wner 6 Июл 2019 в 00:35

Информация не «скрыта», а динамически генерируется с помощью JavaScript. В этом можно убедиться, сравнив «источник просмотра» с DOM в инспекторе элементов инструментов разработчика браузера.

Таким образом, JavaScript должен быть выполнен на DOM, чтобы получить желаемую информацию. Это может быть достигнуто с помощью безголового браузера. Безголовый браузер будет выполнять JavaScript как настоящий браузер, и им можно программно управлять, чтобы получить нужные данные.

Есть несколько разных безголовых браузеров и драйверов, написанных для еще большего количества языков. Я предпочитаю использовать Chrome без головы с Nick.js драйвером javascript. Вы можете использовать пример сценария в нижней части их домашней страницы с несколькими изменениями.

Если вы должны использовать Python, вот хороший учебник для начала: Driving Headless Chrome с Python.

0
Leftium 6 Июл 2019 в 00:22

Вы можете имитировать запрос GET. Эта информация поступила из веб-трафика, наблюдаемого в инструментах разработки, F12 , вкладка Сеть при загрузке страницы. Авторизация и идентификатор сеанса могут быть ограничены по времени. Вы можете использовать Session для обработки части куки, предварительно сделав запрос на прежний URL в течение того же сеанса.

import requests
import urllib3; urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


headers = {
    'Pragma': 'no-cache',
    'DNT': '1',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'en-US,en;q=0.9',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
    'lkId': '',
    'Accept': 'application/json, text/plain, */*',
    'Cache-Control': 'no-cache',
    'Authorization': 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiI5ZDhlNWJhNy02ZDg3LTRiMWEtYjZjNi0xOWZjMDJlM2QxZWYiLCJzdWIiOiJhbm9ueW1vdXMiLCJleHAiOjE1NjMyMzUwNjZ9.OnUcjrEXUsrmFyDBpgvhzznHMFicEknSDkjCyxaugO5z992H-McRRD9bfwNl7xMI3dm2HtdAPuTu3nnFzgCLuQ',
    'Connection': 'keep-alive',
    'Referer': 'https://pub.fsa.gov.ru/ral/view/8/applicant',
    'orgId': '',
}

with requests.Session() as s:
    r = s.get('https://pub.fsa.gov.ru/ral/view/8/applicant', verify = False)
    r = s.get('https://pub.fsa.gov.ru/api/v1/ral/common/companies/8', headers=headers).json()
    print(r)
1
QHarr 6 Июл 2019 в 00:14