Есть ли способ быстрее очистить этот сайт с помощью python?

веб-сайт "https://www.diretta.it/partita/ALdJKzeJ/#/classifiche/table/overall", и я использую этот код с селеном, но это занимает около 30 секунд, и выполнение одной и той же операции много раз становится слишком много время

from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By


chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--headless")
chrome_options.add_argument("--disable-gpu")
wbe= webdriver.Chrome('/Users/paolopiceni/Desktop/scraping/chromedriver',options=chrome_options)

wbe.get("https://www.diretta.it/partita/ALdJKzeJ/#/classifiche/table/overall")
sleep(2)

TEAM_HOME= wbe.find_element(By.CLASS_NAME,'duelParticipant__home ').text
TEAM_AWAY= wbe.find_element(By.CLASS_NAME,'duelParticipant__away ').text

teams_class_totale= wbe.find_elements(By.XPATH, '//*[@class = "ui-table__row table__row--selected "]/div[@class = "table__cell table__cell--participant  "]')
team1_class_totale=teams_class_totale[0].text
team2_class_totale=teams_class_totale[1].text

print(TEAM_HOME,TEAM_AWAY,team1_class_totale,team2_class_totale)

Пробую код:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from time import perf_counter

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--headless")

service = Service('/Users/paolopiceni/Desktop/scraping/chromedriver')

XPATH = '//*[@class = "ui-table__row table__row--selected "]/div[@class = "table__cell table__cell--participant  "]'
HC = 'duelParticipant__home'
AC = 'duelParticipant__away'
IW = 5

def main():
    with webdriver.Chrome('/Users/paolopiceni/Desktop/scraping/chromedriver', options=chrome_options) as wbe:
        wbe.implicitly_wait(IW)
        wbe.get("https://www.diretta.it/partita/ALdJKzeJ/#/classifiche/table/overall")

        TEAM_HOME = wbe.find_element(By.CLASS_NAME, HC).text
        TEAM_AWAY = wbe.find_element(By.CLASS_NAME, AC).text

        teams_class_totale = wbe.find_elements(By.XPATH, XPATH)
        assert len(teams_class_totale) > 1
        return TEAM_HOME, TEAM_AWAY, teams_class_totale[0].text, teams_class_totale[1].text

if __name__ == '__main__':
    start = perf_counter()
    print(*main())
    end = perf_counter()
    print(f'Duration = {end-start:.4}s')

но работает в 41с

El Gaish Ceramica Cleopatra Ceramica Cleopatra El Gaish
Duration=41.54s

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from time import perf_counter
import datetime

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--headless")

service = Service('/Users/paolopiceni/Desktop/scraping/chromedriver')

XPATH = '//*[@class = "ui-table__row table__row--selected "]/div[@class = "table__cell table__cell--participant  "]'
HC = 'duelParticipant__home'
AC = 'duelParticipant__away'
IW = 5

def main():
    with webdriver.Chrome('/Users/paolopiceni/Desktop/scraping/chromedriver', options=chrome_options) as wbe:
        wbe.implicitly_wait(IW)
        print(datetime.datetime.now())
        wbe.get("https://www.diretta.it/partita/ALdJKzeJ/#/classifiche/table/overall")
        print(datetime.datetime.now())
        TEAM_HOME = wbe.find_element(By.CLASS_NAME, HC).text
        TEAM_AWAY = wbe.find_element(By.CLASS_NAME, AC).text
        print(datetime.datetime.now())
        teams_class_totale = wbe.find_elements(By.XPATH, XPATH)
        print(datetime.datetime.now())
        assert len(teams_class_totale) > 1
        return TEAM_HOME, TEAM_AWAY, teams_class_totale[0].text, teams_class_totale[1].text

if __name__ == '__main__':
    start = perf_counter()
    print(*main())
    end = perf_counter()
    print(f'Duration = {end-start:.4}s')

I try this, and returns:
2023-06-30 13:28:32.871837
2023-06-30 13:29:01.530982
2023-06-30 13:29:04.029629
2023-06-30 13:29:10.085035
El Gaish Ceramica Cleopatra Ceramica Cleopatra El Gaish

так что самое длинное время после строки wbe.get(url) так в чем может быть проблема?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
95
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Возможно, вам поможет использование функции implicitly_wait(). Использование жестко закодированного сна редко бывает хорошей идеей.

Это выполняется менее чем за 3 секунды в моей среде:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from time import perf_counter

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--headless")

service = Service('/Volumes/G-Drive/chromedriver')

XPATH = '//*[@class = "ui-table__row table__row--selected "]/div[@class = "table__cell table__cell--participant  "]'
HC = 'duelParticipant__home'
AC = 'duelParticipant__away'
IW = 5
URL = 'https://www.diretta.it/partita/ALdJKzeJ/#/classifiche/table/overall'

def main():
    with webdriver.Chrome(service=service, options=chrome_options) as wbe:
        wbe.implicitly_wait(IW)
        wbe.get(URL)

        TEAM_HOME = wbe.find_element(By.CLASS_NAME, HC).text
        TEAM_AWAY = wbe.find_element(By.CLASS_NAME, AC).text

        teams_class_totale = wbe.find_elements(By.XPATH, XPATH)
        assert len(teams_class_totale) > 1
        return TEAM_HOME, TEAM_AWAY, teams_class_totale[0].text, teams_class_totale[1].text

if __name__ == '__main__':
    start = perf_counter()
    print(*main())
    end = perf_counter()
    print(f'Duration = {end-start:.2}s')

Выход:

El Gaish Ceramica Cleopatra Ceramica Cleopatra El Gaish
Duration=2.7s

Я не знаю, почему, но он длится 41 секунду '''El Gaish Ceramica Cleopatra Ceramica Cleopatra El Gaish Duration=41.54s'''

mario 30.06.2023 12:15

Ты используешь прокси? Это медленно, если вы получаете доступ к этому URL-адресу из браузера? Соответствует ли скорость вашего широкополосного доступа вашим требованиям? Вы можете добавить несколько отладочных отпечатков, чтобы показать, какие части кода вы достигаете в разные моменты времени.

DarkKnight 30.06.2023 12:23

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

mario 30.06.2023 12:56

@Mario Ну, вы знаете, как использовать print (), поэтому вам просто нужно напечатать текущее время дня. Импортируйте модуль datetime, затем распечатайте (datetime.datetime.now())

DarkKnight 30.06.2023 13:07
Ответ принят как подходящий

Ваш первый селеновый скрипт работает 3 секунды на моем ноутбуке. Но вы можете использовать requests и beautiful soup для получения данных без загрузки всего сайта (медленно - около 40 секунд на вашем ПК).

Этот скрипт печатает так же, как в TEAM_HOME и TEAM_AWAY.

import requests
from bs4 import BeautifulSoup
import json
import re

page = requests.get("https://www.diretta.it/partita/ALdJKzeJ/#/classifiche/table/overall")
page.raise_for_status()

page = BeautifulSoup(page.content, "html.parser")

data = page.find("body").find("script").string
data = re.search(r"window\.environment = (.*);", data, re.S)

data = data.group(1)
data = json.loads(data)

team_home = data["participantsData"]["home"][0]["name"]
team_away = data["participantsData"]["away"][0]["name"]

print(team_home, team_away) # El Gaish Ceramica Cleopatra

# uncomment to explore given data
# json.dump(data, open("data.json", "w"), indent=4)

Таблица немного сложнее. Я думаю, что это происходит из https://local-it.flashscore.ninja/400/x/feed/df_to_1_ALdJKzeJ_1 (убедитесь, что вы указали заголовок x-fsign: SW9D1eZo), и вывод нужно проанализировать, но это должно быть хорошим началом. Но я не понимаю, почему вы хотите, чтобы название команды в выбранной строке было таким же, как и в верхней части (TEAM_HOME, TEAM_AWAY).

ОБНОВЛЯТЬ:

Наконец, я создал парсер. Выбранные строки находятся в переменных row_team_home и row_team_away в качестве словаря. Данные, которые вы хотите получить, можно получить с помощью ключей в словаре.

Пожалуйста, поделитесь своим временем работы (0,32 с на моем ПК) и примите мой ответ, если ваша проблема решена.

import requests
from bs4 import BeautifulSoup
import json
import re
import time

time_start = time.time()

page = requests.get("https://www.diretta.it/partita/ALdJKzeJ/#/classifiche/table/overall")
page.raise_for_status()

page = BeautifulSoup(page.content, "html.parser")

data = page.find("body").find("script").string
data = re.search(r"window\.environment = (.*);", data, re.S)

if not data: raise ValueError("data not found")

data = data.group(1)
data = json.loads(data)

# uncomment to explore given data
# json.dump(data, open("data.json", "w"), indent=4)

team_home = data["participantsData"]["home"][0]
team_away = data["participantsData"]["away"][0]

print(team_home["name"], "- vs -", team_away["name"]) # El Gaish - vs - Ceramica Cleopatra

event_id = data["event_id_c"]
feed_sign = data["config"]["app"]["feed_sign"]

page = requests.get(f"https://local-it.flashscore.ninja/400/x/feed/df_to_1_{event_id}_1", headers = {"x-fsign": feed_sign})
page.raise_for_status()

DELIMETER_ARRAY = "|"
DELIMETER_ROW = "~"
DELIMETER_CELL = "¬"
DELIMETER_VALUE = "÷"

data = page.content.decode()
data = next(filter(None, [[*filter(None, [[*filter(None, [[*filter(None, z.split(DELIMETER_VALUE))] for z in y.split(DELIMETER_CELL)])] for y in x.split(DELIMETER_ROW)])] for x in data.split(DELIMETER_ARRAY)]))

team_home_id = team_home["id"]
team_away_id = team_away["id"]

table = {}
forma = "FORMA"

last_team_id = None

for row in data:
    try:
        row = dict(row)
    except ValueError:
        continue

    if "TI" in row: last_team_id = row["TI"]

    if last_team_id in table: # assume row is forma
        table[last_team_id][forma].append(row)
    else:
        row[forma] = [] # add space to forma

        table[last_team_id] = row

row_team_home = table[team_home_id]
row_team_away = table[team_away_id]

print(row_team_home)
print(row_team_away)

# printed output
"""
{'TR': '14', 'TS': '1', 'TN': 'El Gaish', 'TI': 'rRAQSp3M', 'TIU': '/squadra/el-gaish/rRAQSp3M/', 'TM': '32', 'TW': '7', 'TWR': '7', 'TWO': '0', 'TWP': '0', 'TWA': '0', 'TDR': '12', 'TL': '13', 'TLR': '13', 'TLO': '0', 'TLP': '0', 'TLA': '0', 'TAP': '73.17', 'NRM': '0', 'TPK': '1.03', 'TPF': '-11', 'TG': '30:41', 'TP': '33', 'FORMA': [{'LMS': 'N', 'LMU': 'draw', 'LME': 'ALdJKzeJ', 'LMH': 'rRAQSp3M', 'LMA': 'ATasWtPS', 'LMT': '[b]0:0 [/b](El Gaish - Ceramica Cleopatra)\n1688083200'}, {'LMS': 'V', 'LMU': 'win', 'LME': 'xGGr8cBD', 'LMH': 'Q79lCRYM', 'LMA': 'rRAQSp3M', 'LMT': '[b]0:1 [/b](Ismaily - El Gaish)\n1686182400'}, {'LMS': 'V', 'LMU': 'win', 'LME': 'b1ZiIsZK', 'LMH': 'rRAQSp3M', 'LMA': 't6WUYDaO', 'LMT': '[b]2:0 [/b](El Gaish - Smouha)\n1685750400'}, {'LMS': 'P', 'LMU': 'loss stage-3', 'LME': 'bm8KAoX4', 'LMH': 'Qk0VR4IS', 'LMA': 'rRAQSp3M', 'LMT': '[b]2:0 [/b](Zamalek - El Gaish)\n1685404800'}, {'LMS': 'P', 'LMU': 'loss stage-3', 'LME': 'MROX0A3t', 'LMH': 'rRAQSp3M', 'LMA': 'EPsYDm4A', 'LMT': '[b]0:2 [/b](El Gaish - Al Ahly)\n1685059200'}]}
{'TR': '12', 'TS': '1', 'TN': 'Ceramica Cleopatra', 'TI': 'ATasWtPS', 'TIU': '/squadra/ceramica-cleopatra/ATasWtPS/', 'TM': '32', 'TW': '6', 'TWR': '6', 'TWO': '0', 'TWP': '0', 'TWA': '0', 'TDR': '16', 'TL': '10', 'TLR': '10', 'TLO': '0', 'TLP': '0', 'TLA': '0', 'TAP': '96.67', 'NRM': '0', 'TPK': '1.06', 'TPF': '-1', 'TG': '29:30', 'TP': '34', 'FORMA': [{'LMS': 'N', 'LMU': 'draw', 'LME': 'ALdJKzeJ', 'LMH': 'rRAQSp3M', 'LMA': 'ATasWtPS', 'LMT': '[b]0:0 [/b](El Gaish - Ceramica Cleopatra)\n1688083200'}, {'LMS': 'N', 'LMU': 'draw', 'LME': 'bPHv9wd7', 'LMH': 't6WUYDaO', 'LMA': 'ATasWtPS', 'LMT': '[b]2:2 [/b](Smouha - Ceramica Cleopatra)\n1686096000'}, {'LMS': 'N', 'LMU': 'draw', 'LME': 'IiRqK348', 'LMH': 'ATasWtPS', 'LMA': 'UP8rEKaA', 'LMT': '[b]0:0 [/b](Ceramica Cleopatra - Pharco)\n1685664000'}, {'LMS': 'P', 'LMU': 'loss stage-3', 'LME': 'CC53RUDD', 'LMH': 'EPsYDm4A', 'LMA': 'ATasWtPS', 'LMT': '[b]1:0 [/b](Al Ahly - Ceramica Cleopatra)\n1685318400'}, {'LMS': 'P', 'LMU': 'loss stage-3', 'LME': '2NsYri0o', 'LMH': 'KCzFp0OB', 'LMA': 'ATasWtPS', 'LMT': '[b]1:0 [/b](Future FC - Ceramica Cleopatra)\n1684886400'}]}
"""

time_end = time.time()

# Elapsed: 0.32
print("Elapsed: {:.2}".format(time_end - time_start))

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

mario 01.07.2023 09:46

@mario Наконец, я создал парсер. Смотрите обновление. Пожалуйста, поделитесь своим временем работы (0,32 с на моем ПК) и примите мой ответ, если ваша проблема решена.

Jurakin 01.07.2023 20:34

большое спасибо, вы решили мою проблему, теперь она работает за 0,49 с

mario 02.07.2023 12:10

Другие вопросы по теме