Python爬虫技术 第20节 模拟用户交互

Python爬虫技术是一种自动化获取网页数据的方法。模拟用户交互是其中的一个高级主题,通常用于处理那些需要用户输入、点击按钮或者执行其他交互操作才能加载数据的动态网站。

下面我会分步骤介绍如何使用Python来模拟这些用户交互:

1. 基础爬虫知识

在开始之前,你需要了解一些基本的爬虫知识:

  • HTML: 网页的基本结构。
  • CSS Selectors/XPath: 用来定位HTML元素的方法。
  • Requests/HTTP: 发送网络请求的基础。
  • BeautifulSoup/Scrapy: Python中常用的解析HTML的库。

2. 使用Selenium进行模拟

对于需要模拟用户交互的场景,Selenium 是一个非常强大的工具。它允许你控制浏览器并执行各种操作,比如点击按钮、填写表单等。

安装Selenium:
pip install selenium
安装WebDriver:

你需要根据你的浏览器版本下载对应的WebDriver。例如,如果你使用的是Chrome,你需要下载ChromeDriver。

示例代码:

以下是一个简单的例子,展示如何使用Selenium打开一个网站,填写表单,并提交表单。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time# 设置webdriver路径
driver_path = '/path/to/chromedriver'
browser = webdriver.Chrome(driver_path)# 打开网页
url = 'http://example.com/login'
browser.get(url)# 寻找用户名和密码输入框
username_input = browser.find_element('id', 'username')
password_input = browser.find_element('id', 'password')# 输入用户名和密码
username_input.send_keys('your_username')
password_input.send_keys('your_password')# 提交表单
password_input.send_keys(Keys.RETURN)# 等待页面加载完成
time.sleep(5)# 关闭浏览器
browser.quit()

3. 使用Playwright

Playwright 是一个现代的爬虫框架,支持多种浏览器,包括Chromium, Firefox 和 WebKit。它的性能通常比Selenium更好。

安装Playwright:
pip install playwright
示例代码:

下面是一个使用Playwright登录的例子。

import asyncio
from playwright.async_api import async_playwrightasync def main():async with async_playwright() as p:# 启动浏览器browser = await p.chromium.launch(headless=False)page = await browser.new_page()# 访问登录页面await page.goto('http://example.com/login')# 填写用户名和密码await page.fill('input[name="username"]', 'your_username')await page.fill('input[name="password"]', 'your_password')# 点击登录按钮await page.click('button[type="submit"]')# 等待页面加载完成await page.wait_for_load_state('networkidle')# 获取页面内容content = await page.content()print(content)# 关闭浏览器await browser.close()asyncio.run(main())

注意事项

  • 反爬机制: 很多网站都有反爬措施,如IP封禁、验证码等。
  • 合法性和道德性: 在爬取数据时,请确保遵守网站的使用条款以及相关的法律法规。
  • 性能: 使用Selenium或Playwright可能会比简单的HTTP请求慢得多。

希望这些信息对你有所帮助!如果你有更具体的问题或需求,请随时告诉我。

我们可以基于之前提到的两个示例(Selenium 和 Playwright)进一步增加一些功能。这里我们将添加错误处理、日志记录以及更加复杂的用户交互。

使用 Selenium 进行扩展

假设我们要登录一个网站,填写表单并提交,然后等待页面加载完成,最后抓取页面上的某些特定信息。

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 NoSuchElementException, TimeoutException
import logging
import time# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')# 设置webdriver路径
driver_path = '/path/to/chromedriver'
browser = webdriver.Chrome(driver_path)# 打开网页
url = 'http://example.com/login'
browser.get(url)try:# 寻找用户名和密码输入框username_input = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.ID, 'username')))password_input = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.ID, 'password')))# 输入用户名和密码username_input.send_keys('your_username')password_input.send_keys('your_password')# 提交表单password_input.send_keys(u'\ue007')  # 模拟回车键# 等待页面加载完成WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.ID, 'some_element_id')))# 抓取页面上的某些信息target_element = browser.find_element(By.ID, 'target_element_id')data = target_element.textlogging.info(f"Data: {data}")except NoSuchElementException as e:logging.error("Element not found.")
except TimeoutException as e:logging.error("Timeout waiting for element.")
finally:# 关闭浏览器browser.quit()

使用 Playwright 进行扩展

这次我们将添加异步等待,确保页面加载完成后再进行下一步操作。

import asyncio
from playwright.async_api import async_playwright
import logging# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')async def main():async with async_playwright() as p:# 启动浏览器browser = await p.chromium.launch(headless=False)page = await browser.new_page()# 访问登录页面await page.goto('http://example.com/login')# 填写用户名和密码await page.fill('input[name="username"]', 'your_username')await page.fill('input[name="password"]', 'your_password')# 点击登录按钮await page.click('button[type="submit"]')# 等待页面加载完成try:await page.wait_for_selector('#some_element_id', timeout=10000)except Exception as e:logging.error("Failed to wait for selector.")return# 抓取页面上的某些信息target_element = await page.query_selector('#target_element_id')data = await page.evaluate('(element) => element.textContent', target_element)logging.info(f"Data: {data}")# 关闭浏览器await browser.close()asyncio.run(main())

解释

  1. 日志记录: 使用 logging 模块来记录程序运行过程中的关键信息。
  2. 错误处理: 使用异常处理来捕获可能发生的错误,如找不到元素或超时。
  3. 异步等待: 使用 playwright 中的 wait_for_selector 方法来确保页面上的元素已经加载完成。

这些示例展示了如何更健壮地编写爬虫脚本,以应对常见的问题。如果你需要进一步的功能或有其他具体需求,请告诉我!

接下来我们可以进一步增强代码的功能,使其更加健壮且易于维护。我们将添加更多的错误处理逻辑、更精细的日志记录,以及更复杂的用户交互。

使用 Selenium 进行增强

我们将添加以下功能:

  • 更详细的错误处理。
  • 日志文件记录。
  • 检查登录是否成功。
  • 处理登录失败的情况。
  • 使用显式等待来提高稳定性。
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 NoSuchElementException, TimeoutException
import logging
import os
import time# 配置日志
log_file = "selenium_login.log"
logging.basicConfig(filename=log_file, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
logging.getLogger('').addHandler(console_handler)# 设置webdriver路径
driver_path = '/path/to/chromedriver'
browser = webdriver.Chrome(driver_path)def login(username, password):url = 'http://example.com/login'browser.get(url)try:# 寻找用户名和密码输入框username_input = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.ID, 'username')))password_input = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.ID, 'password')))# 输入用户名和密码username_input.send_keys(username)password_input.send_keys(password)# 提交表单password_input.send_keys(u'\ue007')  # 模拟回车键# 等待页面加载完成WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.ID, 'some_element_id')))# 检查是否登录成功if check_login_success():logging.info("Login successful.")else:logging.error("Login failed.")raise ValueError("Login failed.")# 抓取页面上的某些信息target_element = browser.find_element(By.ID, 'target_element_id')data = target_element.textlogging.info(f"Data: {data}")except NoSuchElementException as e:logging.error("Element not found.")except TimeoutException as e:logging.error("Timeout waiting for element.")finally:# 关闭浏览器browser.quit()def check_login_success():try:# 假设登录成功后会显示某个元素success_element = WebDriverWait(browser, 5).until(EC.presence_of_element_located((By.ID, 'success_message')))return Trueexcept TimeoutException:return Falseif __name__ == '__main__':try:login('your_username', 'your_password')except Exception as e:logging.error(f"An error occurred: {e}")

使用 Playwright 进行增强

对于 Playwright,我们也将添加类似的功能:

  • 更详细的错误处理。
  • 日志文件记录。
  • 检查登录是否成功。
  • 使用异步等待来提高稳定性。
import asyncio
from playwright.async_api import async_playwright
import logging# 配置日志
log_file = "playwright_login.log"
logging.basicConfig(filename=log_file, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
logging.getLogger('').addHandler(console_handler)async def login(username, password):async with async_playwright() as p:# 启动浏览器browser = await p.chromium.launch(headless=False)page = await browser.new_page()# 访问登录页面await page.goto('http://example.com/login')# 填写用户名和密码await page.fill('input[name="username"]', username)await page.fill('input[name="password"]', password)# 点击登录按钮await page.click('button[type="submit"]')# 等待页面加载完成try:await page.wait_for_selector('#some_element_id', timeout=10000)except Exception as e:logging.error("Failed to wait for selector.")await browser.close()return# 检查是否登录成功if await check_login_success(page):logging.info("Login successful.")else:logging.error("Login failed.")await browser.close()return# 抓取页面上的某些信息target_element = await page.query_selector('#target_element_id')data = await page.evaluate('(element) => element.textContent', target_element)logging.info(f"Data: {data}")# 关闭浏览器await browser.close()async def check_login_success(page):try:# 假设登录成功后会显示某个元素await page.wait_for_selector('#success_message', timeout=5000)return Trueexcept Exception:return Falseif __name__ == '__main__':asyncio.run(login('your_username', 'your_password'))

解释

  1. 日志记录: 添加了文件日志记录,并保留了控制台输出。
  2. 登录检查: 添加了一个函数来检查登录是否成功。
  3. 异常处理: 在主函数中添加了异常处理,确保程序能够捕获并记录所有异常。
  4. 代码结构: 将登录逻辑封装成一个单独的函数,提高了代码的可读性和可维护性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/51430.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue的虚拟Dom和diff算法

什么是虚拟dom: 虚拟 DOM 是一个抽象的虚拟树结构,用于表示页面的结构和内容,但它并不直接与实际的浏览器 DOM 交互。当响应式数据变化时,Vue 会生成一个新的虚拟 DOM 树,表示更新后的页面状态,再通过diff…

NumpyPandas:Pandas库(50%-100%)

目录 前言 一、排序 1.使用索引排序 2.使用变量值排序 二、计算新变量 1.新变量为常量 2.根据原变量新增列 3.基于一个原变量做函数运算 4.在指定位置插入新列 三、修改替换变量值 1.对应数值替换 2.指定范围替换 四、虚拟变量变换 五、数值变量分组 六、数据分组…

ChatGPT:@JSONField 有什么用

ChatGPT:JSONField 有什么用 JSONField 注解在使用 Fastjson 进行 JSON 序列化和反序列化时,提供了以下主要功能: 字段别名: 你可以使用 JSONField 注解指定 JSON 字符串中字段的名称。如果 Java 对象的字段名与 JSON 字符串中的…

构建大规模账号池与本地部署:GitHub爬虫项目详解

账号池搭建 必要性 常见登录方式: 基于Session Cookie的登录基于JWT的登录:登录生成JWT字符串 账号池存储cookie或者JWT字符串 方便后续发请求爬取数据 本地部署 conda建立一个虚拟环境 conda create -n new_env python3.x # 替换 x 为你需要的 P…

Python3网络爬虫开发实战(7)JavaScript 动态渲染页面爬取

文章目录 一、Selenium1. 基本安装2. 基本使用3. 声明浏览器对象4. 访问页面5. 查找节点6. 节点交互7. 动作链8. 执行 JavaScript9. 获取节点信息10. 切换 Frame11. 延时等待12. 前进后退13. Cookies14. 选项卡管理15. 异常处理16. 反屏蔽17. 无头模式18. Pyppeteer&#xff0c…

80后最后的书信 年代

当时11亿人口只有1.8万部固定电话 中国几千年来 鱼传尺素 雁寄鸿书 写信最后要写 亲啓 如有照片,封面要写内有照片,请勿折叠 信的开头应该是 见字如面,展信舒颜 如果拜托别人做事情,最后要写为盼 最后要写 某某草 书未尽…

ubuntu 配置opencv-python-imsow()报错

python调用imshow()时出现下面的错误: error: (-2:Unspecified error) The function is not implemented. Rebuild the library with Windows, GTK 2.x or Cocoa support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-c…

Python --Pandas库基础方法(1)

文章目录 Pandas主要数据结构Pandas 的安装Series对象创建使用列表创建调取值与索引指定index字典创建标量与index对象一起传入创建 DataFrame对象创建创建DataFrame对象values、index、columns属性列表创建索引columns的使用 Pandas中的Index导入csv文件指定列名指明分隔符读取…

关于黑马Ajax项目的笔记

一、token的介绍 概念: 访问权限的令牌,本质上是一串字符串 创建: 正确登录后,由后端签发并返回 作用: 判断是否有登录状态等,控制访问权限 注意 前端只能判断token有无,后端才能判断to…

复制带有随机指针的链表(通过复制链表实现)

public static Node copyListWithRand2(Node head){ // 如果头节点为空,直接返回null if(head null){ return null; } // 初始化当前节点和下一个节点 Node cur head; Node next null; // 遍历链表,复制每个节点&#xf…

大厂面经:京东大数据面试题及参考答案(3万字长文)

目录 Hive窗口函数有什么,什么场景,怎么用 Hive文本拼接函数是什么 Hive的数据存储格式有哪些,优缺点 两个表 join 过程中,空值的情况如何处理? Hive存储结构的区别? Hive本身对于SQL做了哪些优化? Hive分区和分桶区别? Hive分桶表的作用? HBase负载均衡怎么…

智能番茄新鲜度检测系统:基于深度学习的全面实现

基于深度学习的番茄新鲜度检测系统(UI界面YOLOv8/v7/v6/v5代码训练数据集) 引言 番茄是全球广泛种植和消费的蔬菜之一,其新鲜度直接影响其营养价值和口感。传统的番茄新鲜度检测主要依赖于人工观察和经验判断,这不仅费时费力&am…

PHP多功能投票系统源码小程序

🎉决策不再难!「多功能投票小程序」一键搞定所有选择困难症✨ 🤔选择困难?「多功能投票小程序」来救场! 每次聚会、团队讨论还是日常小决策,是不是总有那么几个瞬间让你陷入“选哪个好呢?”的…

自动控制:带死区的PID控制算法

带死区的PID控制算法 在计算机控制系统中,为了避免控制动作过于频繁,消除因频繁动作所引起的振荡,可采用带死区的PID控制。带死区的PID控制通过引入一个死区,使得在误差较小的范围内不进行控制动作,从而减少控制系统的…

将nvim的配置 上传gitee

首先是创建仓库 接着进入这个界面 然后是上传代码, 结果: 可以看到已经是可以了。 然后是 拉取代码进行测试。 第一次 拉取 使用 git clone .(家里) 做一点修改,然后上传。(公司) 然后在git pu…

【ROS2】概念:中级-不同的 ROS 2 中间件供应商

目录 支持的 RMW 实现多种 RMW 实现默认 RMW 实现 ROS 2 构建在 DDS/RTPS 之上,作为其中间件,提供发现、序列化和传输。本文( https://design.ros2.org/articles/ros_on_dds.html )详细解释了使用 DDS 实现和/或 DDS 的 RTPS 有线…

Linux驱动开发——字符设备驱动开发

1 概述 1.1 说明 本文是学习rk3568开发板驱动开发的记录,代码依托于rk3568开发板 1.2 字符设备介绍 字符设备是 Linux 驱动中最基本的一类设备驱动,字符设备就是一个一个字节,按照字节流进行读写操作的设备,读写数据是分先后顺…

用 Manim 库来生成一个树形结构的动画

完整代码: from manim import * class LargeTreeGeneration01(MovingCameraScene): DEPTH 3 CHILDREN_PER_VERTEX 2 LAYOUT_CONFIG {"vertex_spacing": (0.8, 1)} VERTEX_CONF {"radius": 0.12, "color": BLUE_B, "fi…

java基础概念05-运算符

一、自增自减运算符 二、赋值运算符 2-1、注意 三、关系运算符 四、逻辑运算符 4-1、短路逻辑运算符 五、三元运算符 六、运算符的优先级

Catalyst优化器:让你的Spark SQL查询提速10倍

目录 1 逻辑优化阶段 2.1 逻辑计划解析 2.2 逻辑计划优化 2.2.1 Catalys的优化过程 2.2.2 Cache Manager优化 2 物理优化阶段 2.1 优化 Spark Plan 2.1.1 Catalyst 的 Join 策略 2.1.2 如何决定选择哪一种 Join 策略 2.2 Physical Plan 2.2.1 EnsureRequirements 规则 3 相关文…