前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Web网页自动化实战《4.获取所有酒店的名字、价格、评分信息,并写入文件》上篇

Web网页自动化实战《4.获取所有酒店的名字、价格、评分信息,并写入文件》上篇

作者头像
清菡
发布2022-06-21 15:28:52
5480
发布2022-06-21 15:28:52
举报
文章被收录于专栏:清菡软件测试清菡软件测试

目录

  • 一、find_elements()的作用
    • 1.获取当前页面中所有酒店名称的元素
    • 2.获取当前页面中所有酒店价格的元素
    • 3.获取当前页面中所有酒店评分的元素
  • 二、分别拿到每家的价格、评分、酒店名并写入文件
    • 1.分别拿到每家的价格、评分、酒店名
    • 2.将拿到的数据写入文件
  • 三、代码
  • 四、总结与扩展
    • 1.总结
    • 2.拓展

一、find_elements()的作用

1.获取当前页面中所有酒店名称的元素

通过元素的class属性获取酒店名,获取到了20个

这20个酒店展示的格式都是一样的。每个div都是独立的。每个div都是个酒店的信息。

这20个酒店名称都有同一个爸爸div

1)find_element(By.XPATH,)

find_element的意思是查找一个元素。 //span[@class="name"]这个表达式可能匹配到一个或多个元素,有多少个由页面来决定。

find_element(By.XPATH,)只匹配找到的元素中的一个,而且是页面中第一个出现的元素。

页面中按先后顺序,从最顶端的html开始从上往下加载。如果页面中有一个以上的,那么它匹配到的是第一个元素。

2)find_elements(By.XPATH,)

要获取找到的这20个元素的文本内容,它们的文本内容是酒店名称。

find_elements(By.XPATH,) ----获取匹配到表达式的所有元素。

Elements里面呈现的html中的元素呈现的顺序和页面中的顺序是一样的。

2.获取当前页面中所有酒店价格的元素

这个表达式匹配到20个元素

3.获取当前页面中所有酒店评分的元素

这个表达式匹配到20个元素

二、分别拿到每家的价格、评分、酒店名并写入文件

这20个元素,每个这样的元素里面都有价格、评分、酒店名称。

1.分别拿到每家的价格、评分、酒店名

这几行代码会一直反复执行,这是个遍历的过程。等到最后一个值全部取完了,它才会执行下面的部分。这几行全部缩进了,表示每取一个值,大家都会去做的事情。

这个换行的效果是print()搞定的

2.将拿到的数据写入文件

fs = open("我的酒店数据.txt", "w",encoding='UTF-8') UTF-8支持中英文。

读:比如读本地某个数据表格,本地必须有才能读,没有就读不到。

w可写入模式:文件不存在,就创建文件并写入。文件存在,直接写入。

w 这种模式写的时候是直接覆盖文件中的内容的。

三、代码

代码语言:javascript
复制
from selenium.webdriver.common.by import By

from selenium import webdriver
import time

# 打开谷歌浏览器,与浏览器建立了会话。
# driver变量=会话。
driver = webdriver.Chrome()
driver.get("https://www.elong.com/")  # 这行代码执行后,会等到页面加载得差不多了再去执行下一行代码。
# get()这个功能是会等到页面加载完成的。
# 有的时候页面加载出来了,但是渲染的方式有些慢。
# 所以我还想等1秒也是可以的。
time.sleep(1)

# 查找元素通过xpath定位方式。
ele = driver.find_element(By.XPATH, '//input[@data-bindid="city"]')  # 定位到目的地的输入框,将刚才在写好的表达式复制过来。
# ele= 我找到的元素
# 点击操作 -- 点击目的地输入框,弹出城市选择框。
ele.click()
time.sleep(2)  # 运行这行代码后会停留2秒,然后再去运行下一行代码。
# 因为接下来要操作的元素,是动态出现的(不是一开始访问网站就有的,而是你做了一个动作让人家动态的出现了)。
# 它是需要时间呈现在页面上的。这个时间就需要你来等一等了。等一等网页,再去找这个元素去操作。


# 输入操作 --ele.send_keys("输入操作")
# 获取它的属性-- ele.get_attribute("属性名称")
# 获取它的文本内容-- ele.text


# 选择热门城市当中的广州
driver.find_element(By.XPATH, '//li[@data="0|15"]').click()
time.sleep(1)  # 加上等待时间。sleep时间不宜太长,7秒8秒,这个时间就太长了。
# 没加等待时间的时候运行代码,会发现操作太快了,且没有选择到对应的日期。

# 选择入住日期
ele = driver.find_element(By.XPATH, '//input[@data-bindid="checkIn"]')
ele.clear()  # 输入日期前,先清空输入框的内容。
ele.send_keys("2022-05-27")

time.sleep(1)  # 每个操作间都加了等待时间。

'''
输入日期后,日期框没有消失,得让日期框消失。点击除了它以外的其它元素
(选一个页面固定的元素,那就点击目的地这个元素),
日期框就能消失了。再去处理下一个元素。不然日期框会挡住别的元素。
接下来点击搜索,搜索按钮被这个日期框遮住了。就会影响你的操作效果。
所以我是根据页面的特征习性来处理的。
'''

# 把弹出的日期选择框关掉。
driver.find_element(By.XPATH, '//div[@id="domesticDiv"]//dt[text()="目的地"]').click()

# 选择退房日期
b = driver.find_element(By.XPATH, '//input[@data-bindid="checkOut"]')
b.clear()
b.send_keys("2022-05-30")  # 输入日期
time.sleep(1)
driver.find_element(By.XPATH, '//div[@id="domesticDiv"]//dt[text()="目的地"]').click()
time.sleep(1)

# a=driver.find_element(By.XPATH,'//input[@data-bindid="allInOne"]')
# a.clear()
# a.send_keys("喜悦门酒店(广州融创文旅城店)")
# time.sleep(1)
# driver.find_element(By.XPATH,'//div[@id="domesticDiv"]//dt[text()="目的地"]').click()

# ========2、点击搜索按钮=========
# time.sleep(0.5)
driver.find_element(By.XPATH, '//span[@data-bindid="search"]').click()

# ==========3、跳转到新的页面了,等待新的页面内容加载=========
time.sleep(7)  # 等待新的内容加载出来,用的是比较长的时间。

# ================4、获取酒店的名字、酒店的价格、酒店的评价===============
# 拿到第一家酒店的信息
# hotel_name=driver.find_element(By.XPATH,'//span[@class="name"]').text
# hotel_price=driver.find_element(By.XPATH,'//p[@class="loginToSee"]').text
# hotel_review=driver.find_element(By.XPATH,'//p[@class="score mb5"]').text
# print("酒店信息:",hotel_name,hotel_review,hotel_price)


# ======================5、获取当前页面的所有酒店的价格、评分、名字
# find_elements(By.XPATH,) --- 获取匹配到表达式的所有元素。names是个列表。列表里面放的是元素对象。
# 所有酒店的名称元素
total_names = driver.find_elements(By.XPATH, '//span[@class="name"]')  # 20个同类型的元素。
time.sleep(1)

# python中用来存放多个数据的是:list/字典/元组/集合这几种方式。


# 所有酒店的价格元素
total_prices = driver.find_elements(By.XPATH, '//p[@class="loginToSee"]')
time.sleep(1)
# 所有酒店的评分元素
total_previews = driver.find_elements(By.XPATH, '//p[@class="score mb5"]')

# 从3个列表当中,每个值都要取出来。
# 店子里有20件衣服。从第1件开始到第20件都要去看一眼。把看一眼叫做访问。
# 这个叫做遍历/循环。从头到尾,每一个成员,你都要去访问。20个集合。
# 20个酒店。每一个酒店,都要去获取名字、价格、评分------遍历。
'''
for 变量 in 列表:# 在列表当中,取每一个成员,给到变量。
    取到的每一个成员,会去做的事情。
    取到的每个酒店,都要去拿酒店的名字、价格和评分。

遍历的是:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]
'''


# 文件操作 -- 我的酒店数据.txt
# 读写操作。创建一个文件,写入数据,然后关闭。
# open -- 文件操作。
# 打开文件的时候,指明写入方式,以及编码格式为utf-8
fs = open("我的酒店数据.txt", "w",encoding='UTF-8')  # write -- w  可写入的模式。文件不存在会创建文件并写入。文件存在,直接写入。
# 这里只有文件名称,没有写路径,这就是告诉python,我就在当前路径下生成文件。
#w 这种模式是直接覆盖文件中的内容的。
# write写的时候,不会自动换行。  换行:\n


# for index in [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]:
for index in range(20):
    print(total_names[index].text, total_prices[index].text, total_previews[index].text)  # 拿到了每家酒店的名字价格和评分。
    fs.write(total_names[index].text + "  ")  # 在我没有关闭这个文件之前,是可以持续写入的。
    fs.write(total_prices[index].text + "  ")
    # fs.write(total_prices[index].get_attribute("属性名称")+"    ")#获取属性值
    # fs.write(total_prices[index].get_attribute('class') + "    ")
    fs.write(total_previews[index].text + "\n")

# 关闭文件
fs.close()

# for 后面的变量可以随便取名,in后面可以跟列表,当然除了列表以外,很多都可以的。
time.sleep(10)

#########6.更多的事情:先选价格,再去看评分。###################
jiage=driver.find_element(By.XPATH,'//li[@class="radio fl"]//span[text()="150元以下"]').click()
try:
    pingfens = driver.find_elements(By.XPATH, '//p[@class="score mb5"]')
    fn = open("150元以下的评分数据.txt", "w",encoding='UTF-8')
    for score in range(20):
        print(pingfens[score].text)
        fn.write(pingfens[score].text+ "\n")
    fn.close()
except:
    pingfens = driver.find_elements(By.XPATH, '//p[@class="score mb5"]')
    fn = open("150元以下的评分数据.txt", "w",encoding='UTF-8')
    for score in range(20):
        print(pingfens[score].text)
        fn.write(pingfens[score].text+ "\n")
    fn.close()
#用捕获异常的方法规避当前遇到的异常了。否则代码是没问题,但多次运行后会报错。

# ========7、关闭浏览器,关闭本次会话========
time.sleep(10)
driver.quit()  # 退出相关驱动,关闭所有窗口。

运行成功

四、总结与扩展

1.总结

1.find_elements()用来查找所有的元素,而且它的结果是个列表。

2.列表的处理方式 -- 遍历取值,创建文件。

3.遍历列表 -- for循环。

4.数据写入文件。

2.扩展

根据列表的长度去遍历:再掌握range函数的用法。参考链接:操作列表

运行这个fs.write(total_prices[index].get_attribute("属性名称")+" ")#获取属性值

fs.write(total_prices[index].text + " ")运行出来的结果都是一样的。

第一种方式的运行结果

第二种方式的运行结果

以上所学,比如领导要看下平台的一些数据,可以利用这个脚本去访问公司的系统把数据拿下来。有些时候领导就想要个报告。学的这些不是没用,要在对应的时机用上来。

爬虫有的时候会用到这么点自动化知识,但不是完全用的自动化知识。爬虫要学得好,真的要学得很深入。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 清菡软件测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
    • 一、find_elements()的作用
      • 1.获取当前页面中所有酒店名称的元素
      • 2.获取当前页面中所有酒店价格的元素
      • 3.获取当前页面中所有酒店评分的元素
    • 二、分别拿到每家的价格、评分、酒店名并写入文件
      • 1.分别拿到每家的价格、评分、酒店名
      • 2.将拿到的数据写入文件
    • 三、代码
      • 四、总结与扩展
        • 1.总结
        • 2.扩展
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档