python中selenium

2024/08/15

简介

需求

各个库对比

Urllib,selenium,requests,scrapy 各有哪些优劣

urllib, selenium, requests, 和 scrapy 是四个常用的 Python 库,广泛应用于网络请求、网页抓取和自动化任务。它们各自有独特的优点和缺点,适合不同的应用场景。

1. urllib

urllib 是 Python 标准库中的一部分,用于处理 URL 和网络请求。它提供了一个基本的 HTTP 客户端。

优点:

  • 标准库,无需安装urllib 是 Python 内置的库,使用时不需要额外安装。
  • 基本功能完备:可以进行 HTTP 请求、处理 URL、解析数据等。
  • 兼容性好:与 Python 兼容性好,尤其是在需要兼容多个 Python 版本时。

缺点:

  • API 复杂且底层:与 requests 相比,urllib 的 API 更复杂,使用起来不够简洁,需要处理更多的底层细节。
  • 缺少高级功能:缺少 requests 的许多高级特性,如会话管理、连接池、文件上传等。

适用场景:

  • 简单的网络请求和数据下载,特别是在不需要安装第三方库的情况下。

2. requests

requests 是一个流行的第三方库,用于简化 HTTP 请求的处理。

优点:

  • 简单易用requests 的 API 设计非常简洁,使用起来非常直观和人性化。
  • 丰富的功能:支持会话管理、持久化连接、Cookie 处理、文件上传、代理、认证等。
  • 广泛使用requests 是事实上的标准库,广泛应用于各类 Python 项目中。

缺点:

  • 不是标准库:需要单独安装,无法直接在标准库环境下使用。
  • 不适合复杂的网页交互requests 主要用于处理静态内容和简单的动态请求,不适合处理复杂的 JavaScript 渲染页面。

适用场景:

  • 各类 HTTP 请求任务,如 API 调用、数据抓取、静态页面下载等。

3. selenium

selenium 是一个自动化测试工具,常用于模拟浏览器行为,执行复杂的网页交互。

优点:

  • 处理复杂网页selenium 可以模拟用户操作,如点击、填表单、滚动等,适合处理需要 JavaScript 渲染的复杂网页。
  • 浏览器自动化selenium 可以与真实浏览器集成,支持多种浏览器(如 Chrome、Firefox)。
  • 强大的调试能力:可以实时查看浏览器的操作过程,调试方便。

缺点:

  • 资源消耗大:因为需要启动实际的浏览器,selenium 比其他库的资源消耗大得多。
  • 速度较慢:模拟浏览器操作的速度较慢,不适合大量数据的快速抓取。
  • 复杂性高:相比于 requestsscrapyselenium 的配置和使用更为复杂。

适用场景:

  • 需要模拟用户交互的网页自动化任务,如登录、表单提交、页面滚动等。
  • 处理依赖 JavaScript 渲染的动态网页内容抓取。

4. scrapy

scrapy 是一个强大的框架,专门用于大规模的网页抓取和数据提取。

优点:

  • 高效并发scrapy 支持异步请求和并发处理,非常适合大规模的数据抓取。
  • 内置功能丰富:包括自动化的请求调度、数据管道处理、数据持久化(支持导出到 CSV、JSON、数据库等)。
  • 可扩展性强:提供了强大的扩展机制,支持中间件、自定义爬虫、代理、用户代理池等。
  • 社区活跃:有丰富的插件和第三方扩展。

缺点:

  • 学习曲线较高scrapy 是一个完整的框架,入门需要一定的学习成本,尤其是对于简单的抓取任务来说,可能显得过于复杂。
  • 重量级:对于小型项目或简单的抓取任务来说,scrapy 可能显得过于重量级。

适用场景:

  • 大规模网页抓取项目,需要处理成千上万的网页,提取结构化数据。
  • 需要异步处理和高并发抓取任务,特别是当数据需要持久化处理时。

总结

  • urllib: 适合简单的 HTTP 请求和 URL 处理,尤其是在不需要安装第三方库的情况下。
  • requests: 适合大多数 HTTP 请求任务,简单、功能丰富,是处理 API 请求和静态页面抓取的最佳选择。
  • selenium: 适合处理复杂网页的自动化任务,尤其是那些依赖 JavaScript 渲染的动态网页。
  • scrapy: 适合大规模网页抓取,功能强大、效率高,适合需要异步处理和高并发抓取的数据抓取项目。

案例分享

#安装需要的库
pip install blinker
pip install selenium-wire
pip install --upgrade blinker mitmproxy

需要实现从浏览器导出以json格式的cookies,然后保存到同级目录下,命名为cookies.json

import json
import os
import random
import time

import requests
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from seleniumwire import webdriver


def share_browser():
    # 初始化
    # 创建一个Chrome WebDriver实例
    chrome_options = Options()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--no-sandbox')
    # 关闭声音
    chrome_options.add_argument('--mute-audio')
    chrome_options.add_argument('--disable-dev-shm-usage')

    driver = webdriver.Chrome(options=chrome_options)
    url = "http://example.com"
    # 使用WebDriver访问网页
    driver.get(url)  # 将网址替换为你要访问的网页地址

    # 加载 JSON 格式的 cookies
    with open('cookies.json', 'r') as file:
        cookies = json.load(file)
        for cookie in cookies:
            # 删除不必要的字段
            cookie.pop('expirationDate', None)
            # 检查 sameSite 属性
            if 'sameSite' in cookie:
                if cookie['sameSite'] not in ["Strict", "Lax", "None"]:
                    # 如果值不合法,删除 sameSite 属性
                    cookie.pop('sameSite')

            driver.add_cookie(cookie)

    # 刷新页面以应用 cookies
    driver.refresh()

    directory = driver.title

    # 检查目录是否存在
    if not os.path.exists(directory):
        # 如果目录不存在,创建目录
        os.makedirs(directory)
        print(f"Directory '{directory}' created.")
    else:
        print(f"Directory '{directory}' already exists.")

    time.sleep(2)

    element = driver.find_element(By.XPATH, '//*[@id="pul"]/li[1]/a[2]')
    element.click()

    # 获取所有打开的窗口句柄
    windows = driver.window_handles

    # 切换到新打开的窗口 playlist
    driver.switch_to.window(windows[-1])
    time.sleep(2)
    # 标题
    # print(driver.title)

    down_url = ""

    # 文件路径,包含目录和文件名
    file_path = os.path.join(directory, "output.txt")

    print(f"clear qian URL SIZE: {len(driver.requests)}")

    for number in range(1, 68):
        # 生成一个1到4之间的随机整数
        sleep_time = random.randint(2, 4)
        # 清空请求记录
        driver.requests.clear()

        # 获取连接
        element = driver.find_element(By.XPATH, '/html/body/section/article/section[2]/ul/li[' + str(number) + ']')
        element.click()
        # 获取名称
        element = driver.find_element(By.XPATH, '/html/body/section/article/section[2]/ul/li[' + str(number) + ']/div[1]/span')
        file_down_name = element.text + ".m4a"

        time.sleep(sleep_time)

        filtered_requests = [req for req in driver.requests if req.url.startswith('https://example.com/')]

        # 获取最后一个匹配的请求
        if filtered_requests:
            print(f"filtered_requests size: {len(filtered_requests)}")
            last_request = filtered_requests[-1]
            down_url = last_request.url
            with open(file_path, "a") as file:
                # 使用 for 循环遍历列表中的每个字符串
                # 将字符串写入文件,并添加换行符
                file.write(f"{file_down_name}: {down_url}\n")
        else:
            print("No matching requests found.")

        # 筛选出符合条件的网络请求
        # for request in driver.requests:
        #     if request.url.startswith('https://example.com/'):
        #         down_url = request.url
        #         print(f"URL SIZE: {len(driver.requests)}")
        #         print(f"URL: {down_url}")
        #         # 打开一个文件以写入模式 ('w' 模式会覆盖已有内容)
        #         with open(file_path, "a") as file:
        #             # 使用 for 循环遍历列表中的每个字符串
        #             # 将字符串写入文件,并添加换行符
        #             file.write(f"{file_down_name}: {down_url}\n")

        if down_url != "":
            file_path = os.path.join(directory, file_down_name)
            with requests.get(down_url, stream=True) as response:
                if response.status_code == 200:
                    with open(file_path, "wb") as file:
                        for chunk in response.iter_content(chunk_size=8192):  # 以 8KB 块为单位下载
                            file.write(chunk)
                    print(f"File downloaded and saved as '{file_down_name}'")
                else:
                    print(f"Failed to download file. HTTP Status Code: {response.status_code}")

            down_url = ""
        time.sleep(sleep_time)


    # 获取网页内容
    # page_content = driver.page_source
    # 保存当前截屏
    # driver.save_screenshot('handless2.png')

    # 如果需要,可以切换回原窗口
    driver.switch_to.window(windows[0])

    # 关闭WebDriver
    driver.quit()

    return ""


print(share_browser())

参考链接

GPT

(本篇博文完结;中文字数一共:6198字,英文字数一共:582 字)


扫扫加关注公众号 让我们一起学习一起成长

(转载本站文章请注明作者和出处 IT超仔

Post Directory