playwright--自动化(三): 跳过检测 使用正常谷歌 指定用户数据 下载文件
还是前两天做一个商城后台爬虫,限制用户缓存,不能用谷歌开发版本,同时需要下载文件。
检测网站https://bot.sannysoft.com/
一开始WebDriver
这一项就标红了,说明网站成功检测到你使用模拟浏览器了。你再往下翻,标红的都是可以被检测出的特征。
左边是普通浏览器,右边是模拟浏览器
左边是普通浏览器,右边是模拟浏览器。如果你一项一项对比,就会发现很多地方都不一样。
这还是有头模式的效果。我们来看看无头模式:
from selenium.webdriver import Chrome from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_options.add_argument("--headless") driver = Chrome('./chromedriver', options=chrome_options) driver.get('https://bot.sannysoft.com/') driver.save_screenshot('screenshot.png')
截图打开以后是下面这样的。不要吓到:
万里河山一片红
这么多特征都直接暴露了,你还隐藏个屁。网站只要想发现你,非常容易。
既然 Selenium 不行,那 Puppeteer 或者 Pyppeteer怎么样呢?我们使用 Pyppeteer 来做个实验。直接启动无头模式并截图。运行效果是下面这样的:
import getpass from playwright.sync_api import sync_playwright # 不出意外这个可以获取到你google的本地缓存文件 __USER_DATE_DIR_PATH__ = f"C:\\Users\\{getpass.getuser()}\\AppData\Local\Google\Chrome\\User Data" playwright = sync_playwright().start() browser = playwright.chromium.launch_persistent_context( # 指定本机用户缓存地址 user_data_dir=__USER_DATE_DIR_PATH__, # 指定本机google客户端exe的路径 executable_path=__EXECUTABLE_PATH__, # 要想通过这个下载文件这个必然要开 默认是False accept_downloads=True, # 设置不是无头模式 headless=False, bypass_csp=True, slow_mo=10, #跳过检测 args=['--disable-blink-features=AutomationControlled'] )
注意用这个方法启动的浏览器会自带一个页面存在,当然你还是可以重新再起一个
# 打开新页 page = browser.new_page() # 访问谷歌首页 page.goto('https://www.google.com',wait_until='networkidle',timeout=90000)
wait_until='networkidle' 意思是 跳转过后再一定时间内没有网络请求链接
timeout 很好理解 超时时间90秒
js注入(用途的话是选择器选择元素用的,具体的js 你们自己写)
# 算是获得句柄吧 window_handle = page.evaluate_handle("window") # 选择元素 window_handle.evaluate("document.querySelectorAll('#drrReportRangeTypeRadioMonthly')[0].checked=true") # 自带select选择 data自行补充 drrMonthlySelect = page.wait_for_selector('//select[@id="drrMonthlySelect"]') drrMonthlySelect.select_option(date)
接下来是下载操作
# 打开下载器 with page.expect_download() as download_info: #找到你要下载的东西,找到点击的元素,点击 page.wait_for_selector('//a[@id="sspa-reports:report-settings-page:-download-button"]').click() # 下载的东西 download = download_info.value # 下载的路径 download.path() # 下载的文件名 download.suggested_filename # 关闭页面 page.close() # 关闭浏览器 browser.stop()
剩下的操作 你想干啥干啥
# 补充几个 # 点击 page.click('//input[@id="signInSubmit"]') # 等待完成 self.page.wait_for_load_state("domcontentloaded") # 输入 page.fill('//input[@id="ap_email"]', user_str) # 查找元素 page.wait_for_selector('//select[@id="drrMonthlySelect"]')