【问题标题】:Python Selenium. Parallel if loop蟒蛇硒。并行 if 循环
【发布时间】:2020-12-27 18:14:13
【问题描述】:
import csv
import time
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
from csv import reader
from selenium.webdriver.common.action_chains import ActionChains
from selenium.common.exceptions import NoSuchElementException


chrome_options = Options()
scroll = 5
chrome_options.add_experimental_option("useAutomationExtension", False)
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
header_added = False
header_added1 = False
url = "url"
driver = webdriver.Chrome(executable_path='C:/chromedriver.exe', options=chrome_options)
driver.maximize_window()
driver.get(url)
time.sleep(3)
search_city = input("Enter the city :")
res_n = input("Enter the Restaurant's name :")
search = driver.find_element_by_xpath('//input[@name="location"]').send_keys(search_city)
time.sleep(2)
driver.find_element_by_xpath('//*[@id="root"]/div[1]/div[1]/div/div[1]/div[1]/div/div[2]/div/div[3]/div[1]/span[2]').click()
time.sleep(3)
driver.find_element_by_xpath('/html/body/div[1]/div[1]/header/div/div/ul/li[5]/div/a/span[1]').click()
time.sleep(1)
search_res = driver.find_element_by_class_name('_2BJMh').send_keys(res_n.lower())
time.sleep(5)
driver.find_element_by_class_name('_2BJMh').send_keys(Keys.RETURN)
time.sleep(5)

try:
    driver.find_element_by_class_name('_3FR5S').click()
    time.sleep(5)
except:
    print("restaurant not open")
    driver.quit()

html = driver.find_element_by_tag_name('html')



def get_items():
    global header_added
    global item_dvs
    cats = driver.find_elements_by_class_name('D_TFT')
    cats[1].click()
    time.sleep(3)
    item_dvs = driver.find_elements_by_class_name('_2wg_t')

    for div in item_dvs:
        name = div.find_element_by_class_name('styles_itemNameText__3bcKX')
        print(name.text)
        price = div.find_element_by_class_name('rupee')
        print(price.text)
        if div.find_elements_by_class_name('styles_itemDesc__MTsVd'):
            desc = div.find_element_by_class_name('styles_itemDesc__MTsVd').text
        else:
            desc = None
        if div.find_element_by_css_selector('div._1C1Fl._23qjy'):
            element = div.find_element_by_css_selector('div._1C1Fl._23qjy')
            print("found")
            driver.execute_script("arguments[0].scrollIntoView();", element)
            add = div.find_element_by_css_selector('._1RPOp')
            driver.execute_script("arguments[0].click();", add)
            time.sleep(1)
            add_ons = driver.find_element_by_class_name('_3UzO2').text
            print(add_ons)
            driver.find_element_by_css_selector('#modal-placeholder > div:nth-child(3) > div > div._1Kr-y._3EeZR > div > div._1EZLh > div > button').click()

        else:
            add_ons = None
        dict1 = {'Item Name': name.text, "Price": price.text, "Add Ons :": add_ons, "Description": desc}
        with open(f'{search_city}_{res_n}.csv', 'a+', encoding='utf-8-sig') as f:
            w = csv.DictWriter(f, dict1.keys())
            if not header_added:
                w.writeheader()
                header_added = True
            w.writerow(dict1)


get_items()

is_cust 循环不断运行,一遍又一遍地打开同一个元素,而其余代码继续运行到下一个 divs。这里有什么问题?

【问题讨论】:

  • 我从不使用 xPath,但它们是双向的 tutorialspoint.com/…... 这可能是这里的原因。如果您使用 cssSelector,您的 div.find_element_by_css_selector 只会检索父 div 的子元素
  • 您的if/else 声明也是错误的。您的 is_cust 将返回一个元素或引发异常。它永远不会是假的
  • 怎么样?什么是解决方案?
  • 您正在使用父元素来查找嵌套元素(div.find...),但从我读到的内容来看,xPath 不会太在意它。我提供了一个答案,但是没有 html 代码很难给你一个准确的解释/解决方案。需要注意的一件事是您正在混合(驱动程序和 div)来搜索您的元素。为什么?

标签: python python-3.x selenium loops web-scraping


【解决方案1】:

xPath 是bidirectional,可能是这里的原因。

使用 cssSelector 试试这个代码:

for div in item_dvs:
    #Do Something

    try:   
        is_cust = div.find_element_by_css_selector('._1C1Fl._23qjy')
        print("found")
    except NoSuchElementException:
        continue

    driver.execute_script("arguments[0].scrollIntoView();", is_cust)
    add = div.find_element_by_css_selector('._1RPOp')
    driver.execute_script("arguments[0].click();", add)
    time.sleep(1)
    # Not sure why for this one you had driver instead of div. Suspect div should be 
    add_ons = div.find_element_by_class_name('_26cJ9').text
    div.find_element_by_css_selector('#modal-placeholder > div:nth-child(3) >   div > div._1Kr-y._3EeZR > div > div._1EZLh > div > button').click()

更新 从您更新的代码中,您正在使用大量的硬编码睡眠。我会建议使用WebDriverWaitexpected_conditions

更多信息在这里:Wait from Selenium

需要进口:

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

在创建驱动程序后添加代码:

等待时间 = 5 wait = WebDriverWait(驱动程序,wait_time)

不要像这样使用睡眠:

time.sleep(5)
driver.find_element_by_class_name('_2BJMh').send_keys(Keys.RETURN)
time.sleep(5)

用途:

wait.until(EC.presence_of_element_located((By.CLASS_NAME, '_2BJMh'))).send_keys(res_n.lower())

不要两次收集元素。使用find_elements_by*然后验证长度:

descs = wait.until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'styles_itemDesc__MTsVd')))
if len(descs) > 0:
    desc = descs[0].text
else:
    desc = None

【讨论】:

  • 您会看到click。这是一个不同的窗口。这就是driver 的原因。另外,我尝试使用css。结果相同。我将重新运行它以确保。
  • 它起作用了!..唉,只适用于几个 div。看起来你已经解决了这个问题..不知道为什么它不能解决其他问题......让我检查一下。
  • 很好.. 到达那里!当它不起作用时,你能提供更多信息吗?如果您打开一个新窗口/弹出窗口,您可能需要引入 WebDriverWait 以允许将元素加载到 DOM 中
  • 你能分享 html/网站吗?如果是这样,请提供您如何检索item_dvs
  • 不,就像你提到的那样。当它没有找到元素时,它不会去其他地方。引发错误。
猜你喜欢
  • 2016-05-28
  • 2021-06-28
  • 2021-07-07
  • 2023-02-06
  • 1970-01-01
  • 2021-10-11
  • 1970-01-01
  • 2018-06-17
  • 1970-01-01
相关资源
最近更新 更多