【发布时间】:2019-04-16 02:52:21
【问题描述】:
我正在使用 FireFox,我的代码运行良好,只是速度很慢。我阻止加载图像,只是为了加快一点速度:
firefox_profile = webdriver.FirefoxProfile()
firefox_profile.set_preference('permissions.default.image', 2)
firefox_profile.set_preference('dom.ipc.plugins.enabled.libflashplayer.so', 'false')
firefox_profile.set_preference("browser.privatebrowsing.autostart", True)
driver = webdriver.Firefox(firefox_profile=firefox_profile)
但性能仍然很慢。我试过无头,但不幸的是,它没有用,因为我收到 NoSuchElement 错误。那么有没有办法加速 Selenium 网络抓取?我不能使用scrapy,因为这是一个动态的网络抓取,我需要多次点击next按钮,直到没有可点击的按钮存在,并且还需要点击弹出按钮。
这是一个sn-p的代码:
a = []
b = []
c = []
d = []
e = []
f = []
while True:
container = driver.find_elements_by_xpath('.//*[contains(@class,"review-container")]')
for item in container:
time.sleep(2)
A = item.find_elements_by_xpath('.//*[contains(@class,"ui_bubble_rating bubble_")]')
for i in A:
a.append(i,text)
time.sleep(2)
B = item.find_elements_by_xpath('.//*[contains(@class,"recommend-titleInline noRatings")]')
for j in B:
b.append(j.text)
time.sleep(3)
C = item.find_elements_by_xpath('.//*[contains(@class,"noQuotes")]')
for k in C:
c.append(k.text)
time.sleep(3)
D = item.find_elements_by_xpath('.//*[contains(@class,"ratingDate")]')
for l in D:
d.append(l.text)
time.sleep(3)
E = item.find_elements_by_xpath('.//*[contains(@class,"partial_entry")]')
for m in E:
e.append(m.text)
try:
time.sleep(2)
next = driver.find_element_by_xpath('.//*[contains(@class,"nav next taLnk ui_button primary")]')
next.click()
time.sleep(2)
driver.find_element_by_xpath('.//*[contains(@class,"taLnk ulBlueLinks")]').click()
except (ElementClickInterceptedException,NoSuchElementException) as e:
break
这是一个经过编辑的版本,但速度没有提高。
========================================================================
while True:
container = driver.find_elements_by_xpath('.//*[contains(@class,"review-container")]')
for item in container:
WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH,'.//*[contains(@class,"ui_bubble_rating bubble_")]')))
A = item.find_elements_by_xpath('.//*[contains(@class,"ui_bubble_rating bubble_")]')
for i in A:
a.append(i.text)
WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH,'.//*[contains(@class,"recommend-titleInline noRatings")]')))
B = item.find_elements_by_xpath('.//*[contains(@class,"recommend-titleInline noRatings")]')
for i in B:
b.append(i.text)
WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH,'.//*[contains(@class,"noQuotes")]')))
C = item.find_elements_by_xpath('.//*[contains(@class,"noQuotes")]')
for i in C:
c.append(i.text)
WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH,'.//*[contains(@class,"ratingDate")]')))
D = item.find_elements_by_xpath('.//*[contains(@class,"ratingDate")]')
for i in D:
d.append(i.text)
WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH,'.//*[contains(@class,"partial_entry")]')))
E = item.find_elements_by_xpath('.//*[contains(@class,"partial_entry")]')
for i in E:
e.append(i.text)
try:
#time.sleep(2)
WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH,'.//*[contains(@class,"nav next taLnk ui_button primary")]')))
next = driver.find_element_by_xpath('.//*[contains(@class,"nav next taLnk ui_button primary")]')
next.click()
WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH,'.//*[contains(@class,"taLnk ulBlueLinks")]')))
driver.find_element_by_xpath('.//*[contains(@class,"taLnk ulBlueLinks")]').click()
except (ElementClickInterceptedException,NoSuchElementException) as e:
break
【问题讨论】:
-
在
while的每次迭代中,您有 17 秒的睡眠时间。你认为这可能与它有关吗? -
考虑使用Waits 而不是多次休眠以减少执行时间。另请注意,如果您进行网络抓取,则应仅将 Selenium 用作最后的手段。您可以尝试使用直接 API 调用获取所需数据,例如,
requestlib -
@Guy,我也在怀疑同样的事情,我正在寻找一种更优化的方式来抓取容器中的文本,它有一个下一步按钮,还有一个烦人的弹出窗口。
-
几件事,虽然不确定它会产生多大的不同。首先,如果一个元素的存在保证了另一个元素,那么您可能不需要 for 循环中的所有这些等待。就像,单击会给您一个新行以及新行中存在的所有元素。还要等到返回您正在寻找的元素。无需再次调用来获取元素。此外,我认为在每次调用中,您都在尝试再次收集所有元素,给定 xpath。因为您的列表可能类似于 1,1,2,1,2,3 种模式。
标签: python selenium firefox web-scraping scrapy