Python Selenium Web Scraping Hidden Div - PullRequest
       0

Python Selenium Web Scraping Hidden Div

1 голос
/ 04 апреля 2020

Ну, как следует из названия, я пытаюсь собрать некоторые данные с веб-сайта ( пример) с помощью Selenium, однако у меня возникают проблемы с получением данных, скрытых в каждой строке таблицы Pro Results. тот, который отображается при нажатии кнопки Показать подробности (+).

Это мой код:

from bs4 import BeautifulSoup

from selenium import webdriver

# Set some Selenium Options
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')

# Webdriver
wd = webdriver.Chrome('chromedriver',options=options)

# URL
url = 'https://www.tapology.com/fightcenter/fighters/30449-sultan-aliev'

# Load URL
wd.get(url)

# Get HTML
soup = BeautifulSoup(wd.page_source, 'html.parser')

# All rows of the Pro Record table 
rows = soup.findAll('div', {'class': 'result'})

print(len(rows)) 

# [Out] 18

# Try to find all hidden data
hidden = soup.findAll('div', {'class': 'detail tall'})

print(hidden)

# [Out] []

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

Я тоже не очень знаком с Selenium, поэтому любые рекомендации будут приветствоваться.

Ответы [ 3 ]

1 голос
/ 05 апреля 2020

json, который содержит необходимую информацию, извлекается из API-интерфейса tapology с помощью запроса js.
Чтобы получить эту информацию, установите seleniumwire и используйте:

from seleniumwire import webdriver
import requests
# ...
driver = webdriver.Firefox()
driver.scopes = [ 'api.tapology.com'] # filter api.tapology.com requests only 
driver.get('https://www.tapology.com/fightcenter/fighters/30449-sultan-aliev')

for request in driver.requests:
    print(request.path)
    r = requests.get(request.path, headers=request.headers)
    print(r.json())  # the info you need is here

https://api.tapology.com/v1/internal_ranking_items/47211352261 # данные рейтинга https://api.tapology.com/v1/internal_fighters/472130449 # данные бойца


enter image description here

enter image description here

1 голос
/ 04 апреля 2020

Может быть, вам не нужно извлекать данные из HTML. Быстрая проверка в инструментах разработчика Chrome показывает, что на этом сайте есть API для запроса данных, но вам нужно использовать точно такой же заголовок запроса.

internal_fighters в формате JSON

internal_ranking_items в JSON формате

Другая альтернатива для этой проблемы - просто смоделировать действие «щелчок» на кнопке.

Проблема с вашим «скрытым» div заключается в том, что тег div динамически добавляется, когда пользователь нажимает кнопку (+).

# click submit button
submit_button = wd.find_elements_by_xpath('//*[@id="fighterRecord"]/section[1]/ul/li[1]/div/div[4]/i')[0]
submit_button.click()
0 голосов
/ 05 апреля 2020

Если вы хотите использовать только селен, попробуйте следующий код. Вам нужно нажимать на каждую кнопку расширения, чтобы получить следующую информацию таблицы. Затем используйте element.get_attribute("textContent")

Код :

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

driver=webdriver.Chrome()
driver.get("https://www.tapology.com/fightcenter/fighters/30449-sultan-aliev")
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"span.closebutton_closeButton--3abym"))).click()
tablerecords=WebDriverWait(driver,20).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR,"div.result")))
print(len(tablerecords))
for row in range(len(tablerecords)):
    tablerecords = WebDriverWait(driver, 10).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "div.result")))
    try:
        expand_btn=tablerecords[row].find_element_by_xpath(".//div[@class='more']/i")
        driver.execute_script("arguments[0].click();", expand_btn)
        time.sleep(2)
        hiddenelements=tablerecords[row].find_element_by_xpath("./following-sibling::div[1]").get_attribute('textContent')
        print(hiddenelements)
    except:
        continue

Выход :

25
Billing:Preliminary CardDuration:3 x 5 Minute RoundsWeight:Welterweight · 170 lbs (77.1 kg) · Weigh-In 170.0 lbs (77.1 kgs)Odds:-120 · Near EvenReferee:Leon Roberts
UFC on ESPN+ 7
UFC 230: Cormier vs. Lewis· Aliev Injury
Billing:Preliminary CardDuration:3 x 5 Minute RoundsWeight:Welterweight · 170 lbs (77.1 kg) · Weigh-In 171.0 lbs (77.6 kgs)Odds:+250 · Moderate UnderdogReferee:Osiris Maia
UFC on FOX 26· Aliev Injury
Billing:Preliminary CardDuration:3 x 5 Minute RoundsWeight:Welterweight · 170 lbs (77.1 kg) · Weigh-In 171.0 lbs (77.6 kgs)Odds:+135 · Slight UnderdogReferee:Ed CollantesDisclosed Pay:$20,000 ($10K Base, $10K Bonus)
UFC 202: Diaz vs. McGregor 2· Aliev Injury
Billing:Preliminary CardDuration:3 x 5 Minute RoundsWeight:Welterweight · 170 lbs (77.1 kg) · Weigh-In 170.0 lbs (77.1 kgs)Odds:-180 · Slight FavoriteReferee:Bobby RehmanUFC on FOX 14 Performance of the Night
Billing:Main CardDuration:3 x 5 Minute RoundsWeight:Light Heavyweight · 205 lbs (93.0 kg)
Billing:Main CardDuration:3 x 5 Minute RoundsWeight:Middleweight · 185 lbs (84.0 kg) · Weigh-In 185.4 lbs (84.1 kgs)Referee:Valentin Tarasov
Billing:Main CardDuration:3 x 5 Minute RoundsWeight:Middleweight · 185 lbs (83.9 kg) · Weigh-In 185.8 lbs (84.3 kgs)Odds:-350 · Moderate FavoriteReferee:Herb Dean
Billing:Preliminary CardDuration:3 x 5 Minute RoundsWeight:Middleweight · 185 lbs (83.9 kg) · Weigh-In 185.5 lbs (84.1 kgs)Odds:+145 · Slight UnderdogReferee:Joseph Hawes
Billing:Main CardDuration:3 x 5 Minute RoundsWeight:Light Heavyweight · 205 lbs (93.0 kg)
Billing:Main CardDuration:2 x 5 Minute Rounds
Billing:Main CardDuration:3 x 5 Minute Rounds
Title Bout:Tournament ChampionshipBilling:Main CardDuration:3 x 5 Minute RoundsWeight:Light Heavyweight · 205 lbs (93.0 kg)
ProFC 39: Global Grand Prix (Stage 6)· Omari Akhmedov injury
Title Bout:Tournament ChampionshipBilling:Main CardDuration:2 x 5 Minute RoundsWeight:Light Heavyweight · 205 lbs (93.0 kg)
Billing:Preliminary CardDuration:3 x 5 Minute RoundsWeight:Light Heavyweight · 205 lbs (93.0 kg)
Billing:Main CardDuration:2 x 5 Minute RoundsWeight:Light Heavyweight · 205 lbs (93.0 kg)
Title Bout:Tournament ChampionshipBilling:Main EventDuration:2 x 5 Minute RoundsWeight:Light Heavyweight · 205 lbs (93.0 kg)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...