在本教程中,你将学习:
- 为什么
User-Agent
头如此重要 - 在有头和无头浏览器中,Selenium的默认用户代理值
- 如何在Selenium中更改用户代理
- 如何在Selenium中实现用户代理轮换
让我们开始吧!
为什么用户代理头重要?
User-Agent
头是一个字符串,用于标识发出HTTP请求的客户端软件。它通常包括有关浏览器或应用程序类型、操作系统和请求来源架构的信息。通常由浏览器、HTTP客户端或执行网页请求的任何其他应用程序设置。
例如,以下是Chrome当前设置的用户代理:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36
该用户代理字符串的组成部分是:
Mozilla/5.0
:历史上用于表示与Mozilla浏览器的兼容性。现在表示为兼容性原因添加的前缀。Windows NT 10.0; Win64; x64
:操作系统(Windows NT 10.0)、平台(Win64)和架构(x64)。AppleWebKit/537.36
:Chrome依赖的浏览器引擎。KHTML, like Gecko
:与KHTML引擎和Mozilla使用的Gecko布局引擎的兼容性。Chrome/125.0.0.0
:浏览器名称和版本。Safari/537.36
:与Safari的兼容性。
简单来说,用户代理标识请求是来自已知浏览器还是其他类型的软件。
爬虫机器人和浏览器自动化脚本往往使用默认或不一致的用户代理字符串。这些在反爬虫解决方案看来暴露了其自动化的本质,反爬虫解决方案通过监控传入的请求来保护网页数据。通过查看User-Agent
头,他们可以确定当前用户是合法用户还是机器人。
欲了解更多详细信息,请阅读我们的网页爬虫的用户代理指南。
默认的Selenium用户代理是什么?
Selenium在发出HTTP GET请求以检索网页时设置的User-Agent
头取决于控制的浏览器以及它是否在有头或无头模式下运行。
注意:在本文中,我们将使用Python中的Selenium并配置它在Chrome上运行。但是,你可以轻松地将你在这里学到的内容扩展到不同的编程语言和浏览器。
要查看Selenium的用户代理字符串,请创建一个基本的浏览器自动化脚本,访问httpbin.io的/user-agent
页面。这只是一个返回传入请求的User-Agent
头的API。
导入selenium
,初始化一个Chrome实例,访问所需页面,并打印其内容:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
# enable headless mode in Selenium
options = Options()
# options.add_argument('--headless')
# initialize a Chrome instance
driver = webdriver.Chrome(
options=options,
)
# visit the desired page
driver.get("https://httpbin.org/user-agent")
# get the page content
user_agent_info = driver.find_element(By.TAG_NAME, "body").text
# print the page content
print(user_agent_info)
# close the browser
driver.quit()
启动上述Python脚本,它将在终端中记录类似如下内容:
{
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
}
该值对应于Chrome在撰写本文时设置的User-Agent
头。你不应该感到惊讶,因为Selenium在一个真实的浏览器窗口上操作。
同时,Selenium通常配置为控制无头浏览器实例。原因是加载浏览器的UI需要大量资源,而在生产中没有任何好处。因此,取消注释--headless
选项以无头模式运行脚本。这次,结果将是:
{
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/125.0.6422.142 Safari/537.36"
}
如你所见,Chrome/125.0.0.0
被HeadlessChrome/125.0.6422.142
替代了。此值明确标识请求来自浏览器自动化工具,因为没有人会使用无头浏览器。因此,反机器人系统可以将此类请求标记为来自机器人的请求并阻止它。这就是为什么设置Selenium用户代理值如此重要的原因!
在我们的Selenium网页爬虫指南中了解更多信息。
如何在Selenium中更改用户代理
Selenium提供了两种设置用户代理值的方法。让我们一起深入了解它们吧!
全局设置用户代理
Chrome支持的选项中也包括--user-agent
标志。此选项允许你指定当Chrome进程在其标签页或窗口中访问网页时应使用的全局用户代理。
在Python中使用Selenium设置全局用户代理如下:
custom_user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
options = Options()
# set a custom user agent in the browser option
options.add_argument(f'--user-agent={custom_user_agent}')
# other options...
# initialize a Chrome instance with a custom user agent
driver = webdriver.Chrome(
options=options,
)
将所有内容整合在一起并通过以下脚本验证它是否有效:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
custom_user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
options = Options()
# set a custom user agent in the browser option
options.add_argument(f'--user-agent={custom_user_agent}')
# enable headless mode
options.add_argument('--headless')
# initialize a headless Chrome instance with a custom user agent
driver = webdriver.Chrome(
options=options,
)
# visit the desired page
driver.get("https://httpbin.org/user-agent")
# get the page content
user_agent_info = driver.find_element(By.TAG_NAME, "body").text
# print the page content
print(user_agent_info)
# close the browser
driver.quit()
现在,启动脚本,它将打印:
{
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
}
这与custom_user_agent
字符串中指定的用户代理匹配。特别是,通过Selenium控制的浏览器现在暴露了一个有头浏览器的用户代理值,即使它在无头模式下运行。这个技巧应该足以欺骗较简单的反机器人解决方案。
这种方法的主要缺点是,你只能在浏览器实例设置期间一次性设置--user-agent
标志。指定后,自定义用户代理将在整个浏览会话中使用,无法在get()
调用之前动态更改。
本地设置用户代理
Chrome开发工具协议(CDP)命令让你可以与正在运行的Chrome浏览器通信。特别是,它们使你能够动态更改浏览器设置的默认值和配置。
你可以使用driver
对象暴露的execute_cdp_cmd()
方法在Selenium中执行CDP命令。具体来说,Network.setUserAgentOverride
CDP命令覆盖给定字符串的用户代理。如下使用它在Selenium中本地更改用户代理:
custom_user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
driver.execute_cdp_cmd('Network.setUserAgentOverride', {'userAgent': custom_user_agent})
验证这种方法是否使你能够在同一浏览会话中多次更新用户代理,逻辑如下:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
options = Options()
# enable headless mode
options.add_argument('--headless')
# initialize a headless Chrome instance
driver = webdriver.Chrome(
options=options,
)
# configure a custom user agent
custom_user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
driver.execute_cdp_cmd('Network.setUserAgentOverride', {'userAgent': custom_user_agent})
# visit the desired page
driver.get("https://httpbin.org/user-agent")
# get the page content and print it
user_agent_info = driver.find_element(By.TAG_NAME, "body").text
print(user_agent_info)
# set another user agent
custom_user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0"
driver.execute_cdp_cmd('Network.setUserAgentOverride', {'userAgent': custom_user_agent})
# reload the page
driver.refresh()
# print the page content
user_agent_info = driver.find_element(By.TAG_NAME, "body").text
print(user_agent_info)
# close the browser
driver.quit()
启动上述脚本,它将产生:
{
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
}
{
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0"
}
太棒了!同一浏览会话中使用两个不同的Selenium用户代理字符串。
在Selenium中实现用户代理轮换
设置非无头的User-Agent
头可能不足以克服反机器人。问题在于来自同一IP地址和具有相同头的请求过多,可能会暴露Selenium脚本的自动化性质。
避免机器人检测的关键是随机化请求,例如实现用户代理轮换。这种方法的核心是,在Selenium中导航到页面之前随机选择一个用户代理。这样,你的自动化请求将显示为来自不同的浏览器,减少触发拦截和封禁的风险。
现在,按照以下步骤,学习如何在Selenium中实现用户代理轮换!
步骤1:获取用户代理列表
从类似User Agent String.com的门户网站获取一些适当的用户代理,并将它们存储在一个Python数组中,如下所示:
user_agents = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14.5; rv:126.0) Gecko/20100101 Firefox/126.0",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Safari/605.1.15"
# other user agents...
]
步骤2:提取随机用户代理
定义一个自定义函数,将随机用户代理设置到Selenium WebDriver对象上:
def set_user_agent(driver):
# set the user agent...
从Python标准库导入random
包,以准备从user_agents
列表中随机选择一个用户代理:
import random
使用random.choice()
函数从数组中随机提取一个用户代理字符串:
random_user_agent = random.choice(user_agents)
然后,使用execute_cdp_cmd()
函数将其分配给Chrome窗口:
driver.execute_cdp_cmd('Network.setUserAgentOverride', {'userAgent': random_user_agent})
现在你的set_user_agent()
函数将包含:
def set_user_agent(driver):
# randmoly pick a user agent string from the list
random_user_agent = random.choice(user_agents)
# set the user agent in the driver
driver.execute_cdp_cmd('Network.setUserAgentOverride', {'userAgent': random_user_agent})
步骤3:设置随机用户代理
在使用get()
导航到页面之前,调用set_user_agent()
函数以更改Selenium用户代理:
# set a custom user agent
set_user_agent(driver)
# visit the desired page
driver.get("https://httpbin.org/user-agent")
步骤4:将所有内容整合在一起
这就是你的Python Selenium用户代理轮换脚本的样子:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import random
user_agents = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14.5; rv:126.0) Gecko/20100101 Firefox/126.0",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Safari/605.1.15"
]
def set_user_agent(driver):
# randmoly pick a user agent string from the list
random_user_agent = random.choice(user_agents)
# set the user agent in the driver
driver.execute_cdp_cmd('Network.setUserAgentOverride', {'userAgent': random_user_agent})
options = Options()
# enable headless mode
options.add_argument('--headless')
# initialize a headless Chrome instance
driver = webdriver.Chrome(
options=options,
)
# set a custom user agent
set_user_agent(driver)
# visit the desired page
driver.get("https://httpbin.org/user-agent")
# get the page content and print it
user_agent_info = driver.find_element(By.TAG_NAME, "body").text
print(user_agent_info)
# close the browser
driver.quit()
多次执行此脚本,注意它将打印不同的用户代理字符串。
就是这样!你现在已经掌握了在Selenium中更改用户代理的技巧。
结论
在本指南中,你了解了User-Agent
头的重要性以及如何在Selenium中覆盖它。此技巧使你能够欺骗基本的反机器人系统,使其认为你的请求来自合法的非无头浏览器。然而,先进的解决方案仍可能能够检测并阻止你。为了防止IP封禁,你可以将代理与Selenium集成,但即使这样也可能不够!
使用Scraping Browser避免这些问题,这是一款下一代浏览器,集成了Selenium和任何其他浏览器自动化工具。Scraping Browser可以轻松绕过反机器人技术,同时避免浏览器指纹识别。它依赖于用户代理轮换、IP轮换和CAPTCHA解决等功能。浏览器自动化从未如此简单!