Python网络爬虫(三):Selenium--以携程酒店为例

1 Selenium简介

        Selenium是一个用于网站应用程序自动化的工具,它可以直接运行在浏览器中,就像真正的用户在操作一样。它相当于一个机器人,可以模拟人类在浏览器上的一些行为,比如输入文本、点击、回车等。Selenium支持多种浏览器,本文以Chrome浏览器为例。chromedriver是一个驱动Chrome浏览器的驱动程序,针对不同的浏览器有不同的driver。

        1.1 Selenium的优缺点

        优点:浏览器能请求到的数据,Selenium同样能请求到,爬虫稳定,适用于所有类型的动态渲染网页。

        缺点:代码量大、容易被反爬、性能低。笔者认为性能低、速度慢是其最大缺点。

2 浏览器基本操作

        浏览器基本操作包括打开浏览器、设置窗口大小、设置打开浏览器位置、关闭浏览器、前进、后退、刷新、获取网页代码等。下面先通过代码来演示如何打开网页并设置浏览器窗口的大小以及打开位置:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Optionsurl = 'https://hotels.ctrip.com/hotels/396376.html#ctm_ref=hp_htl_pt_pro_01'  # 携程上海虹桥宾馆主页
service = Service(executable_path=r'D:\anaconda\Scripts\chromedriver.exe')  # 指定chromedriver位置
opt = Options()
opt.add_argument('user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36"')
opt.add_argument('--disable-blink-features=AutomationControlled')  # 隐藏浏览器痕迹
driver = webdriver.Chrome(service=service, options=opt)  # 实例化浏览器对象
# driver.maximize_window()  # 浏览器窗口最大化
# driver.set_window_position(1000, 20)    # 设置浏览器打开位置
# driver.set_window_size(800,800)    # 设置浏览器窗口大小
driver.get(url)  # 打开网页

        接下来演示如何前进、后退、刷新网页。需要注意的是,Selenium打开不同的网页或者进行前进、后退时,都是在同一个窗口下操作的,不会打开新的窗口:

driver.get('https://hotels.ctrip.com/hotels/396376.html#ctm_ref=hp_htl_pt_pro_01')  # 打开携程
time.sleep(1)url2 = 'https://www.jd.com'    # 打开京东
driver.get(url2)
time.sleep(1)driver.back()    # 回退
time.sleep(1)driver.forward()    # 前进
time.sleep(1)driver.refresh()    # 刷新页面
time.sleep(1)source = driver.page_source    # 获取当前页面源代码

         接下来用一个表格展示Selenium浏览器的基本操作:

浏览器基本操作
方法说明
get()打开浏览器

maximize_window()

浏览器窗口最大化

set_window_position()

设置浏览器打开位置

set_window_size()

设置浏览器窗口大小
back()回退
forward()前进
        refresh()刷新页面
page_source获取网页源代码
close()关闭当前标签页
quit()退出浏览器

3 网页元素定位

        Selenium抓取网页信息是在开发者工具的Elements选项卡里,Selenium定位网页元素主要通过元素的属性值或者元素在HTML里的路径位置,主要的定位方式如下:

定位方式方法
ID定位driver.find_element(By.ID, 'ID')
name定位driver.find_element(By.NAME, 'NAME')
class定位driver.find_element(By.CLASS_NAME, 'CLASS_NAME')
标签名定位                driver.find_element(By.TAG_NAME, 'TAG_NAME')
xpath定位driver.find_element(By.XPATH, 'XPATH')
CSS选择器定位driver.find_element(By.CSS_SELECTOR, 'CSS_SELECTOR')

        下面来演示如何定位评论标签,并点击,先看下图:

         打开携程任意一个酒店页面,这里以上海虹桥宾馆为例,打开开发者工具,点击Elements选项卡左侧的箭头,然后将鼠标悬停在页面“显示所有...条点评”链接上,点击,开发者工具中就自动定位到了选中的标签,在选中的标签上右击--Copy--Copy XPath,这样就复制了该标签的XPath路径,为“//*[@id="ibu-hotel-detail-head"]/div[2]/div[2]/div[1]/div/div/div[1]/p[2]”,然后调用click()方法点击,代码如下:

element_comment = driver.find_element(By.XPATH,'//*[@id="ibu-hotel-detail-head"]/div[2]/div[2]/div[1]/div/div/div[1]/p[2]')
element_comment.click()

 4 网页元素操控

        操控网页元素在网页元素定位后才能执行,Selenium可以模拟任何操作,比如单机、右击、拖拉、滚动、复制粘贴或者文本输入等,操作方式可分为三大类:常规操作、鼠标事件操作和键盘事件操作。

        4.1 常规操作

        常规操作包含文本清除、文本输入、单击元素、提交表单、获取元素值等。下面以打开京东首页并在搜索框输入mate60Pro,按回车搜索为例:

import timefrom selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keysurl = 'https://jd.com'
driver = webdriver.Chrome()
driver.get(url)
driver.maximize_window()
# 输入昵称和密码
input_element = driver.find_element(By.XPATH, '//*[@id="key"]')
input_element.send_keys('mate60Pro', Keys.ENTER)
time.sleep(3)

         上述例子分别执行了打开京东首页、窗口最大化、定位搜索框位置、输入文本“mate60Pro”、键盘按下回车操作。

        下面列出一些实际开发中常见的操作方式:

代码作用
driver.find_element(By.ID, 'X').clear()清除X标签的内容
driver.find_element(By.ID, 'X').location获取元素在网页中的坐标位置,坐标格式:{'y':20, 'x':100}
driver.find_element(By.ID, 'X').get_attribute('id')获取元素的某个属性值
driver.find_element(By.ID, 'X').is_displayed()判断X元素在网页上是否可见
driver.find_element(By.ID, 'X').is_selected()判断X元素是否被选,通常用于checkbox和radio标签,返回值为True或False
“”“selected标签的选值”“”    from selenium.webdriver.support.select import Select
Select(driver.find_element(By.ID, 'X')).select_by_index('2')根据下拉框的索引来选取
Select(driver.find_element(By.ID, 'X')).select_by_index('book')根据下拉框的value属性来选取
Select(driver.find_element(By.ID, 'X')).select_by_visible_text('beijing')根据下拉框的值来选取

 4.2 鼠标事件

        鼠标事件操作由Selenium的ActionChains类来实现。ActionChains类定义了多种鼠标操作方法,具体的操作方法如下表所示:

ActionChains类的鼠标操作方法
操作方法说明示例
perform        执行鼠标事件click(element).perform(),click是鼠标单击事件,perform是执行这个单击事件
reset_actions取消鼠标事件

click(element).reset_actions(),click

是鼠标单击事件,reset_actions是取消单击事件

click鼠标单击click(element),element是某个元素对象
click_and_hold长按鼠标左键click_and_hold(element),element是某个元素对象
context_click长按鼠标右键context_click(element),element是某个元素对象
double_click鼠标双击        double_click(element),element是某个元素对象
drag_and_drop对元素长按左键并移动到另一个元素的位置后释放鼠标左键drag_and_drop(element,element1),element是某个元素对象,element1是目标元素对象
drag_and_drop_by_offset对元素长按左键并移动到指定的坐标位置drag_and_drop_by_offset(element, x, y),element是某个元素对象,x是偏移的x坐标, y是偏移的y坐标
key_down对元素长按键盘中的某个按键        key_down(Keys.CONTROL, element),Keys.CONTROL是由Keys定义的键盘事件,element是某个元素对象
key_up对元素释放键盘中的某个按键key_up(Keys.CONTROL, element),Keys.CONTROL是由Keys定义的键盘事件,element是某个元素对象
move_by_offset对当前鼠标所在位置进行偏移move_by_offset(x, y),x是偏移的x坐标, y是偏移的y坐标
move_to_element将鼠标移动到某个元素所在的位置move_to_element(element),element是某个元素对象
move_to_element_with_offset将鼠标移动到某个元素并偏移一定位置move_to_element_with_offset(element, x, y),element是某个元素对象,x是偏移的x坐标, y是偏移的y坐标
pause设置暂停执行时间pause(60)
release释放鼠标长按操作release(element),element是某个元素对象,如果element为空,对当前鼠标的位置长按操作进行释放
send_keys执行文本输入send_keys(value),value是输入的内容
send_keys_to_element对当前元素执行文本输入send_keys_to_element(element, value), element是某个元素对象,value是输入的内容

        以上方法都是在ActionChains类所定义的类方法,若想使用这些操作方法,必须将ActionChains类实例化后才能调用。以B站的登录页面为例,通过鼠标操作方法去双击网页中的“登录”按钮。

        

import timefrom selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChainsurl = 'https://passport.bilibili.com/login'
driver = webdriver.Chrome()
driver.get(url)
driver.maximize_window()
time.sleep(1)
# 输入昵称和密码
element = driver.find_element(By.CLASS_NAME, 'btn_primary disabled')
ActionChains(driver).double_click(element).perform()
time.sleep(3)

        上述代码中,首先将ActionChains实例化,实例化的时候传入driver对象。实例化之后就可以直接调用鼠标事件操作方法,这些方法需要传入element对象,element是网页中某个标签元素。最后再调用perform方法,这是一个执行命令,因为鼠标可以执行拖拉、长按等持久性的操作,调用perform方法可以让这个鼠标操作马上执行。

        4.3 键盘事件

        键盘事件是模拟人为按下键盘的某个按键,主要通过send_keys方法来实现。以百度搜索为例,利用键盘的快捷键实现搜索内容的变换。代码如下:

import timefrom selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keysurl = 'https://www.baidu.com'
driver = webdriver.Chrome()
driver.get(url)# 获取输入框标签对象
element = driver.find_element(By.XPATH, '//*[@id="kw"]')
element.send_keys('我爱python')
time.sleep(2)# 删除最后的一个文字
element.send_keys(Keys.BACK_SPACE)
time.sleep(2)# 添加输入空格键和“教程”
element.send_keys(Keys.SPACE)
element.send_keys('教程')
time.sleep(2)# ctrl+a 全选输入框内容
element.send_keys(Keys.CONTROL, 'a')
time.sleep(2)# ctrl+x 剪切输入框内容
element.send_keys(Keys.CONTROL, 'x')
time.sleep(2)# ctrl+v 粘贴内容到输入框
element.send_keys(Keys.CONTROL, 'v')
time.sleep(2)# 通过回车键来代替单击操作
driver.find_element(By.ID, 'su').send_keys(Keys.ENTER)

 5 携程酒店评论采集

        先看一下采集的评论:

        附上完整代码:

import csv
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
from lxml import etreeclass XcSpider:def __init__(self):self.opt = Options()self.opt.debugger_address = '127.0.0.1:8888'self.opt.add_argument('user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36"')self.opt.add_argument('--incognito')self.opt.add_argument('--disable-blink-features=AutomationControlled')  # 隐藏浏览器痕迹self.service = Service(executable_path=r'D:\anaconda\Scripts\chromedriver.exe')self.driver = webdriver.Chrome(options=self.opt, service=self.service)self.driver.implicitly_wait(10)self.f = open('携程酒店评论.csv', 'a', encoding='utf-8-sig', newline='')self.writer = csv.DictWriter(self.f,fieldnames=['score', 'brief_comment', 'content', 'time_location', 'username','room_type', 'room_type2', 'checkin', 'comment_num'])self.writer.writeheader()def fetch_source(self, url):self.driver.get(url)time.sleep(3)self.driver.find_element(by=By.XPATH,value='//*[@id="ibu-hotel-detail-head"]/div[2]/div[2]/div[1]/div/div/div[1]/p[2]').click()source = self.driver.page_sourceself.parse_html(source)ActionChains(driver=self.driver).move_by_offset(400, 400).perform()time.sleep(3)# 执行js代码,滚动条往下拉500像素js = "window.scrollTo(0,500);"self.driver.execute_script(js)count = 1while count < 235:print(f'正在爬取第{count}页数据...')count += 1next_button = self.driver.find_element(by=By.XPATH,value='//*[@id="ibu_hotel_review"]/div/ul[2]/li/div/div[2]/div[2]/div[12]/ul/li[3]/a/i')next_button.click()time.sleep(1)source = self.driver.page_sourceself.parse_html(source)self.driver.execute_script(js)def parse_html(self, source):tree = etree.HTML(source)div_list = tree.xpath('//*[@id="ibu_hotel_review"]/div/ul[2]/li/div/div[2]/div[2]/div[position() < 11]')for div in div_list:score = div.xpath('./div/div[2]/div[1]/div/div[1]/strong/text()')score = self.handle_list(score)brief_comment = div.xpath('./div/div[2]/div[1]/div/div[2]/text()')brief_comment = self.handle_list(brief_comment)content = div.xpath('./div/div[2]/div[2]/p/text()')content = self.handle_list(content)time_location = div.xpath('./div/div[2]/div[3]/div[2]/text()')time_location = self.handle_list(time_location)username = div.xpath('./div/div[1]/div[1]/div/p/text()')username = self.handle_list(username)room_type = div.xpath('./div/div[1]/div[2]/ul/li[1]/span/text()')room_type = self.handle_list(room_type)checkin = div.xpath('./div/div[1]/div[2]/ul/li[2]/span/text()')checkin = self.handle_list(checkin)room_type2 = div.xpath('./div/div[1]/div[2]/ul/li[3]/span/text()')room_type2 = self.handle_list(room_type2)comment_num = div.xpath('./div/div[1]/div[2]/ul/li[4]/span/text()')comment_num = self.handle_list(comment_num)dit = {'score':score,'brief_comment': brief_comment,'content': content,'time_location': time_location,'username': username,'room_type': room_type,'room_type2': room_type2,'checkin': checkin,'comment_num': comment_num,}self.writer.writerow(dit)def handle_list(self, xpath_list):if xpath_list:xpath_list = xpath_list[0].strip()return xpath_listelse:return ''def main(self):self.fetch_source('https://hotels.ctrip.com/hotels/396376.html#ctm_ref=hp_htl_pt_pro_01')self.f.close()if __name__ == '__main__':XS = XcSpider()XS.main()

                

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

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

相关文章

记录一次官网访问很慢的情况

客户查看云监控,带宽未超限,客户取的是1分钟的原生值,也就是1分钟也是个平均值。 但是客户的原始值&#xff0c;其实就是1分钟内的平均值。所以客户的瞬时超限&#xff0c;其实是看不出来的。但是后端同事从实时监控里面可以看到超限的情况。 客户升带宽后&#xff0c; 发现还…

Flutter 应用数据持久化指南

1. 介绍 1.1 什么是数据持久化&#xff1f; 数据持久化是指将应用程序中的数据保存在持久存储介质&#xff08;如硬盘、数据库等&#xff09;中的过程。在计算机科学领域&#xff0c;持久化数据是指数据在程序退出或系统关机后仍然存在的能力。这种持久性使得数据可以在不同的…

是德科技keysight 33621A波形发生器

181/2461/8938产品概述&#xff1a; 与上一代DDS波形发生器相比&#xff0c;采用独家Trueform技术的安捷伦HP 33621A波形发生器具有更高的性能、保真度和灵活性。安捷伦HP 33621A 120 MHz、单通道、Trueform arbs&#xff0c;带时序控制和64 MSa存储器&#xff0c;1 ps抖动&am…

go juc 线程中的子类

1.go test() 主死随从 package mainimport ("fmt""strconv""time" )func test() {for i : 1; i < 10; i {fmt.Println("hello " strconv.Itoa(i))//阻塞time.Sleep(time.Second)} } func main() {//开启协程go test()for i : 1; …

如何配置vite的proxy

1.前言 vite项目&#xff0c;本地开发环境可以通过配置proxy代理实现跨域请求。但是生产环境&#xff0c;该配置不生效&#xff0c;一般使用 nginx 转发&#xff0c;或者后端配置cors 2.解释 server: {port: 9000,proxy: { // 本地开发环境通过代理实现跨域&#xff0c;生产…

基于ssm的轻型卡车零部件销售平台(java项目+文档+源码)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的轻型卡车零部件销售平台。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 轻型卡车零部件销售平台…

C# 批量删除Excel重复项

当从不同来源导入Excel数据时&#xff0c;可能存在重复的记录。为了确保数据的准确性&#xff0c;通常需要删除这些重复的行。 手动查找并删除可能会非常耗费时间&#xff0c;而通过编程脚本则可以实现在短时间内处理大量数据。本文将提供一个使用C# 快速查找并删除Excel重复项…

【ArduinoQuartus】在小脚丫STEP CYC10上安装PulseRain Reindeer并在软核上运行基础功能

【Arduino&Quartus】在小脚丫STEP CYC10上安装PulseRain Reindeer并在软核上运行基础功能 一、将Reindeer软核下载到STEP CYC10&#xff08;一&#xff09;下载PulseRain Reindeer软核&#xff08;二&#xff09;配置Reindeer软核到开发板1.将sof文件转换为jic文件2.将jic文…

Centos7安装单机版Kafka

下载 链接&#xff1a;https://pan.baidu.com/s/1W8lVEF6Y-xlg6zr3l9QAbg?pwdhbkt 提取码&#xff1a;hbkt 上传到服务器/opt目录 安装 # kafka安装目录为 /opt/kafka cd /opt; mkdir kafka; mv kafka_2.13-2.7.0.tgz ./kafka;cd kafka; #解压 tar -zxvf kafka_2.13-2.7.0…

说一说Redis的Bitmaps和HyperLoLog?

本篇内容对应 “Redis高级数据类型”小节 和 “7.5 网站数据统计”小节 对应视频&#xff1a; Redis高级数据结构 网站数据统计 1 什么是UV和DAU&#xff1f; DAUUV英文全称Daily Active UserUnique Visotr中文全称日活跃用户量独立访客如何统计数据通过用户ID排重统计数据通…

上位机图像处理和嵌入式模块部署(qmacvisual图像清晰度)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 做过isp的同学都知道&#xff0c;图像处理里面有一个3A&#xff0c;即自动曝光、自动白平衡和自动对焦。其中自动对焦这个&#xff0c;就需要用输入…

绩效考核存在合理性、公平性、客观性吗?

目录 一、绩效考核流于形式&#xff1a;没有实际考核过 二、考核结果的确定: 主管一人说了算 三、考核结果&#xff1a; 与绩效奖金挂钩吗&#xff1f; 四、考核的滥用&#xff1a;成为公司排挤迫使员工离职的手段 五、公司说&#xff1a; 让你滚蛋&#xff0c;谁还会发你奖…

SpringBoot(48)-使用 SkyWalking 进行分布式链路追踪

Spring Boot&#xff08;48&#xff09;- 使用 SkyWalking 进行分布式链路追踪 介绍 在分布式系统中&#xff0c;了解各个服务之间的调用关系和性能表现是非常重要的。SkyWalking 是一款开源的分布式系统监控与分析平台&#xff0c;能够帮助我们实现分布式系统的链路追踪、性…

使用minikube安装使用单机版K8S(docker)

前置&#xff1a;作为一个开发&#xff0c;工作之余想玩一下k8s&#xff0c;但是搭建成本太高&#xff0c;所以就找到了minikube这个工具&#xff0c;快速搭建单机版k8s&#xff0c;下面是个人搭建流程&#xff0c;基于centos7&#xff0c;仅供参考。 1.下载kubectl&#xff0…

ES学习日记(十)-------Java操作ES之连接客户端

Elasticsearch有两种连接方式: transport、rest。transport 通过TCP方式访问ES(只支持iava)&#xff0c;rest 方式通过http API 访问ES(没有语言限制)。 ES官方建议使用Iest 方式&#xff0c;transport 在7.8 版本中不建议使用&#xff0c;在8.x的版本中废弃。你可以用Java客户…

Java23种设计模式

本文主要是对Java中一些常用的设计模式进行讲解 后期会进行不断的更新&#xff0c;欢迎浏览 23种设计模式 创建型模式&#xff0c;共五种&#xff1a;工厂方法模式、抽象工厂模式、建造者模式、原型模式、单例模式。结构型模式&#xff0c;共七种&#xff1a;适配器模式、桥接…

使用 Flume 将 CSV 数据导入 Kafka:实现实时数据流

使用 Flume 将 CSV 数据导入 Kafka&#xff1a;实现实时数据流 文介绍了如何使用 Apache Flume 将 CSV 格式的数据从本地文件系统导入到 Apache Kafka 中&#xff0c;以实现实时数据流处理。通过 Flume 的配置和操作步骤&#xff0c;我们可以轻松地将数据从 CSV 文件中读取并发…

RT-Thread下使用NTP服务器获取时间并同步到硬件RTC

单片机:STM32F407VET6 实现功能:通过ntp服务器获取时间并同步到硬件RTC上 1.配置NTP相关参数 1.1打开netutils相关软件包 1.2 关闭软件RTC相关配置 参考资料:RT-Thread中使用NTP自动更新时间_rtthread ntp-CSDN博客 2.配置硬件RTC 2.1 在ENV里面使能硬件RTC 2.2使用STM32C…

日志服务 HarmonyOS NEXT 日志采集最佳实践

作者&#xff1a;高玉龙&#xff08;元泊&#xff09; 背景信息 随着数字化新时代的全面展开以及 5G 与物联网&#xff08;IoT&#xff09;技术的迅速普及&#xff0c;操作系统正面临前所未有的变革需求。在这个背景下&#xff0c;华为公司自主研发的鸿蒙操作系统&#xff08…

idea maven 打包 内存溢出 报 GC overhead limit exceeded -> [Help 1]

idea 使用maven打包 报GC overhead limit exceeded -> [Help 1] 解决方法&#xff1a; 打开settings -> 点开如同所示 将 vm Options 参数 设为 -Xmx8g