简介
需求
各个库对比
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
比其他库的资源消耗大得多。 - 速度较慢:模拟浏览器操作的速度较慢,不适合大量数据的快速抓取。
- 复杂性高:相比于
requests
和scrapy
,selenium
的配置和使用更为复杂。
适用场景:
- 需要模拟用户交互的网页自动化任务,如登录、表单提交、页面滚动等。
- 处理依赖 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