如何使用活动/已选择的类刮取<li>标签?

时间:2019-08-07 06:24:49

标签: python selenium web-scraping

我正在尝试从网站上抓取一个列表。有两个不同的列表,并且只有在选择第一个选项后才会加载一个列表。问题是,我无法选择第一个选项。我抓取了所有可用选项的列表。但是写完之后,我必须从给定的选项中选择它,但我无法这样做。

我尝试使用browser.find_element_by_css_selector(....)。click(),但即使设置了适当的等待条件,它也会显示elementnotfound异常。我认为是因为找不到该元素。

   browser.find_element_by_css_selector("#Brand_name").send_keys(company[i])
   element=  browser.find_element_by_css_selector("#Brand_name_selectWrap")
   browser.implicitly_wait(5) # seconds
   browser.find_element_by_css_selector("""#Brand_name_selectWrap > ul > li.selected""").click()

PS:以下是我要抓取的链接。我需要所有手机上市公司。 https://bangalore.quikr.com/Escrow/post-classifieds-ads/?postadcategoryid=227

有人可以提出更好的方法吗?

2 个答案:

答案 0 :(得分:1)

您可以将所有选项及其rel属性收集到字典中,然后使用适当的等待条件循环显示该子列表:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

d = webdriver.Chrome()
d.get('https://bangalore.quikr.com/Escrow/post-classifieds-ads/?postadcategoryid=227')
options = {i.get_attribute('textContent'):i.get_attribute('rel') for i in d.find_elements_by_css_selector('#Brand_name_selectWrap .optionLists li:not(.optionHeading) a')}
input_element = d.find_element_by_id('Brand_name')

for k,v in options.items():
    input_element.click()  
    input_element.send_keys(k)
    selector = '[rel="' + v + '"]'

    WebDriverWait(d, 3).until(EC.element_to_be_clickable((By.CSS_SELECTOR, selector))).click()
    WebDriverWait(d, 2).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "#Model_selectWrap.showCustomSelect")))

我创建了一个词典,其中包含所有针对手机的选项。键是输入框中要输入的实际文本,值是这些元素的rel属性值。每个选项都有一个rel属性。这意味着我可以通过按键输入电话名称,以便生成下拉菜单以从可能的值中选择您的手机,然后在css attribute = value选择器中使用rel属性以确保我单击了正确的名称

锚标记(<rel>中的a属性描述了链接指向的文档的关系。

selector变量仅保留当前的css attribute = value选择器,用于通过其rel属性值获取移动下拉选项。

答案 1 :(得分:0)

该元素被另一个元素覆盖,因此您需要使用ActionChains来执行点击。

您需要导入它:

from selenium.webdriver.common.action_chains import ActionChains

然后仅在input之后单击send_keys

input_el = browser.find_element_by_css_selector('#Brand_name')
ActionChains(browser).move_to_element(input_el).click().perform()

使用WebDriverWait来验证您的条件是一个好习惯:

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.action_chains import ActionChains

wait = WebDriverWait(browser, 15)
input_el = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,"#Brand_name")))
ActionChains(browser).move_to_element(input_el).click().perform()