【问题标题】:Webdriver find_element_by_id works in shell, but won't execute in python script?Webdriver find_element_by_id 在shell中工作,但不会在python脚本中执行?
【发布时间】:2017-01-18 12:39:11
【问题描述】:

我正在通过尝试解决问题来学习 python。

当我在登录站点后尝试访问某个元素时,相同的命令在 shell 中有效,如果它在以下文件中则无效。

另外,我认为我的方法是错误的,因为元素不断更改其 ID,唯一不变的是我尝试过的“更多搜索结果”:find_link_by_text 失败,我认为是因为元素不包含hreffind_link_by_xpathcontains 文本。

网页抓取:

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
import time
import requests, bs4, re, csv

chrome_path = r"C:\Users\-----\Desktop\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
driver.get("https://dir.indiamart.com/search.mp?    ss=Power+Distribution+Transformers")
driver.maximize_window()
time.sleep(10)  #setting a gap for website load

action = webdriver.ActionChains(driver)
elm = driver.find_element_by_id("user_sign_in").click()
inputElement = driver.find_element_by_id('email')
inputElement.send_keys('xxxxxx')
driver.find_element_by_name("Submit3").send_keys(Keys.RETURN)
time.sleep(30)

#The code till above this is working perfectly
# element: 
#<div id="scroll2" class="fm2 p8 cur m_bt2" 
#onclick="javascript:displayResultsLogin('scroll2')"> Show More Results
# </div>
try:
    driver.find_element_by_id("scroll2").click()   
#Trying the the above find_element_* works if I input it in shell.
except:
    print("Didn't work")
    pass
# If I leave it in the file, removing the except, it shows element not found

r = driver.page_source
soup = bs4.BeautifulSoup(r, 'html.parser')
blocks = soup.find_all('div', class_='lst')

with open('output.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    for b in blocks:
        name = b.find(class_='cnm').get_text(strip=True)
        addr = b.find(class_='clg').get_text(strip=True)
        call = b.find(class_='ls_co phn').find(text=re.compile('\d+')).strip()
        writer.writerow([name, addr, call])

由于某种原因,在这个文件中的最后一部分,只会将元素中的 0 添加到文件中,而不是 xxxxxxxx 数字。

【问题讨论】:

  • 更加清晰和简洁:您应该指定您正在尝试执行的操作、预期和实际输出的简短描述,只留下那些导致问题的代码行 + 添加异常日志(如果有)一个......目前还不清楚你在问什么
  • 我确实发布了一个更中肯的问题,但似乎需要更多细节。我会编辑这个。

标签: python selenium web-scraping webdriver


【解决方案1】:

它可以在 shell 中工作,但在脚本中运行时却不能 - 这表明这是一个时间问题。在 shell 中,允许页面加载的每个命令之间都有延迟,而在脚本中则没有。问题可以通过WebDriverWait and one of the Expected Conditions解决:

wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.ID, "scroll2"))).click()

# or try locating the element by text
# wait.until(EC.element_to_be_clickable((By.XPATH, "//*[contains(., 'Show More Results')]"))).click()

wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".lst")))

r = driver.page_source
soup = bs4.BeautifulSoup(r, 'html.parser')

【讨论】:

  • 谢谢。即使出现以下错误,第一个选项仍然有效:raise TimeoutException(message, screen, stacktrace) selenium.common.exceptions.TimeoutException: Message:。但我仍然无法让wait.until(EC.element_to_be_clickable((By.XPATH, "//*[contains(., 'Show More Results')]"))).click() 工作。我尝试使用预期条件文档中的一些其他选项,但仍然没有。 r = driver.page_source 仍然不考虑 0 之后的数字。当我运行它而不是该脚本的一部分时它会做什么。
  • 我试过:try: DriverWait(self.driver, 10).until(EC.presence_of_element_located((By.XPATH, '//*[@id="scroll2" and text() != ""]'))) except: raise Exception('Unable to find text in this element after waiting 10 seconds') 使用你以前的答案来检查文本是否存在,我得到Unable to find text exception。现在试图弄清楚元素中的“显示更多结果”到底是什么。 :)
  • 谢谢。执行一次时,代码的注释掉部分的微小变化起作用:wait.until(EC.element_to_be_clickable((By.XPATH, "//*[contains(text(), ' Show More Results')]"))).click() 我很难理解为什么它不会再次执行(我使用了 shell)独立尝试并使用for 循环。给出一个超时异常,即使我可以看到按钮显示在页面上并且文本保持不变。
猜你喜欢
  • 1970-01-01
  • 2013-09-01
  • 1970-01-01
  • 2017-07-19
  • 2020-03-29
  • 1970-01-01
  • 1970-01-01
  • 2013-10-29
  • 1970-01-01
相关资源
最近更新 更多