Вызов ячеек в фрейме данных с использованием Selenium - итерация по фрейму данных для записи в строку поиска веб-сайта - PullRequest
0 голосов
/ 02 июля 2018

Пока у меня есть : Скрипт Python, который может вызывать Chromedriver, вводить уникальный URL-адрес и выводить результаты из скорости чтения страницы.

Что я хочу сделать : создать цикл, который берет несколько URL-адресов из файла Excel по одному, загружает тест скорости страницы, извлекает результаты и повторяет процесс до всех URL-адресов. были прочитаны.

from selenium import webdriver
import time
import pandas as pd

dataSheet = pd.read_excel("URL_Test_File.xlsx")
df = pd.DataFrame()
pageSpeed = []

for data in dataSheet:
    armyURL = dataSheet['URLs']
    browser = webdriver.Chrome('C:\\Webdriver\\chromedriver')
    browser.get(('https://developers.google.com/speed/pagespeed/insights/'))
    time.sleep(3)
    searchBar = browser.find_element_by_name('url')
    searchBar.send_keys(armyURL)
    searchBar.send_keys(u'\ue007')
    time.sleep(7)
    scoreCard = browser.find_element_by_class_name('speed-report-card-score')
    df["Speed Results"] = scoreCard
    clearBar = browser.find_element_by_name('url')
    clearBar.clear()

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

Ответы [ 4 ]

0 голосов
/ 02 июля 2018

Поскольку вы не указали ссылку на свой файл Excel, я создал ссылку с тем же именем столбца, что и у вас.

Вы можете скачать его здесь: https://drive.google.com/open?id=1eelHqJcnNdKNIDYL7NIgwwdNsUEFqL4U

В случае, если в будущем файл будет удален, файл Excel выглядит следующим образом:

dataSheet = pd.read_excel("URL_Test_File.xlsx")
print(dataSheet)

Выход:

           URLs
0     yahoo.com
1  facebook.com
2    google.com

допущенные вами ошибки :

Первая ошибка-

for data in dataSheet

выдаст только имена всех столбцов. Попробуйте это:

for data in dataSheet:
    print(data)

ВЫХОД будет:

URLs

Чтобы перебрать столбец URL таблицы Excel, вам нужно сделать следующее:

for armyURL in dataSheet['URLs']:
    print(armyURL)

Вторая ошибка: Это не может считаться ошибкой, но, поскольку вы хотите проанализировать все сайты на одной вкладке, вы должны объявить browser перед циклом for. Потому что, если вы объявите browser внутри цикла for, он откроет новое окно браузера для каждого URL, поэтому очистка панели поиска URL бесполезна.

Третья ошибка:

df["Speed Results"] = scoreCard

ничего не добавит в ваш фрейм данных. Попробуйте это:

df = pd.DataFrame()
for i in range(3):
    df["Speed Results"]=i
print(df)

Выход будет просто

Speed Results

Для вставки значений во фрейм данных необходимо использовать методы iloc или loc. Гугл о них. Я использовал loc для решения. Вам нужно передать row number для ввода значений DataFrame, чтобы я инициализировал переменную i=0 перед циклом for, чтобы сохранить количество строк, и увеличил его на 1 в конце цикла. Попробуйте это:

df = pd.DataFrame()
df["Speed Results"]="" 
'''
you can specify columns in Dataframe declaration too like:
df = pd.DataFrame(index=None,columns=["Speed Results"])
'''
for i in range(3):
    df.loc[i]=i
print(df)

Выход:

    Speed Results
0   0
1   1
2   2

Четвертая ошибка: Поскольку вы хотите добавить оценку в ваш фрейм данных, который представляет собой текст, вам нужно использовать атрибут text для того же.

scoreCard = browser.find_element_by_class_name('speed-report-card-score')
df.loc[i]= scoreCard.text

Что вы должны были добавить:

Иногда браузеру может потребоваться время для загрузки элементов, и тем временем, если селен ищет какой-то элемент, который еще не загружен, он может выдать ошибку. Поэтому используйте WebDriverWait , чтобы заставить селен ожидать загрузки элемента.

Я добавил цикл while, который ожидает загрузки карты результатов.

Полный код:

import pandas as pd
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By

chrome_options = webdriver.ChromeOptions()

chrome_options.add_argument("start-maximized")

cpath="C:/Users/Downloads/chromedriver_win32/chromedriver.exe"


dataSheet = pd.read_excel("C:/Users/Downloads/URL_Test_File.xlsx")
df = pd.DataFrame(index=None,columns=["Speed Results"])
#df["Speed Results"]=""
browser = webdriver.Chrome(chrome_options=chrome_options,executable_path=cpath)

i=0

for armyURL in dataSheet['URLs']:
    browser = webdriver.Chrome(chrome_options=chrome_options,executable_path=cpath)

    #browser = webdriver.Chrome('C:\\Webdriver\\chromedriver')
    browser.get(('https://developers.google.com/speed/pagespeed/insights/'))
    sleep(3)
    searchBar = browser.find_element_by_name('url')
    searchBar.send_keys(armyURL)
    searchBar.send_keys(Keys.RETURN)
    sleep(7)
    while(True):
        try:
            WebDriverWait(browser,10).until(EC.presence_of_element_located((By.CLASS_NAME,'speed-report-card-score')))
            break
        except:
            pass
    scoreCard = browser.find_element_by_class_name('speed-report-card-score')
    #scoreCard=browser.find_element_by_xpath('//div[@class="speed-report"]/div[@class="speed-report-card left"]/p[@class="speed-report-card-score"]/span[@class="fast"]')
    df.loc[i]= scoreCard.text
    clearBar = browser.find_element_by_name('url')
    clearBar.clear()
    i+=1

print(df)

ВЫВОД:

      Speed Results
0  1.2s FCP2.2s DCL
1  1.7s FCP3.1s DCL
2  0.7s FCP0.7s DCL
0 голосов
/ 02 июля 2018

Вы ищете что-то подобное?

...
# add the right number of columns based on the number of elements in 
# scoreCard_list (see below)
result = pd.DataFrame(columns=["column a", "column b"]) 
counter = 0
for data in dataSheet:
  counter += 1
  ...
  scoreCard_list = scoreCard.text.split("\s+") # or choose other delimiter to split on
  result.loc[counter] = scoreCard_list
  ...
0 голосов
/ 02 июля 2018

Обновление

Я понял, что в моем исходном коде было больше недостатков, чем ожидалось, особенно вызов фрейма данных в цикле, который использует фрейм данных в качестве периметра. Это то, что я в конечном итоге написал, чтобы этот цикл заработал (спасибо Лео и dblclik за просмотр).

from selenium import webdriver
import time
import pandas as pd

dataSheet = pd.read_excel("URL_Test_File.xlsx") #test file is has column label URLs
df = pd.DataFrame()
pageSpeed = []

browser = webdriver.Chrome('C:\\Webdriver\\chromedriver')
browser.get(('https://developers.google.com/speed/pagespeed/insights/'))
time.sleep(3)

for i in dataSheet["URLs"]: #Specifying the exact part of the data frame to iterate over
    enterURL = i
    searchBar = browser.find_element_by_name('url')
    searchBar.send_keys(armyURL)
    searchBar.send_keys(u'\ue007')
    time.sleep(7)
    scoreCard = browser.find_element_by_class_name('speed-report-card-score')
    df["Speed Results"] = scoreCard.text
    clearBar = browser.find_element_by_name('url')
    clearBar.clear()

При использовании этого все еще есть некоторые проблемы, когда речь идет о сборе и добавлении точной информации, которые по-прежнему требуют устранения неполадок, но для тех, у кого есть такая же проблема при переборе кадров данных с Selenium, это должно быть на полпути приличным началом.

0 голосов
/ 02 июля 2018

Предполагая, что вы получаете данные с листа Excel и синтаксический анализ выполняется правильно, этот новый код должен делать то, что вы хотите. Вам нужно либо добавить данные к вашему df, либо вы можете использовать что-то вроде того, что у меня здесь, функция pd.DataFrame.from_dict() для создания фрейма данных из словаря ваших данных:

from selenium import webdriver
import time
import pandas as pd

dataSheet = pd.read_excel("URL_Test_File.xlsx")
#df = pd.DataFrame()  # We will create the df at the end
pageSpeed = []
url_list = [] # Create a list to collect your URLs as you iterate

for data in dataSheet:
    armyURL = dataSheet['URLs']
    browser = webdriver.Chrome('C:\\Webdriver\\chromedriver')
    browser.get(('https://developers.google.com/speed/pagespeed/insights/'))
    time.sleep(3)
    searchBar = browser.find_element_by_name('url')
    searchBar.send_keys(armyURL)
    searchBar.send_keys(u'\ue007')
    time.sleep(7)
    scoreCard = browser.find_element_by_class_name('speed-report-card-score')
    pageSpeed.append(scoreCard) # Add the speed data to your pageSpeed[] list
    url_list.append(armyURL) # Add the URL data to your url_list[] list
    clearBar = browser.find_element_by_name('url')
    clearBar.clear()
    browser.quit() # Close the browser since we'll open a new one up the next time (and we should always have a .quit() at the end of our Selenium code)

speed_test_dict = {'Pages': url_list, 'Page Speed': pageSpeed}
df = pd.DataFrame.from_dict(speed_test_dict)

Поскольку у меня нет вашего файла Excel, я не могу полностью протестировать, но это должно сработать (или я буду редактировать / изменять, если возникнут проблемы)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...