爬虫系列:反爬的几种措施
一些大型的网站(亚马逊、沃尔玛、淘宝、京东等)会对 selenium 控制的浏览器暴露特征进行监控,如果不做任何处理直接进行爬取,就很被限制。
一、隐藏浏览器指纹特征
方法一:加载浏览器内容前,先执行 stealth.min.js,去除部分特征
有高人已经介绍过了:https://mp.weixin.qq.com/s/Bge-_yiatSq4CQq7fRvjdQ
2023-2-10尝试后发现,对于我爬取的网站,此方法已经时效,可能很久没更新。也行其他的网站可用(只做备用,不做首选)
stealth.min.js 文件获取: https://github.com/kingname/stealth.min.js
from selenium import webdriver
driver = webdriver.Chrome()
with open('js/stealth.min.js') as ff:
print('执行反爬js')
js = ff.read()
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": js
})
方法二:undetected_chromedriver
官网:https://github.com/ultrafunkamsterdam/undetected-chromedriver
专门针对浏览器识别做出来的第三方库。
import undetected_chromedriver as uc
driver = uc.Chrome(version_main=91)
这里建议
undetected_chromedriver如果要使用无头模式,设置headless 为 True 即可。


但是有可能遇到 无法自动识别到Chrome浏览器的版本号,self.patcher.version_main返回为None,就会报错
所有最好的设定以下参数
browser_executable_path: 浏览器的 启动文件(chrome.exe)路径driver_executable_path: 对应浏览器的驱动(chromedriver.exe)路径version_main: 浏览器版本号(整数)headless: True 或者uc.ChromeOptions()类里面设置options.add_argument('--headless')keep_user_data_dir: 除此之外 最好也设置一下 用户的缓存数据目录。有些网站会判断用户是不是有缓存,没缓存大概率就是机器了
# chrome_option.py
import undetected_chromedriver as uc
from fake_useragent import UserAgent
# ChromeOptions类是一个配置 chrome 启动是属性的类。通过这个类,可以为chrome配置参数
class Options:
# ua = UserAgent() # 创建User-Agent对象
# useragent = ua.random
def conf_options(self):
# 配置ChromeOptions
options = uc.ChromeOptions()
# 页面加载策略 normal (默认); eager; none
options.set_capability('pageLoadStrategy', 'eager')
# 不加载图片(如果设置【页面加载策略】异常,可以添加以下参数,提升运行速度)
options.add_argument('blink-settings=imagesEnabled=false')
# # 默认启动的driver窗体最大化
# options.add_argument('start-maximized')
# 以最高权限运行 (解决DevToolsActivePort文件不存在的报错)
options.add_argument('--no-sandbox')
# ERROR:ssl_client_socket 不安全的地址错误,循环报错,导致程序终止。以下参数可忽略掉那些证书错误
options.add_argument('--ignore-certificate-errors')
# 彻底禁用gpu加速启动
options.add_argument('--disable-gpu --disable-software-rasterizer')
# # 无头模式。
# options.add_argument('--headless')
# ----------------- 反爬措施 ----------
# # 设置User-Agent
# options.add_argument(f'User-Agent={self.useragent}')
# 代理ip
# options.add_argument('--proxy-server=http://ip:port')
# ----------------- 反爬措施 ----------
prefs = {}
# 添加去掉密码弹窗管理(chrome密码登录时弹出的密码提示框,遮挡了要点击的元素,导致元素不可点击)
prefs.update({"credentials_enable_service": False ,"profile.password_manager_enabled": False})
# # -------------- 下载相关 -----------
# # 设置下载目录(当前目录,可设置其他目录)
# download_path = './'
# prefs.update({"download.default_directory": download_path})
# # 开启自动下载
# prefs.update({"download.prompt_for_download": False})
# # 取消浏览器下载时保存路径弹框
# prefs.update({"download.directory_upgrade": True})
# # -------------- 下载相关 -----------
# # 是禁止弹出所有窗口(慎用)
# prefs.update({"profile.default content settings·popups": 0})
# 去掉"此文件类型可能会损害您的计算机”的提示
prefs.update({"safebrowsing.enabled": True})
options.add_experimental_option("prefs", prefs)
# 设置语言
options.add_argument('lang=en_US')
options.add_argument("--disable-popup-blocking")
options.add_argument('--no-first-run')
options.add_argument('--no-service-autorun')
options.add_argument('--no-default-browser-check')
options.add_argument('--password-store=basic')
return options
# conftest.py 生成driver对象
import undetected_chromedriver as uc
@pytest.fixture(scope="session")
def driver2():
global driver
# 驱动路径
print(f'chromedriver.exe 完整路径是:{Config.chromedriver_dir}')
sys.path.append(Config.chromedriver_dir)
chrome_options = Options().conf_options()
# 指定chrome.exe:browser_executable_path、driver_executable_path
driver = uc.Chrome(version_main=91, headless=True, options=chrome_options,browser_executable_path=Config.chrome_exe_dir, driver_executable_path=Config.chromedriver_dir,keep_user_data_dir=Config.keep_user_data_dir)
yield driver
print("全部用例执行完后 teardown quit dirver")
driver.quit()
# project.py 项目路径
import os
class Config:
# 全局项目根目录
root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# logger.info(f'全局项目根目录:{root_dir}')
excle_dir = os.path.join(root_dir, "./file/excle_data.xlsx")
chromedriver_dir = os.path.join(root_dir, "./chrome/chromedriver.exe")
chrome_exe_dir = os.path.join(root_dir, "./chrome/chrome.exe")
keep_user_data_dir = os.path.join(root_dir, "./chrome/cache")
settings = Config()
二、其他操作
浏览器参数配置
设置随机User-Agent
from fake_useragent import UserAgent
options.add_argument(f'User-Agent={UserAgent().random}')
去掉提示正在执行自动化的警告条
options.add_experimental_option('useAutomationExtension', False)
options.add_experimental_option('excludeSwitches', ['enable-automation'])
随机ip访问
通过启动参数 --proxy-server代理有访问目标
# 代理ip
# options.add_argument('--proxy-server=http://ip:port')
如何获取那么多的可用、稳定ip呢?
查看爬虫系列的另一篇文章:爬虫系列:自建并维护代理ip池