Python (bs4 selenium) — Поиск HTML-данных после моделирования некоторых действий с selenium

#python #selenium #beautifulsoup #request

#python #selenium #beautifulsoup #запрос

Вопрос:

Я написал следующий код:

 driver = webdriver.Firefox()
driver.get('https://www.ybpn.de/ihre-parfuemerien/')

search_elem = driver.find_element_by_id("search_input") # Find search form
search_elem.send_keys("80331") # Enter zip code - later based on a .txt of zip codes
submit_button = driver.find_element_by_name("tx_ybpn_storefinder[submit]").submit() # press "submit" button, search
  

Selenium открывает URL-адрес, ищет «поле ввода», вводит почтовый индекс и нажимает отправить.

Теперь я хочу выполнить поиск на «новой странице» (после действия из приведенного выше кода) для конкретных данных с помощью bs4.

Обычно я бы использовал следующий код:

 url = ("https://www.ybpn.de/ihre-parfuemerien/")
page = requests.get(url)
soup = BeautifulSoup(page.text, features="html.parser")
  

Проблема: когда я использую «обычный» URL, он загружает динамическую карту без необходимых мне данных. Страница не создает уникальный URL-адрес после того, как я выполнил поиск с помощью selenium. Он добавляет только определенное значение хэша в конце URL-адреса, но когда я подключаюсь к этому URL-адресу, я перенаправляюсь на «обычную страницу» — нет URL-адреса, который загружает страницу с моими результатами поиска.

Вопрос: Как я могу получить определенный URL или создать переменную после действия «поиск определенного почтового индекса» для поиска с помощью bs4 нужных мне данных?

Я действительно надеюсь, что это понятно, что я имею в виду! Спасибо!

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

1. после отправки используйте driver.current_url , чтобы получить новый URL и использовать это

2. Вы хотите использовать Selenium вместе с запросами и BeautifulSoup? Почему? В чем смысл?

3. driver.current_url не работает — когда я ищу данные с помощью bs4, он выводит обычные данные без выполнения действия поиска. Я думаю, это связано с тем, что не сгенерирован URL-адрес, содержащий информацию о поиске.

4. @JaSON — Я хочу выполнить поиск по динамической веб-странице. Нужные мне данные загружаются при вводе определенного почтового индекса, поэтому сначала я должен имитировать действие «введите почтовый индекс», потому что мне нужны только данные из определенного диапазона почтовых индексов.

5. Но почему бы не использовать либо Selenium, либо requests Bs4 для всего процесса? Я не вижу смысла смешивать эти подходы. Я предполагаю, что вы боретесь с проблемой X-Y

Ответ №1:

Чтобы получить контакты для определенного почтового индекса, вы можете использовать этот пример:

 import requests
from bs4 import BeautifulSoup


url = 'https://www.ybpn.de/ihre-parfuemerien/'
data = {'tx_ybpn_storefinder[searchReq][term]': '80331'}

soup = BeautifulSoup(requests.get(url).content, 'html.parser')
data['tx_ybpn_storefinder[__trustedProperties]'] = soup.select_one('#storefinder [name*=__trustedProperties]')['value']
soup = BeautifulSoup(requests.post(url, data=data).content, 'html.parser')

for item in soup.select('.storefinder__list-item'):
    print(item.select_one('.storefinder-item__title').get_text(strip=True))
    print(item.select_one('.storefinder-item__adress').get_text(strip=True, separator='n'))
    print(item.select_one('.storefinder-item__contact').get_text(strip=True))
    print('-' * 80)
  

С принтами:

 Parfümerie Brückner
Rindermarkt 1
80331
München
Tel.: 49 89 263181
--------------------------------------------------------------------------------
Parfümerie Brückner
Marienplatz 8
80331
München
Tel.: 49 89 223874
--------------------------------------------------------------------------------
City Parfümerie Rathjen
Tal 14
80331
München
Tel.: 49 89 2285222
--------------------------------------------------------------------------------
Die kleine Theatiner Parfümerie
Theatiner Straße 35
80333
München
Tel.: 49 89 267919
--------------------------------------------------------------------------------
City Parfümerie Rathjen
Stachus Passagen Karlsplatz 1. UG
80335
München
Tel.: 49 89 55 4009
--------------------------------------------------------------------------------

...and so on.
  

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

1. Вы действительно спасли мои выходные — большое вам спасибо. Я не знаю, могу ли я указать почтовый индекс с помощью «[searchReq] [term]’: ‘80331’» без использования selenium.

2. Не могли бы вы, может быть, объяснить, что делает команда «print(‘-‘ * 80)»? Вы предоставили мне идеальное решение, и я хочу понять код! 🙂

3. @betagurkeDEV print('-' * 80) просто печатает строку из 80 символов '-' (или символ '-' повторяется 80 раз, а затем печатается вся строка).

4. Да, это логично: D теперь я вижу, это всего лишь «разделитель».

Ответ №2:

У меня есть идея, основанная на принятом ответе, которая заключается в получении внутреннего HTML всего тела.

     driver = webdriver.Firefox()
    driver.get('https://www.ybpn.de/ihre-parfuemerien/')
    
    search_elem = driver.find_element_by_id("search_input") # Find search form
    search_elem.send_keys("80331") # Enter zip code - later based on a .txt of zip codes
    submit_button = driver.find_element_by_name("tx_ybpn_storefinder[submit]").submit() # press "submit" button, search

soup = BeautifulSoup(page.find_element_by_tag_name("body").get_attribute('innerHTML'), features="html.parser")
for item in soup.select('.storefinder__list-item'):
    print(item.select_one('.storefinder-item__title').get_text(strip=True))
    print(item.select_one('.storefinder-item__adress').get_text(strip=True, separator='n'))
    print(item.select_one('.storefinder-item__contact').get_text(strip=True))
    print('-' * 80)