Есть ли способ чередовать извлечение элементов с селеном или Beautifulsoup4? - PullRequest
1 голос
/ 05 мая 2019

Интересная проблема.Я очищаю сайт для ставок с селеном, затем обрабатываю с помощью bs4.Проблема в том, что сайт загружает информацию о своих шансах, а не как имена команд.Например:

London v Tokyo            2/1   4/1
Amsterdam v Helsinki      5/1   3/1

New York v California     7/1   10/1

Когда я вытаскиваю это и повторяю по нему, это выглядит так:

Names = [London, Tokyo, Amsterdam, Helsinki]
Odds = [2/1, 5/1, 4/1, 3/1, 7/1, 10/1]

Коэффициенты загружаются сверху вниз, слева направо, по-разномудлина кусков.Что означает, что когда я пытаюсь объединить имена и шансы, они не будут совпадать.

Мой вопрос: как мне обойти это?В конечном итоге я хочу, чтобы информация была опубликована, поэтому за именем команды следуют ее шансы:

Games = [London, 2/1, Tokyo, 4/1, Amsterdam, 5/1, Helsinki, 3/1, New York, 7/1, California, 10/1]

** ОБНОВЛЕНИЕ ** Сайт: https://www.bet365.com/#/AC/B151/C1/D50/E2/F163/ Если вы получили целевую страницу, топросто нажмите через.Затем «Esports» на левой панели, затем «All Matches» со средней страницы.

Код:

from selenium import webdriver
from bs4 import BeautifulSoup

url = "https://www.bet365.com/#/AC/B151/C1/D50/E2/F163/"
driver = webdriver.Chrome()
driver.get(url)

# Then i'm navigating to the "All Matches" page

soup = BeautifulSoup(driver.page_source, 'html.parser')
teams = driver.find_elements_by_class_name("sl-CouponParticipantWithBookCloses_Name")
odds_raw = driver.find_elements_by_class_name("gl-ParticipantOddsOnly_Odds")

odds = []
teams_text = []
new_teams = []
new_odds = []

for name in teams:
teams_text.append(name.text)

Команды входят как блоки, например: «Лондон против Токио».Таким образом, чтобы разделить названия команд, я повторяю их и делю их

for name in teams_text:
first, second = name.split(" v ")
new_teams.append(first)
new_teams.append(second)

Затем я перевожу полученные коэффициенты и преобразовал их в десятичную:

for odd in odds_raw:
odds.append(odd.text)
for odd in odds:
first, second = odd.split("/")
new_odd = (int(first) / int(second)) + 1
new_odds.append(round(new_odd, 2))

Так что теперь у меня естьсписок всех имен команд и список десятичных нечетных значений.Вот где моя проблема.То, как bet365 выдает свои шансы на матчи, заключается в вертикальных блоках различной длины для каждого игрового подразделения.

Так что, если шансы выглядят так:

Division 1
London v Tokyo        1   2
Amsterdam v Helsinki  3   4
Division 2
New York v California 5   6
Division 3
Sydney v Brisbane     7   8
Bali v Singapore      9   10
Berlin v Paris        11  12

Тогда, когда я их вытащушансы получатся такими:

[1, 3, 2, 4, 5, 6, 7, 9, 11, 8, 10, 12]

Там, где деления разной длины, мне трудно понять, как к нему приблизиться.

Ответы [ 3 ]

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

Вы можете получить желаемый результат, используя цикл for, например:

Names = ["London", "Tokyo", "Amsterdam", "Helsinki","New York","California"]
Odds = [2/1, 5/1, 4/1, 3/1, 7/1, 10/1]
start_nmb = 1 

for nmb, odd in enumerate(Odds):
    Names.insert(start_nmb, odd)
    start_nmb += 2

Выход:

['London', 2.0, 'Tokyo', 5.0, 'Amsterdam', 4.0, 'Helsinki', 3.0, 'New York', 7.0, 'California', 10.0]

Надеюсь, это поможет!

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

Вот длинный способ попробовать.Нечетные строки (как определено циклом) для шансов входят в команду 1 (левая часть команды 1 против команды 2. Четные строки идут в команду 2. Списки списков сглаживаются. Затем списки объединяются, как показано в ответе здесь от @ user942640 для альтернативных членов.

Примечание. Для получения точных результатов используется список равной длины.

import itertools
from bs4 import BeautifulSoup as bs
#your existing code to get to page and wait for presence of all elements
soup = bs(driver.page_source, 'lxml')
teams = [item.text.split(' v ') for item in soup.select('.sl-CouponParticipantWithBookCloses_NameContainer')]

i = 0
team1 = []
team2 = []

for item in soup.select('.sl-MarketCouponValuesExplicit2'):
    if i % 2 == 0:
        team1.append([i.text for i in item.select('div:not(.gl-MarketColumnHeader )')])
    else:
        team2.append([i.text for i in item.select('div:not(.gl-MarketColumnHeader )')])
    i+=1

team1 =  [item for sublist in team1 for item in sublist]
team2 =  [item for sublist in team2 for item in sublist]
teams = [item for sublist in teams for item in sublist]
team_odds =  [x for x in itertools.chain.from_iterable(itertools.zip_longest(team1,team2)) if x]
final = [x for x in itertools.chain.from_iterable(itertools.zip_longest(teams, team_odds)) if x]
print(final)

Итак, что-то вроде (отмечая, что коэффициенты сохраняютсяобновление):

from selenium import webdriver
import itertools
from bs4 import BeautifulSoup as bs
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get('https://www.bet365.com/#/HO/')
driver.get('https://www.bet365.com/#/AC/B151/C1/D50/E2/F163/')
WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".sl-MarketCouponValuesExplicit2")))
soup = bs(driver.page_source, 'lxml')
teams = [item.text.split(' v ') for item in soup.select('.sl-CouponParticipantWithBookCloses_NameContainer')]

i = 0
team1 = []
team2 = []

for item in soup.select('.sl-MarketCouponValuesExplicit2'):
    if i % 2 == 0:
        team1.append([i.text for i in item.select('div:not(.gl-MarketColumnHeader )')])
    else:
        team2.append([i.text for i in item.select('div:not(.gl-MarketColumnHeader )')])
    i+=1

team1 =  [item for sublist in team1 for item in sublist]
team2 =  [item for sublist in team2 for item in sublist]
teams = [item for sublist in teams for item in sublist]

team_odds =  [x for x in itertools.chain.from_iterable(itertools.zip_longest(team1,team2)) if x]
final = [x for x in itertools.chain.from_iterable(itertools.zip_longest(teams, team_odds)) if x]
print(final)
0 голосов
/ 05 мая 2019

Вы можете использовать регулярные выражения для захвата элементов.

import re
s = '''London v Tokyo 2/1 4/1 Amsterdam v Helsinki 5/1 3/1 New York v California 7/1 10/1'''
re.findall(r'(\w+)\s+v\s+(\w+)\s+(\d+/\d+)\s+(\d+/\d+)', s)

[('London', 'Tokyo', '2/1', '4/1'),
 ('Amsterdam', 'Helsinki', '5/1', '3/1'),
 ('York', 'California', '7/1', '10/1')]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...