Почему я получаю содержимое тега пустого тела при попытке использовать веб-очистку с помощью библиотеки запросов?

#python #web-scraping #beautifulsoup #python-requests

Вопрос:

Я пытался использовать веб-скребок на веб-сайте, используя запросы и библиотеки python Beautifulsoup. Проблема в том, что я получаю html-данные веб-страницы, но содержимое тега тела пусто, в то время как на панели проверки на веб-сайте этого нет. Кто-нибудь может объяснить, почему это происходит и что я могу сделать, чтобы получить содержимое тела?

Вот мой код:

 from bs4 import BeautifulSoup
import requests

source = requests.get('https://webaccess-il.rexail.com/?s_jwe=eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..gKfb7AnqhUiIMIn0PGb35g.SUsLS70gBec9GBgraaV5BK8hKyqm-VvMSNjP3nIumtcrj9h19zOkYjaBHrW4SDL10DjeIcwQcz9ul1p8umMHKxPPC-QZpCyJbk7JQkUSqFM._d_sGsiSyPF_Xqs2hmLN5A#/store-products-shopping-non-customers').text
soup = BeautifulSoup(source, 'lxml')
print(soup)
 

Вот панель проверки веб — сайта:

введите описание изображения здесь

И вот результат моего кода:

введите описание изображения здесь

Спасибо вам 🙂

Ответ №1:

Есть две причины, по которым ваш код не может работать. Первый из них заключается в том, что веб-сайт действительно требует дополнительной header информации или cookie информации, которую вы можете попытаться найти с помощью инструмента Проверки браузера и добавить с помощью

 requests.get(url, headers=headers, cookies=cookies)
 

где headers и cookies находятся словари.

Другая причина, в которую я верю, заключается в том, что контент динамически загружается через Javascript после сборки, и то, что вы получаете, — это изначально загруженный веб-сайт.

Чтобы также предоставить вам решение, я приведу пример с использованием Selenium, который имитирует весь браузер, который обслуживает весь веб-сайт, однако у selenium есть некоторые накладные расходы на настройку, которые вы можете легко погуглить.

 from time import sleep
from selenium import webdriver
from bs4 import BeautifulSoup
url = 'https://webaccess-il.rexail.com/?s_jwe=eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..gKfb7AnqhUiIMIn0PGb35g.SUsLS70gBec9GBgraaV5BK8hKyqm-VvMSNjP3nIumtcrj9h19zOkYjaBHrW4SDL10DjeIcwQcz9ul1p8umMHKxPPC-QZpCyJbk7JQkUSqFM._d_sGsiSyPF_Xqs2hmLN5A#/store-products-shopping-non-customers'
driver = webdriver.Firefox()
driver.get(url)
sleep(10)
content = driver.page_source
soup = BeautifulSoup(content)

 

Если вы хотите, чтобы моделирование браузера не было видно, вы можете добавить

 from selenium.webdriver.firefox.options import Options
options = Options()
options.headless = True
driver = webdriver.Firefox(options=options)
 

что заставит его работать в фоновом режиме.

В качестве альтернативы Firefox вы можете использовать практически любой браузер, используя соответствующий драйвер.

Пример установки на базе Linux можно найти здесь Ссылка

Ответ №2:

Несмотря на то, что я нахожу использование Селена более легким для начинающих, этот сайт беспокоил меня, поэтому я придумал чистый requests способ, которым я также хочу поделиться.

Процесс: Когда вы просматриваете сетевой трафик после загрузки веб-сайта, вы обнаруживаете множество исходящих запросов get. Предполагая, что вас интересуют загруженные продукты, я обнаружил вызов прямо над изображениями продуктов, загружаемых с Amazon S3, на

 https://client-il.rexail.com/client/public/public-catalog?s_jwe=eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..gKfb7AnqhUiIMIn0PGb35g.SUsLS70gBec9GBgraaV5BK8hKyqm-VvMSNjP3nIumtcrj9h19zOkYjaBHrW4SDL10DjeIcwQcz9ul1p8umMHKxPPC-QZpCyJbk7JQkUSqFM._d_sGsiSyPF_Xqs2hmLN5A
 

важно

 https://client-il.rexail.com/client/public/public-catalog?s_jwe=[...]
 

Нажав на URL-адрес, я обнаружил, что это действительно JSON продуктов. Однако s_jwe токен является динамическим, и без него JSON не загружается.

Теперь, изучив URL-адрес начальной загрузки и выполнив поиск s_jwe , вы найдете

 <script>
            window.customerStore = {store: angular.fromJson({"id":26,"name":"u05deu05e9u05e7 u05d4u05e8 u05e4u05e8u05d7u05d9u05dd","imagePath":"images/stores/26/88aa6827bcf05f9484b0dafaedf22b0a.png","secondaryImagePath":"images/stores/4d5d1f54038b217244956071ca62312d.png","thirdImagePath":"images/stores/26/2f9294180e7d656ba7280540379869ee.png","fourthImagePath":"images/stores/26/bd2861565b18613497a6ce66903bf9eb.png","externalWebTrackingAccounts":"[{"accountType":"googleAnalytics","identifier":"UA-130110792-1","primaryDomain":"ecomeshek.co.il"},{"accountType":"facebookPixel","identifier":"3958210627568899"}]","worksWithStoreCoupons":false,"performSellingUnitsEstimationLearning":false}), s_jwe: "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..gKfb7AnqhUiIMIn0PGb35g.SUsLS70gBec9GBgraaV5BK8hKyqm-VvMSNjP3nIumtcrj9h19zOkYjaBHrW4SDL10DjeIcwQcz9ul1p8umMHKxPPC-QZpCyJbk7JQkUSqFM._d_sGsiSyPF_Xqs2hmLN5A"};
            const externalWebTrackingAccounts = angular.fromJson(customerStore.store.externalWebTrackingAccounts);
        </script>
 

содержащий

 s_jwe: "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..gKfb7AnqhUiIMIn0PGb35g.SUsLS70gBec9GBgraaV5BK8hKyqm-VvMSNjP3nIumtcrj9h19zOkYjaBHrW4SDL10DjeIcwQcz9ul1p8umMHKxPPC-QZpCyJbk7JQkUSqFM._d_sGsiSyPF_Xqs2hmLN5A"
 

Итак, подводя итог, хотя начальная страница не содержит продуктов, она содержит маркер и URL-адрес продукта.

Теперь вы можете извлечь эти два и вызвать каталог продукции напрямую как таковой:

ОКОНЧАТЕЛЬНЫЙ КОД:

 import requests
import re
import json

s = requests.Session()

initial_url = 'https://webaccess-il.rexail.com/?s_jwe=eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..gKfb7AnqhUiIMIn0PGb35g.SUsLS70gBec9GBgraaV5BK8hKyqm-VvMSNjP3nIumtcrj9h19zOkYjaBHrW4SDL10DjeIcwQcz9ul1p8umMHKxPPC-QZpCyJbk7JQkUSqFM._d_sGsiSyPF_Xqs2hmLN5A#/store-products-shopping-non-customers'
initial_site = s.get(url= initial_url).content.decode('utf-8')

jwe = re.findall(r's_jwe:.*"(.*)"', initial_site)

product_url = "https://client-il.rexail.com/client/public/public-catalog?s_jwe="  jwe[0]
products_site = s.get(url= product_url).content.decode('utf-8')
products = json.loads(products_site)["data"]
print(products[0])
 

При декодировании требуется небольшая доработка, но я уверен, что вы справитесь с этим. 😉

Это, конечно, более простой способ очистки этого веб-сайта, но, как я надеюсь, показал, очистка всегда немного похожа на игру в Шерлока Холмса.

Любые вопросы, рад помочь.

Комментарии:

1. Спасибо вам за отличные ответы! Я попробую это сделать 🙂