Python 使用Selenium调用数据帧中的单元格-通过数据帧迭代写入网站搜索栏
到目前为止,我已经: 一个python脚本,可以调用Chromedriver,输入一个单一的url,并将结果带出页面速度读取 我想做的事情:创建一个循环,每次从excel文件中获取多个URL,加载页面速度测试,提取结果,并重复该过程,直到所有URL都被读取Python 使用Selenium调用数据帧中的单元格-通过数据帧迭代写入网站搜索栏,python,pandas,selenium,Python,Pandas,Selenium,到目前为止,我已经: 一个python脚本,可以调用Chromedriver,输入一个单一的url,并将结果带出页面速度读取 我想做的事情:创建一个循环,每次从excel文件中获取多个URL,加载页面速度测试,提取结果,并重复该过程,直到所有URL都被读取 from selenium import webdriver import time import pandas as pd dataSheet = pd.read_excel("URL_Test_File.xlsx") df = pd.D
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()
(我对编码比较陌生,所以我知道目前的工作有点草率)假设您是从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文件,我无法完全测试,但这应该可以工作(如果有任何问题,我将编辑/修改)假设您从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文件,我无法完全测试,但这应该可以工作(或者如果有任何问题,我将编辑/修改)您正在寻找类似的内容吗
...
# 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
...
你在找这样的东西吗
...
# 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
...
更新: 我意识到我的初始代码中有比预期更多的缺陷,特别是在循环中调用数据帧时,它使用数据帧作为周界。这就是我最终写出来的使这个循环工作的东西(感谢Leo和dblclik查看了这个)
在使用这种方法时,在准确收集和附加信息方面仍然存在一些问题,这些问题仍然需要解决,但是对于那些在使用Selenium迭代数据帧时遇到同样问题的人来说,这应该是一个不错的开始 更新: 我意识到我的初始代码中有比预期更多的缺陷,特别是在循环中调用数据帧时,它使用数据帧作为周界。这就是我最终写出来的使这个循环工作的东西(感谢Leo和dblclik查看了这个)
在使用这种方法时,在准确收集和附加信息方面仍然存在一些问题,这些问题仍然需要解决,但是对于那些在使用Selenium迭代数据帧时遇到同样问题的人来说,这应该是一个不错的开始 由于您没有为excel文件提供链接,我创建了一个与您的列名称相同的链接 您可以从这里下载: 如果将来文件被删除,excel文件如下所示:
dataSheet = pd.read_excel("URL_Test_File.xlsx")
print(dataSheet)
输出:
URLs
0 yahoo.com
1 facebook.com
2 google.com
Speed Results
0 0
1 1
2 2
你所犯的错误:
第一个错误-
for data in dataSheet
将只提供所有列名。
试试这个:
for data in dataSheet:
print(data)
df = pd.DataFrame()
for i in range(3):
df["Speed Results"]=i
print(df)
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)
输出将是:
URLs
要遍历excel工作表的URL列,您需要执行以下操作:
for armyURL in dataSheet['URLs']:
print(armyURL)
第二个错误:
这不能被认为是错误的,但因为您想分析同一选项卡中的所有站点,所以需要在for
循环之前声明browser
。
因为如果在for
循环中声明浏览器
,它将为每个URL打开新的浏览器窗口,所以清除URL搜索栏是没有用的
第三个错误:
df["Speed Results"] = scoreCard
不会在数据框中添加任何内容。
试试这个:
for data in dataSheet:
print(data)
df = pd.DataFrame()
for i in range(3):
df["Speed Results"]=i
print(df)
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
您需要使用iloc
或loc
方法在数据帧中插入值。
用谷歌搜索他们。
我使用了loc
作为解决方案。
您需要传递行数
以输入值DataFrame,因此我在之前为
循环初始化了一个变量I=0
,以保持行数,并在循环结束时将其递增1。
试试这个:
for data in dataSheet:
print(data)
df = pd.DataFrame()
for i in range(3):
df["Speed Results"]=i
print(df)
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)
输出:
URLs
0 yahoo.com
1 facebook.com
2 google.com
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
您应该添加的内容:
有时浏览器可能需要一些时间来加载元素,同时,如果selenium搜索一些尚未加载的元素,则可能会出现错误。
因此,使用WebDriverWait使selenium等待元素加载
我已经添加了一个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
由于您没有为excel文件提供链接,我创建了一个与您的列名称相同的链接 您可以从这里下载: 如果将来文件被删除,excel文件如下所示:
dataSheet = pd.read_excel("URL_Test_File.xlsx")
print(dataSheet)
输出:
URLs
0 yahoo.com
1 facebook.com
2 google.com
Speed Results
0 0
1 1
2 2
你所犯的错误:
第一个错误-
for data in dataSheet
将只提供所有列名。
试试这个:
for data in dataSheet:
print(data)
df = pd.DataFrame()
for i in range(3):
df["Speed Results"]=i
print(df)
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)
输出将是:
URLs
要遍历excel工作表的URL列,您需要执行以下操作:
for armyURL in dataSheet['URLs']:
print(armyURL)
第二个错误:
这不能被认为是错误的,但因为您想分析同一选项卡中的所有站点,所以需要在for
循环之前声明browser
。
因为如果在for
循环中声明浏览器
,它将为每个URL打开新的浏览器窗口,所以清除URL搜索栏是没有用的
第三个错误:
df["Speed Results"] = scoreCard
不会在数据框中添加任何内容。
试试这个:
for data in dataSheet:
print(data)
df = pd.DataFrame()
for i in range(3):
df["Speed Results"]=i
print(df)
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
您需要使用iloc
或loc
方法在数据帧中插入值。
用谷歌搜索他们。
我使用了loc
作为解决方案。
您需要传递行数
以输入数据帧中的值,因此我在之前为
循环初始化了一个变量I=0
,以保持行数和增量