【Selenium】基于 WebDriverWait 爬取带有懒加载的静态页面

0x00 前言

朋友做标书,需要用到每日温度,他的老板让在这个网页手动复制做一个长期表出来:http://www.tianqihoubao.com/lishi/nanjing/month/202412.html

想着帮个忙,做个爬虫脚本吧,忽然发现这个页面很有意思:

  • 简单的 BeautifulSoup4 只能爬到主要信息还没有加载时的页面内容
  • 网页返回信息的时间上下限非常久,快则3秒慢则30秒
  • 流式一行一行渲染,简单 wait 会很容易只获取一半就截断了

0x01 驱动准备

我的 Chrome 是 133.x 版本的,由于 114.x 之后的版本就不在原先的页面更新了,还挺难找的。

现在的 ChromeDriver 可以到这里下载:

https://googlechromelabs.github.io/chrome-for-testing/#stable

0x02 源码分享

python 复制代码
# coding: utf-8
# ==========================================================================
#   Copyright (C) since 2024 All rights reserved.
#
#   filename : web_spider_eye_selenium.py
#   author   : chendian / okcd00@qq.com
#   date     : 2024/12/08 00:33:33
#   desc     : Download the driver in https://googlechromelabs.github.io/chrome-for-testing/#stable
#              
# ==========================================================================
import time
import json 
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
    


class WebSpiderSelenium():

    def __init__(self):
        self.options = Options()
        self.options.headless = True  # 设置无头模式(不弹出浏览器窗口)

        # 设置 ChromeDriver 路径
        driver_path = './chromedriver_131.exe'  # 修改为你自己的 ChromeDriver 路径
        service = Service(driver_path)
        
        # 初始化 WebDriver
        self.driver = webdriver.Chrome(service=service, options=self.options)

    def scrape_table_content_with_selenium(self, url, css_selector):

        try:
            self.driver.get(url)
            # time.sleep(5)  # 可以根据实际情况调整等待时间

            # 等待目标元素加载完成(最长等待10秒)
            target_element = WebDriverWait(self.driver, 10).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, css_selector))
            )

            return target_element.text.strip()
        except Exception as e:
            return f"发生错误: {e}"

    def scrape_table_content_with_selenium_wait(self, url, css_selector):
        # 配置 ChromeOptions
        
        try:
            # 打开网页
            self.driver.get(url)

            # 等待页面加载完成
            time.sleep(5)  # 可以根据实际情况调整等待时间

            # 使用选择器定位到目标元素
            target_element = self.driver.find_element(By.CSS_SELECTOR, css_selector)

            # 获取并返回目标元素的文本内容
            return target_element.text.strip()
        except Exception as e:
            return f"发生错误: {e}"


def crawl_weather():
    # 示例
    results = {}
    css_selector = "#content > table > tbody"  # 指定选择器
    wss = WebSpiderSelenium()

    # for date in ['202308', '202309', '202406', '202408']:
    for year in ['2023', '2024']:
        for month in [f"{i:02d}" for i in range(1, 13)]:
            date = f"{year}{month}"
            url = f"http://www.tianqihoubao.com/lishi/nanjing/month/{date}.html"  # 替换为实际的目标 URL
            result = wss.scrape_table_content_with_selenium(url, css_selector)
            results[date] = str(result)
    json.dump(results, open('./南京近两年天气.v2.json', 'w'), ensure_ascii=False, indent=1)


def analysis_results():
    results = json.load(open('./南京近两年天气.v2.json', 'r'))
    import pandas as pd
    ret = []
    for month, text in results.items():
        lines = text.split('\n')[1:]
        for line in lines:
            items = line.split()
            date, l, h = items[0], items[3], items[5]
            ret.append({"日期": date, "最低温度": l, "最高温度": h})
    pd.DataFrame(ret).to_excel("./南京近两年温度情况.xlsx")


if __name__ == "__main__":
    crawl_weather()
    analysis_results()

0x03 效果展示

朋友只需要温度信息,如果需要更多,在 items 里拼就行

欢迎大家举一反三用于其它爬虫场景。

相关推荐
程序员小远11 天前
自动化测试基础知识总结
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例
LT101579744411 天前
2026年Web自动化测试工具选型指南:多浏览器兼容解决方案
前端·测试工具·自动化
程序员三藏11 天前
Web自动化测试详解
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例
深蓝电商API12 天前
Selenium 5.0 全新架构解析:值得升级吗?
爬虫·selenium
专业机床数据采集12 天前
基于 Wireshark 抓包逆向设备通信协议,并用 C# UDP协议跨平台 实现宝元数控程序列表读取、上传、下载和删除
网络·测试工具·wireshark·程序传输·宝元数控·dnc·数控程序传输
程序员龙叔12 天前
从 0 开始学习 AI 测试 - 从接口测试来教你如何用 AI 来生成自动化测试代码
自动化测试·软件测试·python·软件测试工程师·测试工具·性能测试·ai测试
Saniffer_SH12 天前
【高清视频】Gen6 服务器还没到,Gen6 SSD 怎么测?Emily 现场演示三种测试环境
人工智能·驱动开发·测试工具·缓存·fpga开发·计算机外设·压力测试
川石课堂软件测试12 天前
APP自动化测试|高级手势操作&toast操作
css·功能测试·测试工具·microsoft·fiddler·单元测试·harmonyos
LT101579744412 天前
2026年开源自动化测试工具选型指南:功能与适用场景解析
测试工具·开源·自动化