【问题标题】:Scraping with Selenium on Dynamic Content (MULTIPLE Pages) - Python在动态内容(多页)上使用 Selenium 抓取 - Python
【发布时间】:2021-04-28 17:51:39
【问题描述】:

我一直在尝试从 Doordash 中抓取动态内容(餐厅名称、评级、餐厅类型),我想要抓取的不仅仅是一个网站,而是多个网站,可能在一个 100 到 1000 个页面上Doordash 上的单个域。

我得到了一个“单次刮擦”,但是,当我使用下面的代码时,它给了我一个很长的错误

def ScrapeDoorDash(df):
for i in df:
    url = df[i]
    print(url)
    driver = webdriver.Chrome(ChromeDriverManager().install())
    driver.get(url)
    restaurantname = driver.find_element_by_xpath('//*[@id="root"]/div/div[1]/div[2]/div/div[1]/header/div[2]/h1').text
    rating = driver.find_element_by_xpath('//*[@id="root"]/div/div[1]/div[2]/div/div[1]/header/div[2]/div[1]/div[3]/div/span[1]').text
    #estauranttype = driver.find_element_by_xpath('//*[@id="root"]/div/div[1]/div[2]/div/div[1]/header/div[2]/div[1]/div[1]/span').text
    #Store into / print Out
    print (restaurantname, rating, restauranttype)

XPath 已经正确,但我注意到 Selenium 每次都会打开 chrome,让它在抓取内容之前完成加载。在我上面提供的代码中,我注意到在第一页加载完成之前已经弹出了错误。

有没有办法实现一些代码来“暂停 for 循环”,让它在移动到“URL 数据帧”中的下一个项目之前先加载和抓取?

请使用以下创建 URL 数据框

url = ["https://www.doordash.com/store/popeyes-toronto-254846/en-CA", "https://www.doordash.com/store/sunset-grill-toronto-211003/en-CA"]

url = pd.DataFrame(数据) 网址

错误消息如下(它更长)。它说没有这样的元素,但是,当页面完成加载时,我单独尝试了它,找到了这些元素并抓取了正确的内容。只是当我尝试抓取多个页面时,它给了我一个错误。

任何帮助将不胜感激!

【问题讨论】:

    标签: python selenium web-scraping


    【解决方案1】:

    您可以使用 time 模块来暂停脚本。

    import time
    
    time.sleep(2)
    

    把它放在请求线和花键线之间。

    脚本将在括号中的时间暂停,以秒为单位。在本例中为 2 秒。

    做一些测试,并在最短的时间内让脚本工作。

    【讨论】:

      【解决方案2】:

      正如 Fabix 所说,time 模块将允许您在从网页中检索元素之前让代码休眠。

      此外,为了防止 chrome 驱动程序为每个 url 打开一个新实例,请在循环之外打开浏览器。

      import time
      
      def ScrapeDoorDash(urls):
          with webdriver.Chrome(ChromeDriverManager().install()) as driver:
              for url in urls:
                  print(url)
                  driver.get(url)
                  time.sleep(3)
                  restaurantname = driver.find_element_by_xpath('//*[@id="root"]/div/div[1]/div[2]/div/div[1]/header/div[2]/h1').text
                  rating = driver.find_element_by_xpath('//*[@id="root"]/div/div[1]/div[2]/div/div[1]/header/div[2]/div[1]/div[3]/div/span[1]').text
                  restauranttype = driver.find_element_by_xpath('//*[@id="root"]/div/div[1]/div[2]/div/div[1]/header/div[2]/div[1]/div[1]/span').text
                  #Store into / print Out
                  print (restaurantname, rating, restauranttype)
      

      通过使用with webdriver.Chrome(ChromeDriverManager().install()) as driver:,驱动程序连接将在您退出语句后关闭。

      【讨论】:

        【解决方案3】:

        我建议你使用waits。它可能比time.sleep 更好,因为你不必自己寻找完美的时间,它更可靠,但它使代码更大(尽管你可以为它创建函数):

        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.common.exceptions import TimeoutException
        
        xpath = "..."
        wait_time = 10
        # driver will try to find element by xpath for 10 seconds
        # if could not find, will raise TimeoutException
        
        interval = 0.1 # time between attempts to search xpath. 0.5 seconds by default
        
        # returns found element
        elem = WebDriverWait(driver, wait_time , interval ).until(EC.presence_of_element_located((By.XPATH, xpath)))
        some = elem.text
        

        对于每次打开浏览器,请参阅 ZacLanghorne 的回答

        【讨论】:

          猜你喜欢
          • 2019-11-05
          • 2013-07-10
          • 2023-01-29
          • 2020-05-24
          • 1970-01-01
          • 1970-01-01
          • 2016-09-15
          • 2012-01-28
          • 1970-01-01
          相关资源
          最近更新 更多