#python #selenium #beautifulsoup
#python #selenium #beautifulsoup
Вопрос:
Вот код:
import pandas as pd
from bs4 import BeautifulSoup
from time import sleep
from random import randint
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Chrome("chromedriver 3")
player_ids = ['114']
rd_id = 1
# iterating through player_ids
for i in player_ids:
team_id = i
base_url = "https://bet365.apps.imgarena.com/golf/3.18.0/full/?eventId=183amp;language=enamp;options=eyJ2aWRlb1BsYXliYWNrRW5hYmxlZCI6ZmFsc2V9#/leaderboard/team/"
mid_url = "?roundNo="
end_url = "amp;holeNo=1"
team_url = base_url str(team_id) mid_url str(rd_id) end_url
driver.get(team_url)
shotsbtn = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH,'//*[@id="root"]/div[1]/div[1]/div[1]/div[1]/div[3]/div[3]/span[1]')))
shotsbtn.click()
results = []
# iterating through each hole 1-18
for i in range(1, 3):
hole_id = i
base_xpath = '//*[@id="root"]/div[1]/div[1]/div[1]/div[1]/div[2]/div[3]/div[1]/div[2]/div[1]/div['
end_xpath = ']/span[1]'
full_xpath = base_xpath str(hole_id) end_xpath
sleep(randint(2,5))
holebtn = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH,full_xpath)))
holebtn.click()
sleep(randint(2,5))
content = driver.page_source
soup = BeautifulSoup(content, "html.parser")
# pulling required shot data from each hole
for a in soup.findAll('div', {'class': 'text__42f569fe no-name__42f569fe'}):
name = a.find
results.append(name)
# exporting information by player to.csv
df = pd.DataFrame({'Player': results})
df.to_csv('player_' str(team_id) '.csv', index=False, encoding='utf-8')
Что я хочу сделать, так это извлечь «имя игрока» и / или «team_id» вместе с каждым «hole_id», чтобы каждый выстрел был однозначно идентифицирован.
На данный момент я открываю это как .csv:
На данный момент я получаю что-то похожее на это:
Shot 4: </span <span in the hole for Par</span</div
Shot 3: </span <span stroke 3, 41 yds to Green, 9 ft 6 in. left to pin</span</div
Shot 2: </span <span stroke 2, 135 yds to Rough, 43 yds left to pin</span</div
Shot 1: </span <span stroke 1, 281 yds to Rough, 177 yds left to pin</span</div
И в идеале я надеюсь, что это будет выглядеть примерно так:
Hole 1, 114, 'Hatton, Tyrrell', Shot 4: </span <span in the hole for Par</span</div
Hole 1, 114, 'Hatton, Tyrrell', Shot 3: </span <span stroke 3, 41 yds to Green, 9 ft 6 in. left to pin</span</div
Hole 1, 114, 'Hatton, Tyrrell', Shot 2: </span <span stroke 2, 135 yds to Rough, 43 yds left to pin</span</div
Hole 1, 114, 'Hatton, Tyrrell', Shot 1: </span <span stroke 1, 281 yds to Rough, 177 yds left to pin</span</div
Ответ №1:
После многих часов напряженной работы я придумал окончательный код. Вот оно:
import pandas as pd
from bs4 import BeautifulSoup
from time import sleep
from random import randint
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
player_ids = ['114','115']
rd_id = 1
dictionary = {'Hole Number': [],
'Id': [],
'Player name': [],
'Shot number': [],
'Shot details': []}
# iterating through player_ids
name_list = []
hole_num_list = []
id_list = []
shot_data_final = []
shot_num_list = []
for i in player_ids:
team_id = i
base_url = "https://bet365.apps.imgarena.com/golf/3.18.0/full/?eventId=183amp;language=enamp;options=eyJ2aWRlb1BsYXliYWNrRW5hYmxlZCI6ZmFsc2V9#/leaderboard/team/"
mid_url = "?roundNo="
end_url = "amp;holeNo=1"
team_url = base_url str(team_id) mid_url str(rd_id) end_url
driver.get(team_url)
shotsbtn = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH,'//*[@id="root"]/div[1]/div[1]/div[1]/div[1]/div[3]/div[3]/span[1]')))
shotsbtn.click()
results = []
# iterating through each hole 1-18
for i in range(1, 3):
hole_id = i
base_xpath = '//*[@id="root"]/div[1]/div[1]/div[1]/div[1]/div[2]/div[3]/div[1]/div[2]/div[1]/div['
end_xpath = ']/span[1]'
full_xpath = base_xpath str(hole_id) end_xpath
sleep(randint(2,5))
holebtn = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH,full_xpath)))
holebtn.click()
sleep(randint(2,5))
content = driver.page_source
soup = BeautifulSoup(content, "html.parser")
name = soup.find('div',class_ = "player-name__691c96bc").text
hole_num = int(soup.find('span',class_ = "inner__-3c5fde4a active__-3c5fde4a").text)
shot_data = soup.find('ul',class_ = "list__3ed248d4").find_all('li')
for shot in shot_data:
shott = shot.text.split(':')
shot_num = shott[0]
shot_num_list.append(shot_num)
shot_data_final.append(shott[-1].strip())
for x in range(len(shot_data_final) - len(id_list)):
name_list.append(name)
hole_num_list.append(hole_num)
id_list.append(team_id)
hole_num_list.append('')
id_list.append('')
name_list.append('')
shot_num_list.append('')
shot_data_final.append('')
driver.close()
dictionary['Hole Number'] = hole_num_list
dictionary['Id'] = id_list
dictionary['Player name'] = name_list
dictionary['Shot number'] = shot_num_list
dictionary['Shot details'] = shot_data_final
df = pd.DataFrame(dictionary)
df.to_csv('Shots.csv',index=False)
Вывод:
Код в значительной степени понятен, поэтому я не думаю, что есть что объяснять. Надеюсь, это поможет!
Комментарии:
1. Спасибо, файл .csv теперь выглядит на месте. Просто повторите это сейчас, чтобы решить проблему перезаписи данных отверстий после каждого цикла. Я уверен, что это проблема с отступами, когда списки сбрасываются на пустые, тем самым получая только данные для 1 отверстия вместо всех 18?
2. Я изменил его. Проверьте это.
3. @dataguy Я обнаружил несколько ошибок в своем коде, поэтому я обновил его. Ознакомьтесь с моей последней правкой. Я предоставил полный код, и он отлично работает. Просто скопируйте, вставьте его в свой редактор и сообщите мне результат.
4. Спасибо, я возился с вашим исходным кодом решения, поскольку он был почти готов, но не совсем. Теперь это идеально.