Изменение значения выпадающего меню в HTML с помощью Python

#python #html #python-requests

#python #HTML #python-запросы

Вопрос:

Я выполняю несколько упражнений по созданию веб-страниц. Я хочу получить данные о продажах автомобилей в Европе и впоследствии подготовить несколько графиков. Поэтому я нашел http://carsalesbase.com/european-car-sales-data / является неплохим источником данных. Мне удалось получить данные о продажах одного конкретного автомобиля одного конкретного производителя. Если я изменю URL, я также смогу получить доступ к номерам продаж нескольких автомобилей и, возможно, нескольких производителей.

Вот мой код:

 import requests
from bs4 import BeautifulSoup as bs
import numpy as np
import matplotlib.pyplot as plt

car_type=0
car_spec=['ford-focus','ford-fiesta','ford-ecosport']

my_url='http://carsalesbase.com/european-car-sales- 
data/ford/' car_spec[car_type] '/'

page = requests.get(my_url)
soup = bs(page.content, 'html.parser')
t=soup.find("table")

rows=t.find_all('td')
  

Например, я могу получить доступ к данным о продажах трех автомобилей Ford.

Однако я хочу перебрать каждую машину каждого производителя. В Carsalesbase для этой цели есть два выпадающих меню. Одно из них предназначено производителю. Мне уже удалось прочитать все возможные значения из этого меню. Это пара «значение / текст»:

 <option value="0">Select Brand</option>,
<option value="82"> Group</option>,
<option value="17">Alfa Romeo</option>,
<option value="1">Alpina</option>,
<option value="249">Alpine</option>,
<option value="2">Aston Martin</option>,
<option value="67">Audi</option>,
  

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

После этого я полагаю, что смогу получить доступ ко всем данным о продажах с помощью этой http-схемы:

http://carsalesbase.com/?hide-value=1amp;brand-option=17amp;model-option=2089amp;css-go=Go

Я наблюдал это с помощью Chrome-developers tools на вкладке сеть. Обратите внимание, что «brand-option = 17» соответствует Alfa Romeo, который соответствует моему ручному вводу.

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

Кто-нибудь может помочь, как это сделать?

ps: Я читал о Selenium, который кажется подходящим инструментом для этого, но мне не нравится, что браузер действительно открывается при его использовании. должен быть более простой способ.

Спасибо!

добавление:

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

 <form action="http://carsalesbase.com/" class="search-form" method="get" 
role="search">
<input class="" id="hide-value" name="hide-value" type="hidden" value="1"/>
<select class="kelas1" id="brand-option" name="brand-option">
<option value="0">Select Brand</option>
<option value="82"> Group</option> <option value="17">Alfa Romeo</option> 
<option value="1">Alpina</option> ... <option value="74">Volkswagen</option> 
<option value="26">Volvo</option>
</select>
<select class="kelas1" id="model-option" name="model-option">
<option value="0">Select Model</option>
</select>
<input name="css-go" type="submit" value="Go"/>
</form>
  

но все еще не знаю, как заполнить эту форму.

Ответ №1:

Существует обходной путь для чтения таблицы из html с использованием pandas read_html. Всего несколько строк для передачи таблицы html в фрейм данных pandas.

Для меня, проверяющего отзывчивость http://carsalesbase.com/?hide-value=1amp;brand-option=17amp;model-option=2089amp;css-go=Go не возвращает ответ.

 import requests
import lxml
from lxml import html
import pandas as pd
import html5lib
from bs4 import BeautifulSoup
from tabulate import tabulate

url = "http://carsalesbase.com/european-car-sales-data/alfa-romeo/"

r = requests.get(url)
tree = html.fromstring(r.content)

tables = tree.xpath('//table')

for table in tables:
  df = pd.read_html(html.tostring(table), header=0)
  df = df[0]
  print(tabulate(df, headers='keys', tablefmt='psql'))
  

Печатается ниже:

 --- -------------- -------------------------- --------------- 
|    |   Unnamed: 0 |   Alfa Romeo  All Models | MarketShare   |
|---- -------------- -------------------------- ---------------|
|  0 |         2018 |                   83.438 | 0,00%         |
|  1 |         2017 |                   86.805 | 0,56%         |
|  2 |         2016 |                   66.155 | 0,44%         |
|  3 |         2015 |                   56.688 | 0,40%         |
|  4 |         2014 |                   58.976 | 0,46%         |
|  5 |         2013 |                   64.285 | 0,52%         |
|  6 |         2012 |                   90.145 | 0,72%         |
|  7 |         2011 |                  131.385 | 0,95%         |
|  8 |         2010 |                  110.654 | 0,79%         |
|  9 |         2009 |                  110.827 | 0,76%         |
| 10 |         2008 |                  102.183 | 0,71%         |
| 11 |         2007 |                  144.404 | 0,92%         |
| 12 |         2006 |                  145.171 | 0,93%         |
| 13 |         2005 |                  130.922 | 0,81%         |
| 14 |         2004 |                  158.195 | 0,98%         |
| 15 |         2003 |                  159.611 | 1,11%         |
| 16 |         2002 |                  169.82  | 1,16%         |
| 17 |         2001 |                  205.431 | 1,36%         |
| 18 |         2000 |                  176.389 | 1,17%         |
| 19 |         1999 |                  180.154 | 1,18%         |
| 20 |         1998 |                  172.675 | 1,19%         |
| 21 |         1997 |                  128.107 | 0,95%         |
| 22 |         1996 |                  117.543 | 0,92%         |
| 23 |         1995 |                  130.358 | 1,08%         |
| 24 |         1994 |                  101.548 | 0,85%         |
| 25 |         1993 |                  114.292 | 1,02%         |
| 26 |         1992 |                  156.184 | 1,16%         |
| 27 |         1991 |                  180.035 | 1,34%         |
| 28 |         1990 |                  203.787 | 1,51%         |
  

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

1. Спасибо за ваш ответ. Моя проблема не в том, что я не могу прочитать значения таблицы. Это работает нормально. Даже если я установлю carsalesbase.com /… в качестве URL-адреса я могу проанализировать его с помощью Beatifulsoup, и мой график продаж получается красивым. Моя проблема скорее в том, что я не могу прочитать «model-option» для перебора всех моделей, скажем, Alfa Romeo (brand-option = 17). Это потому, что я не могу заполнить выпадающий список brand-option программно. Есть идеи, как это сделать?

Ответ №2:

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

Однако данные из второго выпадающего списка были сохранены в другом Java script на этом веб-сайте.

Итак, я очистил все теги «script» в HTML, пока не найду тот, который содержит нужные мне данные. Я могу открыть этот скрипт программно и перенести данные из скрипта в мой основной скрипт на python.

Таким образом, я могу выполнить итерацию по этой http-схеме:

http://carsalesbase.com/?hide-value=1amp;brand-option=17amp;model-option=2089amp;css-go=Go

Это довольно специализированное решение, и, очевидно, вам нужен selenium или аналогичный для очистки веб-сайтов с помощью JS в целом. Но для моей проблемы этого достаточно.