Python爬虫:动态获取页面

动态网站根据用户的某些操作产生一些结果。例如,当网页仅在向下滚动或将鼠标移动到屏幕上时才完全加载时,这背后一定有一些动态编程。当您将鼠标指针悬停在某些文本上时,它会为您提供一些选项,它还包含一些动态.这是是一篇关于动态网页的非常好的详细文章。
您可以在互联网上找到许多文章来帮助您抓取动态网站。这篇文章是我抓取Doordash.com 的方法。一切都是逐步进行的。
抓取动态网页的一个必要条件是在浏览器中加载其 javascript。而且,这是通过无头浏览器完成的(稍后会解释)。
我的目标是从 Doordash.com 上抓取 5 万多个菜单。
[请记住,除了某些特定条件外,Python 区分大小写。]
让我们通过导入一些必要的库以及我们可能需要的一些辅助库来开始编码。正如标题所示,我将使用 Selenium 库
#importing required libraries
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
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support.wait import WebDriverWait
from selenium_move_cursor.MouseActions import move_to_element_chrome
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
import js
import json
import numpy as np
import time
import pandas as pd #to save CSV file
from bs4 import BeautifulSoup
import ctypes #to create text popup
Selenium 的“Webdriver”模块是最重要的,因为它将控制浏览器。为了控制浏览器,有一定的要求,这些要求已经以驱动程序的形式设置,例如“google chrome”的“chromedriver”。我将使用“ chromedriver ”。而且,要使用它,我们需要告诉“webdriver”它。
让我们为“webdriver”定义这个浏览器,并将其选项设置为“--headless”。
#defining browser and adding the “ — headless” argument
opts = Options()
opts.add_argument(‘ — headless’)
driver = webdriver.Chrome(‘chromedriver’, options=opts)
这个“无头”参数被设置为处理动态网页,加载它们的 javascript。
以下是 URL 以及使用“webdriver”打开 URL 的代码。
url = 'https://www.doordash.com/en-US'
driver.maximize_window() #maximize the window
driver.get(url) #open the URL
driver.implicitly_wait(220) #maximum time to load the link
我将 chromedriver 放在项目目录中以保持路径简单。或者可以使用“OS”模块定义路径来代替“chromedriver”。
第一种方法:
我对 Doordash.com 进行了概述,以了解我们的结果(即菜单)的位置以及如何访问它们。
该脚本将
1-打开浏览器
#defining browser and adding the “ — headless” argument
opts = Options()
opts.add_argument(‘ — headless’)
driver = webdriver.Chrome(‘chromedriver’, options=opts)
2- 搜索 URL (doordash.com)
url = 'https://www.doordash.com/en-US'
driver.maximize_window() #maximize the window
driver.get(url) #open the URL
driver.implicitly_wait(220) #maximum time to load the link
3-向下滚动以加载整个页面
driver.execute_script("window.scrollTo(0, document.body.scrollHeight,)")
4-导航至“您附近的热门美食”
5-点击“Pizza Near Me”(我认为这对于 50k+ 菜单来说已经足够了)
time.sleep(5)
element = driver.find_element_by_xpath(‘//h2[text()=”Top Cuisines Near You”]’).find_element_by_xpath(‘//a[@class=”sc-hrWEMg fFHnHa”]’)
time.sleep(5)
element.click()
driver.implicitly_wait(220)
6-加载页面和页面范围
#define the lists
names = []
prices = []
#extract the number of pages for the searched product
driver.implicitly_wait(120)
time.sleep(3)
result = driver.page_source
soup = BeautifulSoup(result, 'html.parser')
page = list(soup.findAll('div', class_="sc-cvbbAY htjLED"))
start = int(page[2].text)
print('1st page:',start)
last = int(page[-2].text)
final = last +1
print('last page:',final)
#getting numbers out of string of pages
print(f'first page:{start}, and last page with + 1: {final}')
7-点击各个商店(页面已设置默认位置中国,因此无需担心位置)
#set the page_range And
#lloop all the pages of store
for i in range(start, final, 1):time.sleep(7)#find the number of stores per pagelist_length = len(driver.find_elements_by_xpath(“//div[@class=’StoreCard_root___1p3uN’]”))products_per_page = list_length+1#loop through the menues of each store on a pagefor x in range(0, list_length, 1):time.sleep(7)driver.execute_script(“window.scrollTo({top:75, behavior:’smooth’,})”) store_name = driver.find_elements_by_xpath(‘//div[@class=”StoreCard_storeDetail___3C0TX”]’)strnm = store_name[x]print(f’{x}- ‘, strnm.text)time.sleep(4)element=driver.find_elements_by_xpath(“//div[@class=’StoreCard_storeDetail___3C0TX’]”)click = element[x]move_to_element_chrome(driver, click, display_scaling=100)time.sleep(7)click.click()driver.implicitly_wait(360)
8-抓取菜单并抓取后返回商店页面
time.sleep(20)result = driver.page_sourcetime.sleep(11)soup = BeautifulSoup(result, ‘html.parser’)div = soup.find(‘div’, class_=”sc-jwJjzT kjdEnq”)if div is not None:time.sleep(25)for i in div.findAll(‘div’, class_=”sc-htpNat Ieerz”):pros = i.find(‘div’, class_=”sc-jEdsij hukZqW”)print(‘writing (‘, pros.text, ‘) to disk’)names.append(pros.text)rates = i.find(‘span’, class_=”sc-bdVaJa eEdxFA”)#if there is no price for the food, append ‘N/A’ in the list of ‘prices’if rates is not None:print(‘price: ‘, rates.text)rate = rates.textelse:print(‘N/A’)rate = ‘N/A’prices.append(rate)driver.back()
9-检查名称列表中的菜单数量
length = len(names)
完成列表中大约 10000 个菜单后中断循环,并通过弹出窗口通知我们,否则重复循环
#if menu record reaches the target, exit the script and produce target completion message boxif ((length > 10000) and (length <10050)):ctypes.windll.user32.MessageBoxW(0, f”Congratulations! We have succefully scraped {length} menues.”, “Project Completion”, 1)breakelse:driver.back()continue
10-整个过程将保持循环,直到我们得到大约 10000 个菜单。
11-如果在抓取一页上的所有商店时未达到 10000 目标,请单击“下一步”按钮进行抓取
#after scraping each store on a page, it will tell that it is going to next pageprint(f’Now moving to page number {i}’)#click next page buttondriver.find_elements_by_xpath(‘//div[@class=”sc-gGBfsJ jFaVNA”]’)[1].click()
12-将结果保存为 CSV 文件。
#save to dataframe
df = pd.DataFrame({‘Name’:names, ‘Price’:prices})
#export as csv file
df.to_csv(‘doordash_menues.csv’)

相关文章:
Python爬虫:动态获取页面
动态网站根据用户的某些操作产生一些结果。例如,当网页仅在向下滚动或将鼠标移动到屏幕上时才完全加载时,这背后一定有一些动态编程。当您将鼠标指针悬停在某些文本上时,它会为您提供一些选项,它还包含一些动态.这是是一篇关于动态…...
大数据平台迁移后yarn连接zookeeper 异常分析
大数据平台迁移后yarn连接zookeeper 异常分析 XX保险HDP大数据平台机房迁移异常分析。 异常现象: 机房迁移后大部分组件都能正常启动Yarn 启动后8088 8042等端口无法访问Hive spark 作业提交到yarn会出现卡死。 【备注】虽然迁移,但IP不变。 1. Yarn连…...
Ubuntu Nginx 配置 SSL 证书
首先需要在 Ubuntu 中安装 Nginx 服务, 打开终端执行以下命令: $ sudo apt update $ sudo apt install nginx -y然后启动 Nginx 服务并设置为开机时自动启动, 执行以下命令: $ sudo systemctl start nginx $ sudo systemctl enable nginx最后再验证一下 Nginx 服务的当前状态…...
将本地前端工程中的npm依赖上传到Nexus
【问题背景】 用Nexus搭建了内网的依赖仓库,需要将前端工程中node_modules中的依赖上传到Nexus上,但是node_modules中的依赖已经是解压后的状态,如果直接机械地将其简单地打包上传到Nexus,那么无法通过npm install下载使用。故有…...
软考高级架构师下篇-16通信系统架构设计理论与实践
目录 1. 引言2. 通信系统网络架构3. 网络构建关键技术4. 网络构建5. 前文回顾1. 引言 此章节主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本节知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中…...
国庆中秋特辑(二)浪漫祝福方式 使用生成对抗网络(GAN)生成具有节日氛围的画作
要用人工智能技术来庆祝国庆中秋,我们可以使用生成对抗网络(GAN)生成具有节日氛围的画作。这里将使用深度学习框架 TensorFlow 和 Keras 来实现。 一、生成对抗网络(GAN) 生成对抗网络(GANs,…...
stm32 串口发送和接收
串口发送 #include "stm32f10x.h" // Device header #include <stdio.h> #include <stdarg.h>//初始化串口 void Serial_Init() {//开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Pe…...
Vite + Vue3 实现前端项目工程化
通过官方脚手架初始化项目 第一种方式,这是使用vite命令创建,这种方式除了可以创建vue项目,还可以创建其他类型的项目,比如react项目 npm init vitelatest 第二种方式,这种方式是vite专门为vue做的配置,…...
Java动态代理Aop的好处
1. 预备知识-动态代理 1.1 什么是动态代理 动态代理利用Java的反射技术(Java Reflection)生成字节码,在运行时创建一个实现某些给定接口的新类(也称"动态代理类")及其实例。 1.2 动态代理的优势 动态代理的优势是实现无侵入式的代…...
各种存储性能瓶颈如何分析与优化?
【摘要】本文结合实践剖析存储系统的架构及运行原理,深入分析各种存储性能瓶颈场景,并提出相应的性能优化手段,希望对同行有一定的借鉴和参考价值。 【作者】陈萍春,现就职于保险行业,拥有多年的系统、存储以及数据备…...
Android StateFlow初探
Android StateFlow初探 前言: 最近在学习StateFlow,感觉很好用,也很神奇,于是记录了一下. 1.简介: StateFlow 是一个状态容器式可观察数据流,可以向其收集器发出当前状态更新和新状态更新。还可通过其 …...
Docker Compose初使用
简介 Docker-Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。 Docker-Compose将所管理的容器分为三层,分别是 工程(project),服务(service)以及容器(cont…...
测试与FastAPI应用数据之间的差异
【squids.cn】 全网zui低价RDS,免费的迁移工具DBMotion、数据库备份工具DBTwin、SQL开发工具等 当使用两个不同的异步会话来测试FastAPI应用程序与数据库的连接时,可能会出现以下错误: 在测试中,在数据库中创建了一个对象&#x…...
WebStorm 2023年下载、安装教程、亲测有效
文章目录 简介安装步骤常用快捷键 简介 WebStorm 是JetBrains公司旗下一款JavaScript 开发工具。已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的…...
k8s储存卷
卷的类型 In-Tree存储卷插件 ◼ 临时存储卷 ◆emptyDir ◼ 节点本地存储卷 ◆hostPath, local ◼ 网络存储卷 ◆文件系统:NFS、GlusterFS、CephFS和Cinder ◆块设备:iSCSI、FC、RBD和vSphereVolume ◆存储平台:Quobyte、PortworxVolume、Sto…...
【解决Win】“ 无法打开某exe提示无法成功完成操作,因为文件包含病毒或潜在的垃圾软件“
在下载某个应用程序,打开时出现了“无法成功完成操作因为文件包含病毒或潜在垃圾”的提示,遇到这个情况怎么解决? 下面为大家分享故障原因及具体的处理方法。 故障原因 是由于杀毒 防护等原因引起的。 解决方案 打开Windows 安全中心 选择…...
SpringBoot调用ChatGPT-API实现智能对话
目录 一、说明 二、代码 2.1、对话测试 2.2、单次对话 2.3、连续对话 2.4、AI绘画 一、说明 我们在登录chatgpt官网进行对话是不收费的,但需要魔法。在调用官网的API时,在代码层面上使用,通过API KEY进行对话是收费的,不过刚…...
element-table出现错位解决方法
先看示例图,这个在开发中还是很常遇到的,在table切换不同数据时或者切换页面时,容易出现: 解决方法很简单,官方有提供方法: 我们可以在重新渲染数据后: this.$nextTick(() > {this.$refs.…...
DC电源模块具有不同的安装方式和安全规范
BOSHIDA DC电源模块具有不同的安装方式和安全规范 DC电源模块是将低压直流电转换为需要的输出电压的装置。它们广泛应用于各种领域和行业,如通信、医疗、工业、家用电器等。安装DC电源模块应严格按照相关的安全规范进行,以确保其正常运行和安全使用。 D…...
zabbix自定义监控、钉钉、邮箱报警
目录 一、实验准备 二、安装 三、添加监控对象 四、添加自定义监控项 五、监控mariadb 1、添加模版查看要求 2、安装mariadb、创建用户 3、创建用户文件 4、修改监控模版 5、在上述文件中配置路径 6、重启zabbix-agent验证 六、监控NGINX 1、安装NGINX,…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
