SELENIUM: element.text медленный, и я не знаю почему - PullRequest
0 голосов
/ 08 марта 2019
driver.get('https://nameberry.com/popular_names/US')
boys_names = driver.find_elements_by_css_selector("""tr.even>.boys""")
girls_names = driver.find_elements_by_css_selector("""tr.even>.girls""")
# so this goes quickly

def list_gen(ls): 
    hugo = []
    for i in ls:
        hugo.append(i.text)
    return hugo


i = time()
boys_names = list_gen(boys_names) # takes each <a> tag found before contained in boys_names and creates a list
# of names by taking everything CONTAINED (NOT attributes) between the opening and closing tag <a>
e = time()
print(e-i) # gives ~ 50 sec

i = time()
girls_names = list_gen(girls_names) # same thing but with girl names
e = time()
print(e-i) # gives ~ 80 sec 
# those timings are consistent even though no. of boys and girls is the same
# which is also weird
# no. is 1000 btw so that quite alot

Так что в основном я не понимаю, почему это так долго. Я пришел к выводу, что element.text почему-то занимает больше всего времени. Есть ли способ сделать это быстрее, не импортируя другие модули?

Ответы [ 2 ]

1 голос
/ 08 марта 2019

Вы можете использовать Javascript, который будет возвращать значения менее чем за 2 секунды.

Array.from(document.querySelectorAll('tr.even>.girls')).map(function(element) {return element.textContent;})

Просто запустите это в нашей консоли, вы увидите результат.

Теперь вы можетеназовите этот Javascript в вашем скрипте python selenium следующим образом:

driver.execute_script("return Array.from(document.querySelectorAll('tr.even>.girls')).map(function(element) {return element.textContent;})")

Попробуйте и дайте нам знать.

1 голос
/ 08 марта 2019

Я думаю, причина того, что ваш код занимает так много времени, в том, что цикл в list_gen отправляет кучу запросов на веб-страницу во время цикла. Если вы установите точку останова в вашем цикле и посмотрите на сетевую страницу браузера в инструментах разработки во время ее работы, вы увидите множество запросов, начинающихся с цикла. Я думаю, это потому, что страница загружает новые элементы, а селен прокручивает ее вниз. Насколько я могу сказать, если вы хотите, чтобы это было быстрее, вы должны использовать что-то еще. Мое предложение было бы использовать Красивый суп.

from selenium import webdriver  
from time import time  
from bs4 import BeautifulSoup  

driver = webdriver.Chrome()  

i = time()  
driver.get('https://nameberry.com/popular_names/US')  
soup = BeautifulSoup(driver.page_source, 'html5lib')  

boys_names = [x.getText() for x in soup.find_all("td", {"class", "boys"})]  
girls_names = [x.getText() for x in soup.find_all("td", {"class", "girls"})]  

e = time()  
print(e - i) # gives ~ 14 sec for me

Это получает весь источник веб-страницы сразу и анализирует его вместо того, чтобы работать со списком объектов веб-драйвера, которые возвращает селектор css.

Если вы не используете браузер селена ни для чего другого и хотите получать только имена, вы можете использовать запросы, чтобы получить источник страницы еще быстрее, поскольку вам не нужно загружать браузер селена.

import requests  

i = time()  

response = requests.get('https://nameberry.com/popular_names/US')  
soup = BeautifulSoup(response.content, 'html5lib')  
boys_names = [x.getText() for x in soup.find_all("td", {"class", "boys"})]  
girls_names = [x.getText() for x in soup.find_all("td", {"class", "girls"})]  

e = time()  
print(e - i) # gives ~ 3.2 sec
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...