当前位置: 首页 > 知识库问答 >
问题:

如何从网页操作懒惰加载方法中获取所有数据?

西门逸仙
2023-03-14

我已经用python编写了一些脚本,使用selenium从redmart网站上获取不同产品的名称和价格。我的刮板点击一个链接,转到它的目标页面,从那里解析数据。然而,这个爬虫程序面临的问题是,由于网页加载速度慢,它只能从页面上刮取很少的项目。如何从控制延迟加载过程的每个页面获取所有数据?我尝试了“执行脚本”方法,但我做得不对。以下是我正在尝试的脚本:

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

driver = webdriver.Chrome()
driver.get("https://redmart.com/bakery")
wait = WebDriverWait(driver, 10)

counter = 0    
while True:

    try:
        wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "li.image-facets-pill")))
        driver.find_elements_by_css_selector('img.image-facets-pill-image')[counter].click()      
        counter += 1    
    except IndexError:
        break 

    # driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

    for elems in wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "li.productPreview"))):
        name = elems.find_element_by_css_selector('h4[title] a').text
        price = elems.find_element_by_css_selector('span[class^="ProductPrice__"]').text
        print(name, price)

    driver.back()
driver.quit() 

共有1个答案

澹台聪
2023-03-14

我想您可以使用Selenium来实现这一点,但如果您关心的是速度,那么@Andersson在Stackoverflow的另一个问题中为您编写了代码,那么,您应该复制站点使用的API调用,并从JSON中提取数据,就像站点所做的那样。

如果您使用Chrome Inspector,您将看到外部while循环中每个类别的站点(原始代码中的try块)都调用一个API,该API返回站点的整体类别。可以按如下方式检索所有这些数据:

categories_api = 'https://api.redmart.com/v1.5.8/catalog/search?extent=0&depth=1'
r = requests.get(categories_api).json()

对于下一个API调用,您需要获取与面包店相关的URI。可以这样做:

bakery_item = [e for e in r['categories'] if e['title'] == 'Bakery]
children = bakery_item[0]['children']
uris = [c['uri'] for c in children]

URI现在将是一个字符串列表(['bakery-bread'、'Breaks-treats-212'、'sliced-bread-212'、'wraps pita indian breads'、'rolls-buns-212'、'Bakers-Artisal-breads-212'、'Frient-part-bake'、'long life bread toast'、'speciality-212')),您将传递给Chrome Inspector发现的另一个API,网站用来加载内容的。

此API具有以下形式(默认情况下返回较小的页面大小,但我将其增加到500以确保在一个请求中获得所有数据):

items_API = 'https://api.redmart.com/v1.5.8/catalog/search?pageSize=500&sort=1024&category={}'

for uri in uris:
    r = requests.get(items_API.format(uri)).json()
    products = r['products']
    for product in products:
        name = product['title']
        # testing for promo_price - if its 0.0 go with the normal price
        price = product['pricing']['promo_price']
        if price == 0.0:
            price = product['pricing']['price']
        print("Name: {}. Price: {}".format(name, price))

编辑:如果您仍然想坚持使用selenium,可以插入类似这样的内容来解决延迟加载问题。关于滚动的问题以前已经回答过好几次了,所以你的问题实际上是重复的。将来,您应该展示您尝试过的内容(您自己在执行部分的努力)并显示回溯。

check_height = driver.execute_script("return document.body.scrollHeight;") 
while True:
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    time.sleep(5)
    height = driver.execute_script("return document.body.scrollHeight;") 
    if height == check_height: 
        break 
     check_height = height
 类似资料:
  • 我有一个数据表的问题-懒加载。我认为问题是在IdiomasBean.java(TableBean.java),如果我把: 我得到了正确的数据表,但是<代码>按排序、筛选和不起作用。 我得到:java。lang.NullPointerException这里是堆栈跟踪: 下面是代码的其余部分: 指数xhtml diomasBean.java 懒散的数据模型。JAVA IdiomasBo.java 习语

  • 我试图在primefaces数据表设置中实现延迟加载。目前,在没有延迟加载实现的情况下,这是可行的,但是在实现延迟加载后,我在datatable中没有得到任何数据。但是,我可以在我的LoadData方法中打印我的列表,以验证数据是否正在加载到我的列表中,但一旦返回我的LazyModel并尝试加载datatable,似乎就会出现问题。这可能只是我忽略的一些简单的事情。非常感谢您的帮助! 这是我的屏幕

  • 我还有以下两个类,它们是由我的测试模型生成的: 在DBContext的构造函数中,我显式启用了延迟加载,甚至不需要: 后来我打电话给房子列表: 在标记的断点之后,我预期,由于延迟加载,与房屋相关联的所有人员此时都不会加载。我没有访问一个人,为什么要加载他们?但是它们被加载,因为我的调试器向我显示了所有的name属性。 有人能解释一下这种行为吗?为什么惰性加载不起作用?

  • 我创建了一个jHipster示例应用程序(url:http://jhipster.github.io/creating_an_app.html),使用实体子生成器,我创建了一个事件实体,当我检索所有时,该实体与EventImages、EventTickets和EventQuestions具有一个域关系(应用程序在本地计算机上运行,api url:http://127.0.0.1:8080/api/

  • 我们有许多通过接口扩展JpaRepository模式定义的存储库。当运行集成测试或应用程序的某些入口点时,我们只需要这些存储库的一个非常小的子集。 我们可以懒洋洋地加载实际的存储库隐含吗? 相当于@懒在@豆上的东西?注意:我至少尝试了用@lazy注释存储库接口的简单解决方案,但没有成功。

  • 本文向大家介绍php获取网页上所有链接的方法,包括了php获取网页上所有链接的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了php取得网页上所有链接的方法。分享给大家供大家参考。具体实现方法如下: 希望本文所述对大家的php程序设计有所帮助。