Как извлечь данные из выпадающего меню с помощью Python Beautifulsoup - PullRequest
1 голос
/ 27 мая 2019

Я пытаюсь очистить данные с веб-сайта, который имеет многоуровневое раскрывающееся меню, каждый раз, когда выбирается какой-либо элемент, он изменяет вложенные элементы для раскрывающихся вложенных элементов. проблема в том, что для каждого цикла он извлекает одни и те же подпункты из выпадающих элементов. выбор происходит, но он не обновляет элементы от имени нового выбора из цикла Может ли кто-нибудь помочь мне, почему я не получаю желаемых результатов. Возможно, это из-за того, что мой раскрывающийся список написан на Java Script или что-то в этом роде.

например, вот этот маневр на картинке ниже: image of the dropdown я зашел так далеко:

enter code here

from selenium import webdriver
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.by import By
import csv

//#from selenium.webdriver.support import Select 
import time

print ("opening chorome....")  
driver = webdriver.Chrome()
driver.get('https://www.wheelmax.com/')
time.sleep(10)

csvData = ['Year', 'Make', 'Model', 'Body', 'Submodel', 'Size']

//#variables
yeart = []
make= []
model=[]
body = []
submodel = []
size = []
Yindex = Mkindex = Mdindex = Bdindex = Smindex = Sindex = 0

print ("waiting for program to set variables....")
time.sleep(20)

print ("initializing and setting variables....")

//#initializing Year
Year = Select(driver.find_element_by_id("icm-years-select"))
Year.select_by_value('2020')
yr = driver.find_elements(By.XPATH, '//*[@id="icm-years-select"]')
time.sleep(15)

//#initializing Make
Make = Select(driver.find_element_by_id("icm-makes-select"))
Make.select_by_index(1)
mk = driver.find_elements(By.XPATH, '//*[@id="icm-makes-select"]')
time.sleep(15)

//#initializing Model
Model = Select(driver.find_element_by_id("icm-models-select"))
Model.select_by_index(1)
mdl = driver.find_elements(By.XPATH, '//*[@id="icm-models-select"]')
time.sleep(15)

//#initializing body
Body = Select(driver.find_element_by_id("icm-drivebodies-select"))
Body.select_by_index(1)
bdy = driver.find_elements(By.XPATH, '//*[@id="icm-drivebodies-select"]')
time.sleep(15)

//#initializing submodel
Submodel = Select(driver.find_element_by_id("icm-submodels-select"))
Submodel.select_by_index(1)
sbm = driver.find_elements(By.XPATH, '//*[@id="icm-submodels-select"]')
time.sleep(15)

//#initializing size
Size = Select(driver.find_element_by_id("icm-sizes-select"))
Size.select_by_index(0)
siz = driver.find_elements(By.XPATH, '//*[@id="icm-sizes-select"]')
time.sleep(5)


Cyr = Cmk = Cmd = Cbd = Csmd = Csz = ""

print ("fetching data from variables....")

for y in yr:
    obj1 = driver.find_element_by_id("icm-years-select")
    Year = Select(obj1)
    Year.select_by_index(++Yindex)
    obj1.click()
    #obj1.click()
    yeart.append(y.text)
    Cyr = y.text
    time.sleep(10)
    for m in mk:
        obj2 = driver.find_element_by_id("icm-makes-select")
        Make = Select(obj2)
        Make.select_by_index(++Mkindex)
        obj2.click()
        #obj2.click()
        make.append(m.text)
        Cmk = m.text
        time.sleep(10)
        for md in mdl:
            Mdindex =0
            obj3 = driver.find_element_by_id("icm-models-select")
            Model = Select(obj3)
            Model.select_by_index(++Mdindex)
            obj3.click()
            #obj3.click(clickobj)
            model.append(md.text)
            Cmd = md.text
            time.sleep(10)
            Bdindex = 0
            for bd in bdy:
                obj4 = driver.find_element_by_id("icm-drivebodies-select")
                Body = Select(obj4)
                Body.select_by_index(++Bdindex)
                obj4.click()
                #obj4.click(clickobj2)
                body.append(bd.text)
                Cbd = bd.text
                time.sleep(10)
                Smindex = 0
                for sm in sbm:
                    obj5 = driver.find_element_by_id("icm-submodels-select")
                    Submodel = Select(obj5)
                    obj5.click()
                    Submodel.select_by_index(++Smindex)
                    #obj5.click(clickobj5)
                    submodel.append(sm.text)
                    Csmd = sm.text
                    time.sleep(10)
                    Sindex = 0
                    for sz in siz:
                        Size = Select(driver.find_element_by_id("icm-sizes-select"))
                        Size.select_by_index(++Sindex)
                        size.append(sz.text)
                        Scz = sz.text
                        csvData += [Cyr, Cmk, Cmd, Cbd,Csmd, Csz]

Ответы [ 3 ]

0 голосов
/ 27 мая 2019

Из-за https://www.wheelmax.com имеет многоуровневое раскрывающееся меню, зависящее друг от друга, например, если вы выберете опцию Select Year, после выбранного года на основе Select Make включается раскрывающийся список и отображается опция на основе выбранного года. опция.

Так что в основном вам нужно использовать пакет Selenium для опции динамического дескриптора.

Установить селен веб-драйвер в соответствии с вашим браузером

Загрузить веб-драйвер Chrome:

http://chromedriver.chromium.org/downloads

Установить веб-драйвер для браузера Chrome:

unzip ~/Downloads/chromedriver_linux64.zip -d ~/Downloads
chmod +x ~/Downloads/chromedriver
sudo mv -f ~/Downloads/chromedriver /usr/local/share/chromedriver
sudo ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver
sudo ln -s /usr/local/share/chromedriver /usr/bin/chromedriver

учебник по селену

https://selenium -python.readthedocs.io /

Eg. использование селена для выбора нескольких выпадающих опций

from selenium import webdriver
from selenium.webdriver.support.ui import Select
import time

driver = webdriver.Chrome()
driver.get('https://www.wheelmax.com/')
time.sleep(4)

selectYear = Select(driver.find_element_by_id("icm-years-select"))
selectYear.select_by_value('2019')

time.sleep(2)

selectMakes = Select(driver.find_element_by_id("icm-makes-select"))
selectMakes.select_by_value('58')

Обновление:

выбрать раскрывающееся значение параметра или подсчитать общее количество параметров

for option in selectYear.options:
    print(option.text)

print(len(selectYear.options))

Se more

0 голосов
/ 27 мая 2019

Как извлечь данные из выпадающего меню с помощью Python Beautifulsoup

Страница выполняет обратный вызов для заполнения годами. Просто подражайте этому.

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

import requests
​
r = requests.get('https://www.iconfigurators.com/json2/?returnType=json&bypass=true&id=13898&callback=yearObj').json()
years = [item['year'] for item in r['years']]
print(years)
0 голосов
/ 27 мая 2019

Я думаю, что причина, по которой вы не можете разобрать годы с красивым супом, заключается в том, что тег 'select', содержащий теги 'option' со всеми годами, еще не существует / скрыт в тот момент, когда красивый суп загружает страницу,Он добавляется в DOM, выполняя дополнительный JavaScript, который я предполагаю.Если вы посмотрите на DOM загруженной страницы с помощью инструментов разработчика вашего браузера, например, F12 для Mozilla, вы увидите, что тег, содержащий информацию, которую вы ищете: <select id="icm-years-select"">.Если вы попытаетесь разобрать для этого тега объект, загруженный с помощью красивого супа, вы получите пустой список объектов тегов:

from bs4 import BeautifulSoup
from requests import get
response = get('https://www.wheelmax.com/')
yourSoup = BeautifulSoup(response.text, "lxml")
print(len(yourSoup.select('div #vehicle-search'))) // length = 1 -> visible
print()
print(len(yourSoup.select('#icm-years-select')))    // length = 0 -> not visible

Так что, если вы хотите получить годы, используя Python всеми средствами, ядумаю, вы можете попытаться нажать на соответствующий тег, а затем снова проанализировать, используя некоторую комбинацию запросов / красивый суп / или модуль селена, который потребует немного больше копания: -)

В противном случае, если вам просто нужно быстропроанализировано лет, используйте JavaScript:

countYears = document.getElementById('icm-years-select').length;
yearArray = [];
for (i = 0; i < countYears; i++) {yearArray.push(document.getElementById('icm-years-select')[i].value)};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...