Webscraping для всей комбинации выпадающих значений - PullRequest
2 голосов
/ 21 февраля 2020

Я пытаюсь извлечь информацию о ценах и тегах h1 с cars.com, есть раскрывающийся список для поиска по странице.

Я хочу выбрать разные модели и выполнить поиск по цене. Но выбор модели зависит от марки. У меня есть все комбинации с использованием селена. Для каждой из раскрывающихся комбинаций, как я могу получить информацию H1, такую ​​как "soup.find (" H1 ")"

, код выглядит следующим образом:

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

driver = webdriver.Chrome('C:/Users/chromedriver.exe')
driver.get('https://www.cars.com/')
time.sleep(4)

selectMake = Select(driver.find_element_by_name("makeId"))


time.sleep(2)


selectModel = Select(driver.find_element_by_name("modelId"))

data = []
for makesOption in selectMake.options:
    makesText = makesOption.text
    selectMake.select_by_visible_text(makesText)
    time.sleep(1)
    selectModel = Select(driver.find_element_by_name("modelId"))
    for modelOption in selectModel.options:
        modelText = modelOption.text
        selectModel.select_by_visible_text(modelText)
        data.append([makesText,modelText])

Ответы [ 2 ]

1 голос
/ 22 февраля 2020

Вся необходимая информация содержится в json объектах в исходном коде каждой страницы, к счастью, javascript не требуется для их извлечения, поэтому вам не нужно selenium, что медленный по своей природе, и вы можете просто использовать requests для извлечения объекта json и преобразования его в объект python, то есть:

x = requests.get("https://cars.com")
if x.status_code == 200:
    js_obj = re.findall("REDUX_STATE = (.*?)</script>", x.text, re.IGNORECASE | re.MULTILINE)
    if js_obj:
        j_obj = json.loads(js_obj[0]) # check the tree view of the object on notes 

Объект json на главной странице cars.com содержит все марки и модели, которые представлены идентификаторами, а именно:

  • mkId = идентификационный номер
  • mdId = идентификационный номер модели

С помощью этой информации мы можем создавать поисковые запросы для всех марок и моделей:

https://www.cars.com/for-sale/searchresults.action/?dealerType=all&mdId=20773&mkId=20001&page=1&perPage=100


cars.com.py

import requests, re, json

x = requests.get("https://cars.com")
if x.status_code == 200:
    js_obj = re.findall("REDUX_STATE = (.*?)</script>", x.text, re.IGNORECASE | re.MULTILINE)
    if js_obj:
        j_obj = json.loads(js_obj[0])
        for model in j_obj['home']['makeModels']['models'][:1]: # remove [:1] to parse all makes and models
            mkId = model['makeId']
            mdId = model['id']
            label = model['label']
            name = model['name']

            #print(mkId, mdId, label, name)
            # 20001 20773 CL CL

            s_url = f"https://www.cars.com/for-sale/searchresults.action/?dealerType=all&mdId={mdId}&mkId={mkId}&page=1&perPage=100"

            s_page = requests.get(s_url)
            if s_page.status_code == 200:

                s_html = re.findall(r"CARS\.digitalData = (.*?);\s+</script>", s_page.text, re.IGNORECASE | re.MULTILINE)
                if s_html:
                    s_obj = json.loads(s_html[0])
                    if "page" in s_obj:
                        if "vehicle" in s_obj['page']:
                            for v in s_obj["page"]['vehicle']:
                                v_price = v['price']
                                v_make = v['make']
                                v_mileage = v['mileage']
                                #...
                                print(v_make, name, v_price, v_mileage)

Вывод: (v_make, name, v_price, v_m Пробег)

Acura CL 8800 43000
Acura CL 3999 116577
Acura CL 6995 62382
Acura CL 6987 63871
Acura CL 6777 136676
Acura CL 1995 172911
Acura CL 2995 170234
Acura CL 3989 240799
Acura CL 1999 124000
Acura CL 4998 39322
Acura CL 3175 105200
Acura CL 6995 129558
Acura CL 4000 153000
Acura CL 2295 147056
Acura CL 4800 156000
Acura CL 3995 170558
Acura CL 1500 197000
Acura CL 1750 177392
Acura CL 1750 133094
Acura CL 3999 140618
Acura CL 2500 175600
Acura CL 1100 240000
Acura CL 5950 115055
Acura CL 1995 93419
Acura CL None 167456
Acura CL 5900 93500
Acura CL 3444 193000
Acura CL 3900 161756
Acura CL None 125231
Acura CL 3150 202201
Acura CL 5998 130017
Acura CL 5000 158955
Acura CL 3288 0
Acura CL 3300 153713
Acura CL None 202147

Примечания:

  • Python DEMO
  • Скрипт нуждается в улучшении для отлова ошибок
1 голос
/ 21 февраля 2020

Вы инициализируете Select, но ничего не выбираете, найдите подробную информацию о том, как использовать, выберите здесь .

Используя WebDriverWait , вы можете дождаться указанного c состояние элементов. В приведенном ниже коде вместо сна я использовал wait.until(EC.element_to_be_clickable((By.NAME, "makeId"))), где Selenium будет проверять, активен ли элемент для щелчка каждые 0,5 секунды с таймаутом в 10 секунд, и, как только он соответствует критериям для нажатия, будет двигаться вперед.

from selenium import webdriver
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

driver = webdriver.Chrome('C:/Users/chromedriver.exe')
wait = WebDriverWait(driver, 10)

driver.get('https://www.cars.com/')

select_make = Select(wait.until(EC.element_to_be_clickable((By.NAME, "makeId"))))
select_make.select_by_visible_text("BMW")

select_model = Select(wait.until(EC.element_to_be_clickable((By.NAME, "modelId"))))
select_model.select_by_visible_text("- M850 Gran Coupe")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...