如果要访问页面上的所有数据都需要10k +次lazyload按钮的访问,如何使硒页面的加载效率更高?

如何解决如果要访问页面上的所有数据都需要10k +次lazyload按钮的访问,如何使硒页面的加载效率更高?

我正在用无头的chromedriver抓取特定页面

页面真的很大,要完全加载它,我需要在懒惰的加载按钮上点击10k +次

我点击的次数越多,获得的速度就越慢

有没有办法使过程更快?

代码如下:

def driver_config():
    chrome_options = Options()
    prefs = {"profile.managed_default_content_settings.images": 2}
    chrome_options.add_experimental_option("prefs",prefs)
    chrome_options.page_load_strategy = 'eager'
    chrome_options.add_argument("--headless")
    driver = webdriver.Chrome(options=chrome_options)
    return(driver)

def scroll_the_category_until_the_end(driver,category_url):

    driver.get(category_url)
    
    pbar = tqdm()
    pbar.write('initializing spin')
    
    while True:
        try:
            show_more_button = WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,'//*[@id="root"]/div/div[2]/div[2]/div[2]/button')))
            driver.execute_script("arguments[0].click();",show_more_button)
            pbar.update()
                
        except TimeoutException:
            pbar.write('docking')
            pbar.close()
            break

driver = driver_config()
scroll_the_category_until_the_end(driver,'https://supl.biz/russian-federation/stroitelnyie-i-otdelochnyie-materialyi-supplierscategory9403/')

更新:

我也尝试实施另一种策略,但没有成功:

  • 在每次迭代中删除所有公司信息
  • 清算司机现金

我的假设是,如果执行此操作,DOM将始终干净且快速

driver = driver_config()
driver.get('https://supl.biz/russian-federation/stroitelnyie-i-otdelochnyie-materialyi-supplierscategory9403/')

pbar = tqdm()
pbar.clear()

while True:
    try:    

        for el in driver.find_elements_by_class_name('a_zvOKG8vZ'):
            driver.execute_script("""var element = arguments[0];element.parentNode.removeChild(element);""",el)
        
        button = WebDriverWait(driver,"//*[contains(text(),'Показать больше поставщиков')]")))
        driver.execute_script("arguments[0].click();",button)
        pbar.update()
        driver.execute_script("window.localStorage.clear();")

    except Exception as e:
        pbar.close()
        print(e)
        break

解决方法

首先,网站调用javascript来获取新数据,通过单击“更多结果”按钮来调用HTTP请求,它会调用API,并且响应返回的是加载更多结果页面所需的数据。您可以通过检查页面->网络工具-> XHR,然后单击按钮来查看此请求。它将HTTP GET请求发送到每个产品上都有数据的API。

从调用javascript的网站获取数据的最有效方法是重新设计javascript发出的HTTP请求。

在这种情况下,这比较容易,我将请求复制到XHR的cURL命令中以检查页面,然后使用curl.trillworks.com将其转换为python。

这是在单击更多结果页面之前使用XHR的屏幕。

enter image description here

点击更多结果页面,您会注意到请求是如何填充屏幕的?

enter image description here

在这里,我正在复制cURL请求以获取必要的标头等...

enter image description here

在这里,我正在复制cURL请求以获取必要的标头,等等...然后您可以将其输入curl.trillworks.com,它将请求转换为params,cookie和标头,并为您提供请求包的样板

使用请求包对请求进行处理。输入标头的各个部分,会为您提供cookie,但是在您发出请求时实际上并不需要它们。

最简单的请求是不带标题,参数或cookie的请求,但是大多数API端点都不接受。在这种情况下,在处理了请求包之后,您需要一个用户代理和一些参数,这些参数指定您从API取回哪些数据。实际上,您甚至不需要有效的用户代理。

现在,您可以调用while循环以使HTTP请求的大小保持为8。不幸的是,在参数中更改请求的大小并不能获取全部数据!

编码示例

import requests
import time

i = 8
j = 1

headers = { 
        'user-agent': 'M' 
        }

while True: 
    if response.status_code == 200: 
        params = (
            ('category','9403'),('city','russian-federation'),('page',f'{j}'),('size',f'{i}'),)
        response = requests.get('https://supl.biz/api/monolith/suppliers-catalog/search/',headers=headers,params=params)
        print(response.json()['hits'][0])
        i += 8
        j += 1
        time.sleep(4)
    else: 
        break

输出

样本输出

{'id': 1373827,'type': None,'highlighted': None,'count_days_on_tariff': 183,'tariff_info': {'title_for_show': 'Поставщик Премиум','finish_date': '2021-02-13','url': '/supplier-premium-membership/','start_date': '2020-08-13'},'origin_ru': {'id': 999,'title': 'Санкт-Петербург'},'title': 'ООО "СТАНДАРТ 10"','address': 'Пискаревский проспект,150,корпус 2.','inn': '7802647317','delivery_types': ['self','transportcompany','suppliercars','railway'],'summary': 'Сэндвич-панели: новые,2й сорт,б/у. Холодильные камеры: новые,б/у. Двери для холодильных камер: новые,б/у. Строительство холодильных складов,ангаров и др. коммерческих объектов из сэндвич-панелей. Холодильное оборудование: новое,б/у.','phone': '79219602762','hash_id': 'lMJPgpEz7b','payment_types': ['cache','noncache'],'logo_url': 'https://suplbiz-a.akamaihd.net/media/cache/37/9e/379e9fafdeaab4fc5a068bc90845b56b.jpg','proposals_count': 4218,'score': 42423,'reviews': 0,'rating': '0.0','performed_orders_count': 1,'has_replain_chat': False,'verification_status': 2,'proposals': [{'id': 20721916,'title': 'Сэндвич панели PIR 100','description': 'Сэндвич панели. Наполнение Пенополиизлцианурат ПИР PIR. Толщина 100мм. Длина 3,2 метра. Rall9003/Rall9003. Вналичии 600м2. Количество: 1500','categories': [135],'price': 1250.0,'old_price': None,'slug': 'sendvich-paneli-pir-100','currency': 'RUB','price_details': 'Цена  за шт.','image': {'preview_220x136': 'https://suplbiz-a.akamaihd.net/media/cache/72/4d/724d0ba4d4a2b7d459f3ca4416e58d7d.jpg','image_dominant_color': '#ffffff','preview_140': 'https://suplbiz-a.akamaihd.net/media/cache/67/45/6745bb6f616b82f7cd312e27814b6b89.jpg','hash': 'd41d8cd98f00b204e9800998ecf8427e'},'additional_images': [],'availability': 1,'views': 12,'seo_friendly': False,'user': {'id': 1373827,'name': 'ООО "СТАНДАРТ 10"','phone': '+79219602762','origin_id': 999,'country_id': 1,'origin_title': 'Санкт-Петербург','verified': False,'score': 333,'rating': 0.0,'tariff': {'title_for_show': 'Поставщик Премиум','location': {'lon': 30.31413,'lat': 59.93863}}},{'id': 20722131,'title': 'Сэндвич панели ппу100 б/у,2,37 м','description': 'Сэндвич панели. Наполнение Пенополиуретан ППУ ПУР PUR. Толщина 100 мм. длинна 2,37 метра. rall9003/rall9003. БУ. В наличии 250 м2.','price': 800.0,'slug': 'sendvich-paneli-ppu100-b-u-2-37-m','image': {'preview_220x136': 'https://suplbiz-a.akamaihd.net/media/cache/d1/49/d1498144bc7b324e288606b0d7d98120.jpg','preview_140': 'https://suplbiz-a.akamaihd.net/media/cache/10/4b/104b54cb9b7ddbc6b2f0c1c5a01cdc2d.jpg','views': 4,{'id': 20722293,'title': 'Холодильная камера polair 2.56х2.56х2.1','description': 'Холодильная камера. Размер 2,56 Х 2,1. Камера из сэндвич панелей ППУ80. Камера с дверью. -5/+5 или -18. В наличии. Подберем моноблок или сплит систему. …','categories': [478],'price': 45000.0,'slug': 'holodilnaya-kamera-polair-2-56h2-56h2-1','image': {'preview_220x136': 'https://suplbiz-a.akamaihd.net/media/cache/c1/9f/c19f38cd6893a3b94cbdcbdb8493c455.jpg','preview_140': 'https://suplbiz-a.akamaihd.net/media/cache/4d/b0/4db06a2508cccf5b2e7fe822c1b892a2.jpg','views': 5,{'id': 20722112,'title': 'Сэндвич панели ппу 80 б/у,4 м','description': 'Сэндвич панели. Наполнение ППУ. Толщина 80 мм. длинна 2,4 метра. БУ. В наличии 350 м2.','price': 799.0,'slug': 'sendvich-paneli-ppu-80-b-u-2-4-m','image': {'preview_220x136': 'https://suplbiz-a.akamaihd.net/media/cache/ba/06/ba069a73eda4641030ad69633d79675d.jpg','preview_140': 'https://suplbiz-a.akamaihd.net/media/cache/4f/e9/4fe9f3f358f775fa828c532a6c08e7f2.jpg','views': 8,{'id': 20722117,'title': 'Сэндвич панели ппу 60 мм,99 м','description': 'Сэндвич панели. Наполнение Пенополиуретан ППУ ПУР PUR . Новые. В наличии 600 м2. Толщина 60 мм. длинна 2,99 метров. rall9003/rall9003','price': 1100.0,'slug': 'sendvich-paneli-ppu-60-mm-2-99-m','image': {'preview_220x136': 'https://suplbiz-a.akamaihd.net/media/cache/e2/fb/e2fb6505a5af74a5a994783a5e51600c.jpg','preview_140': 'https://suplbiz-a.akamaihd.net/media/cache/9c/f5/9cf5905a26e6b2ea1fc16d50c19ef488.jpg','views': 10,'lat': 59.93863}}}]}
​

解释

在这里,我们确保在发出另一个请求之前响应状态为200。使用f字符串,我们在while循环的每次迭代中将页面更改1,并将JSON对象的结果大小更改8。我对每个请求都设置了时间限制,因为如果一次推送太多HTTP请求,最终将导致IP被禁止。在服务器上要轻柔!

response.json()方法将JSON对象转换为python字典,您尚未指定什么数据,但是我认为,如果您可以处理python字典,则可以获取所需的数据。

评论

这是参数的来源。您可以在此处查看页面和尺寸数据。

enter image description here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-