当前位置: 首页 > news >正文

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爬虫:动态获取页面

动态网站根据用户的某些操作产生一些结果。例如&#xff0c;当网页仅在向下滚动或将鼠标移动到屏幕上时才完全加载时&#xff0c;这背后一定有一些动态编程。当您将鼠标指针悬停在某些文本上时&#xff0c;它会为您提供一些选项&#xff0c;它还包含一些动态.这是是一篇关于动态…...

大数据平台迁移后yarn连接zookeeper 异常分析

大数据平台迁移后yarn连接zookeeper 异常分析 XX保险HDP大数据平台机房迁移异常分析。 异常现象&#xff1a; 机房迁移后大部分组件都能正常启动Yarn 启动后8088 8042等端口无法访问Hive spark 作业提交到yarn会出现卡死。 【备注】虽然迁移&#xff0c;但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搭建了内网的依赖仓库&#xff0c;需要将前端工程中node_modules中的依赖上传到Nexus上&#xff0c;但是node_modules中的依赖已经是解压后的状态&#xff0c;如果直接机械地将其简单地打包上传到Nexus&#xff0c;那么无法通过npm install下载使用。故有…...

软考高级架构师下篇-16通信系统架构设计理论与实践

目录 1. 引言2. 通信系统网络架构3. 网络构建关键技术4. 网络构建5. 前文回顾1. 引言 此章节主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本节知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中…...

国庆中秋特辑(二)浪漫祝福方式 使用生成对抗网络(GAN)生成具有节日氛围的画作

要用人工智能技术来庆祝国庆中秋&#xff0c;我们可以使用生成对抗网络&#xff08;GAN&#xff09;生成具有节日氛围的画作。这里将使用深度学习框架 TensorFlow 和 Keras 来实现。 一、生成对抗网络&#xff08;GAN&#xff09; 生成对抗网络&#xff08;GANs&#xff0c;…...

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 实现前端项目工程化

通过官方脚手架初始化项目 第一种方式&#xff0c;这是使用vite命令创建&#xff0c;这种方式除了可以创建vue项目&#xff0c;还可以创建其他类型的项目&#xff0c;比如react项目 npm init vitelatest 第二种方式&#xff0c;这种方式是vite专门为vue做的配置&#xff0c;…...

Java动态代理Aop的好处

1. 预备知识-动态代理 1.1 什么是动态代理 动态代理利用Java的反射技术(Java Reflection)生成字节码&#xff0c;在运行时创建一个实现某些给定接口的新类&#xff08;也称"动态代理类"&#xff09;及其实例。 1.2 动态代理的优势 动态代理的优势是实现无侵入式的代…...

各种存储性能瓶颈如何分析与优化?

【摘要】本文结合实践剖析存储系统的架构及运行原理&#xff0c;深入分析各种存储性能瓶颈场景&#xff0c;并提出相应的性能优化手段&#xff0c;希望对同行有一定的借鉴和参考价值。 【作者】陈萍春&#xff0c;现就职于保险行业&#xff0c;拥有多年的系统、存储以及数据备…...

Android StateFlow初探

Android StateFlow初探 前言&#xff1a; 最近在学习StateFlow&#xff0c;感觉很好用&#xff0c;也很神奇&#xff0c;于是记录了一下. 1.简介&#xff1a; StateFlow 是一个状态容器式可观察数据流&#xff0c;可以向其收集器发出当前状态更新和新状态更新。还可通过其 …...

Docker Compose初使用

简介 Docker-Compose项目是Docker官方的开源项目&#xff0c;负责实现对Docker容器集群的快速编排。 Docker-Compose将所管理的容器分为三层&#xff0c;分别是 工程&#xff08;project&#xff09;&#xff0c;服务&#xff08;service&#xff09;以及容器&#xff08;cont…...

测试与FastAPI应用数据之间的差异

【squids.cn】 全网zui低价RDS&#xff0c;免费的迁移工具DBMotion、数据库备份工具DBTwin、SQL开发工具等 当使用两个不同的异步会话来测试FastAPI应用程序与数据库的连接时&#xff0c;可能会出现以下错误&#xff1a; 在测试中&#xff0c;在数据库中创建了一个对象&#x…...

WebStorm 2023年下载、安装教程、亲测有效

文章目录 简介安装步骤常用快捷键 简介 WebStorm 是JetBrains公司旗下一款JavaScript 开发工具。已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源&#xff0c;继承了IntelliJ IDEA强大的JS部分的…...

k8s储存卷

卷的类型 In-Tree存储卷插件 ◼ 临时存储卷 ◆emptyDir ◼ 节点本地存储卷 ◆hostPath, local ◼ 网络存储卷 ◆文件系统&#xff1a;NFS、GlusterFS、CephFS和Cinder ◆块设备&#xff1a;iSCSI、FC、RBD和vSphereVolume ◆存储平台&#xff1a;Quobyte、PortworxVolume、Sto…...

【解决Win】“ 无法打开某exe提示无法成功完成操作,因为文件包含病毒或潜在的垃圾软件“

在下载某个应用程序&#xff0c;打开时出现了“无法成功完成操作因为文件包含病毒或潜在垃圾”的提示&#xff0c;遇到这个情况怎么解决&#xff1f; 下面为大家分享故障原因及具体的处理方法。 故障原因 是由于杀毒 防护等原因引起的。 解决方案 打开Windows 安全中心 选择…...

SpringBoot调用ChatGPT-API实现智能对话

目录 一、说明 二、代码 2.1、对话测试 2.2、单次对话 2.3、连续对话 2.4、AI绘画 一、说明 我们在登录chatgpt官网进行对话是不收费的&#xff0c;但需要魔法。在调用官网的API时&#xff0c;在代码层面上使用&#xff0c;通过API KEY进行对话是收费的&#xff0c;不过刚…...

element-table出现错位解决方法

先看示例图&#xff0c;这个在开发中还是很常遇到的&#xff0c;在table切换不同数据时或者切换页面时&#xff0c;容易出现&#xff1a; 解决方法很简单&#xff0c;官方有提供方法&#xff1a; 我们可以在重新渲染数据后&#xff1a; this.$nextTick(() > {this.$refs.…...

DC电源模块具有不同的安装方式和安全规范

BOSHIDA DC电源模块具有不同的安装方式和安全规范 DC电源模块是将低压直流电转换为需要的输出电压的装置。它们广泛应用于各种领域和行业&#xff0c;如通信、医疗、工业、家用电器等。安装DC电源模块应严格按照相关的安全规范进行&#xff0c;以确保其正常运行和安全使用。 D…...

zabbix自定义监控、钉钉、邮箱报警

目录 一、实验准备 二、安装 三、添加监控对象 四、添加自定义监控项 五、监控mariadb 1、添加模版查看要求 2、安装mariadb、创建用户 3、创建用户文件 4、修改监控模版 5、在上述文件中配置路径 6、重启zabbix-agent验证 六、监控NGINX 1、安装NGINX&#xff0c…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...